Example #1
0
        //----------------------------------------------------------------------
        //  Pick() -- this takes an encounter description and creates a real
        //            instance. The primary purpose is to take the min/max
        //            ranges of the elements and convert them into a specific
        //            count -- nothing fancy. )
        //----------------------------------------------------------------------
        public RandomEncounter Pick( )
        {
            RandomEncounter actualEncounter = new RandomEncounter(
                m_XmlNode,
                m_Facet,
                m_RegionType,
                m_RegionName,
                m_Inclusive ? "*" : m_Probability.ToString(),
                m_Shortest.ToString(),
                m_Farthest.ToString(),
                m_LandType.ToString(),
                m_EncounterTime.ToString(),
                m_Level.ToString(),
                m_LevelType.ToString(),
                m_ScaleUp.ToString()
                );

            actualEncounter.m_Distance = Utility.RandomMinMax(m_Shortest, m_Farthest);

            foreach (EncounterElement element in m_Elements)
            {
                ArrayList pickedElements = element.Pick();

                foreach (EncounterElement pickedElement in pickedElements)
                {
                    actualEncounter.m_Elements.Add(pickedElement);
                }
            }

            return(actualEncounter);
        }
Example #2
0
        public void AddEncounter(RandomEncounter encounter)
        {
            object o = m_PossibleEncounters.Find(new EncounterSet.QuickSearch(encounter.Probability));

            EncounterSet encounterSet;

            if (o == null)
            {
                encounterSet = new EncounterSet(encounter.Probability);
                m_PossibleEncounters.Add(encounterSet);
            }
            else
            {
                encounterSet = (EncounterSet)o;
            }

            encounterSet.Add(encounter);
        }
Example #3
0
        public void AddEncounter( RandomEncounter encounter )
        {
            object o = m_PossibleEncounters.Find( new EncounterSet.QuickSearch( encounter.Probability ));

            EncounterSet encounterSet;

            if (o==null)
            {
                encounterSet = new EncounterSet( encounter.Probability );
                m_PossibleEncounters.Add( encounterSet );
            }
            else
            {
                encounterSet = (EncounterSet) o;
            }

            encounterSet.Add( encounter );
        }
Example #4
0
        //----------------------------------------------------------------------
        //  Pick() -- this takes an encounter description and creates a real
        //            instance. The primary purpose is to take the min/max
        //            ranges of the elements and convert them into a specific
        //            count -- nothing fancy. )
        //----------------------------------------------------------------------
        public RandomEncounter Pick( )
        {
            RandomEncounter         actualEncounter = new RandomEncounter( 
                                        m_XmlNode,
                                        m_Facet,
                                        m_RegionType,
                                        m_RegionName,
                                        m_Inclusive ? "*" : m_Probability.ToString(),
                                        m_Shortest.ToString(),
                                        m_Farthest.ToString(),
                                        m_LandType.ToString(),
                                        m_EncounterTime.ToString(),
                                        m_Level.ToString(),
                                        m_LevelType.ToString(),
                                        m_ScaleUp.ToString()
                                    );

            actualEncounter.m_Distance = Utility.RandomMinMax( m_Shortest, m_Farthest );
            
            foreach( EncounterElement element in m_Elements )
            {
                ArrayList pickedElements = element.Pick();
                
                foreach( EncounterElement pickedElement in pickedElements )
                {
                    actualEncounter.m_Elements.Add( pickedElement );
                }
            }

            return actualEncounter;
        }
Example #5
0
		private static void GenerateEncounterRecursive(
			Map map,
			PlayerMobile playerMobile,
			Point3D parentLocation,
			ArrayList cleanupList,
			RandomEncounter encounterTemplate,
			EncounterElement parentElement,
			object parentObject
			)
		{
			Type typeObject = SpawnerType.GetType( parentElement.PickFrom );

			if( typeObject == null )
			{
				Console.WriteLine( "RandomEncounters: Bad attempt to generate an element of type \"{0}\".", parentElement.PickFrom );
				return;
			}

			Point3D spawnPoint;

			if( parentObject == null ) spawnPoint = parentLocation;

			else
			{
				spawnPoint = new Point3D();
				if(
					!SpawnFinder.FindOutwards(
						playerMobile,
						parentLocation,
						ref spawnPoint,
						encounterTemplate.LandType,
						1,
						parentElement.Effect,
						parentElement.EffectHue
						)
				  )
				{
					//Console.WriteLine("NO SPAWN LOCATION AVAILABLE");
					return;
				}
			}

			object created;

			try
			{
				created = Activator.CreateInstance( typeObject );
			}
			catch( Exception e )
			//--------------------------------------------------------------
			//  most likely reason that we may fail is an attempt to construct an object
			//  that requires arguments in its constructor; here we'll help the user
			//  diagnose their problem, but otherwise ignore this part of the encounter
			//  without terminating:
			//--------------------------------------------------------------
			{
				string line = parentElement.XmlNode.Attributes["lineNumber"].Value;
				Console.WriteLine( "RandomEncounters: Bad attempt to contruct an element of type \"{0}\", on line {1}", parentElement.PickFrom, line );
				Console.WriteLine( "{0}", e );
				return; // go no deeper, we're done here, stop recursing
			}

			if( created is Mobile )
			{
				Mobile m = (Mobile)created;

				XmlAttach.AttachTo( m, new XmlDateCount( "RandomEncountersCreated" ) );

				//ObjectPropertyList props = m.PropertyList;

				cleanupList.Add( m );

				//here's where we might add monster to its own party, if it had one
				//if( parentObject!=null && parentObject is Mobile )
				//{
				//    Mobile      parentMobile = (Mobile) parentObject;
				//}

				m.OnBeforeSpawn( spawnPoint, map );

				m.MoveToWorld( spawnPoint, map );

				if( m is BaseCreature )
				{
					BaseCreature c = (BaseCreature)m;

					if( c.IsEnemy( playerMobile ) )
					{
						//  deprecated now with the configurable forceAttack option
						// if( c.AI == AIType.AI_Animal )
						// {
						//    if( c.Fame > 350 )
						//    {
						//        c.Combatant = playerMobile;
						//    }
						//  }
						if( c.AI == AIType.AI_Vendor ) ;
						else if( parentElement.ForceAttack ) c.Combatant = playerMobile;
					}

					c.Home = spawnPoint;
				}

				m.OnAfterSpawn();

				if( encounterTemplate.ScaleUp )
				{
					double pLevel = Helpers.CalculateLevelForMobile( playerMobile, LevelType.Fighter );

					double mLevel = Helpers.CalculateLevelForMobile( m, LevelType.Overall );

					double ratio = pLevel / mLevel;

					int scaleUp = (int)(ratio - .5);

					if( scaleUp > 2 ) scaleUp = 2;

					//--------------------------------------------------------------
					//  Handle add-ons from level based scaling here:
					//--------------------------------------------------------------

					if( scaleUp > 0 )
						for( int i = 0; i < scaleUp; i++ )
						{
							Point3D addonPoint = new Point3D();

							if(
								!SpawnFinder.FindOutwards(
									playerMobile,
									parentLocation,
									ref addonPoint,
									encounterTemplate.LandType,
									1,
									parentElement.Effect,
									parentElement.EffectHue
									)
							  )
							{
								return;
							}

							Mobile addonMob = (Mobile)Activator.CreateInstance( typeObject );

							XmlAttach.AttachTo( addonMob, new XmlDateCount( "RandomEncountersCreated" ) );

							cleanupList.Add( addonMob );

							addonMob.OnBeforeSpawn( addonPoint, map );

							addonMob.MoveToWorld( addonPoint, map );

							if( addonMob is BaseCreature )
							{
								BaseCreature c = (BaseCreature)addonMob;

								if( c.IsEnemy( playerMobile ) )
								{
									//if( c.AI == AIType.AI_Animal )
									//{
									//    if( c.Fame > 350 ) c.Combatant = playerMobile;
									//}
									if( c.AI == AIType.AI_Vendor ) ;
									else if( parentElement.ForceAttack ) c.Combatant = playerMobile;
								}

								c.Home = addonPoint;
							}

							addonMob.OnAfterSpawn();
						}
				}
			}
			else if( created is Item )
			{
				Item item = (Item)created;

				//ObjectPropertyList props = item.PropertyList;

				//if( !item.Movable) XmlAttach.AttachTo( item, new XmlDate( "RandomEncountersCreated" ));
				XmlAttach.AttachTo( item, new XmlDateCount( "RandomEncountersCreated" ) );

				item.OnBeforeSpawn( spawnPoint, map );

				//--------------------------------------------------------------
				// some core items won't decay, but we need them to:
				// the code is in the core, and we don't want to modify that,
				// so we will do it here instead
				//--------------------------------------------------------------

				if( !item.Movable )
				{
					cleanupList.Add( created );
				}

				if( parentObject != null )
				{
					if( parentObject is Mobile )
					{
						Mobile mobileParent = (Mobile)parentObject;
						//Console.WriteLine( "RandomEncounters: added item to mobile: " + item );

						mobileParent.AddItem( item );
					}
					else if( parentObject is Container )
					{
						Container itemParent = (Container)parentObject;

						//Console.WriteLine( "RandomEncounters: added item to container: " + item );
						itemParent.AddItem( item );
					}
					else
					{
						item.MoveToWorld( spawnPoint, map );
						//Console.WriteLine( "RandomEncounters: inserted item into world: " + item );
					}
				}
				else
				{
					item.MoveToWorld( spawnPoint, map );
					//Console.WriteLine( "RandomEncounters: inserted item into world: " + item );
				}

				item.OnAfterSpawn();
			}
			foreach( EncounterElement childElement in parentElement.Elements )
			{
				GenerateEncounterRecursive(
					map,
					playerMobile,
					spawnPoint,
					cleanupList,
					encounterTemplate,
					childElement,
					created
					);
			}
		}
Example #6
0
		//----------------------------------------------------------------------
		//  GenerateEncounter -- this takes an encounter description and
		//     creates an actual encounter. Since our random draw in the previous
		//     section means that we got here, all that's left to do is narrow
		//     down the actual encounter template to a definitive description
		//     (this converts min-max ranges to actuals), plot out positions
		//     for the various elements, create their Mobiles/Items, and go.
		//----------------------------------------------------------------------
		private static void GenerateEncounter(
			PlayerMobile playerMobile,
			RandomEncounter encounterTemplate,
			ArrayList cleanupList
			)
		{
			RandomEncounter encounter = encounterTemplate.Pick();
			Map map = playerMobile.Map;
			Point3D location = new Point3D( playerMobile.X, playerMobile.Y, playerMobile.Z );
			Point3D spawnPoint = new Point3D();

			if( m_Debug )
			{
				Console.WriteLine( "RandomEncounters: generating instances: {0} ...", encounter );
				DumpEncounter( 1, encounter );
			}

			// test code
			//            Tile        playerTile  = map.Tiles.GetLandTile( location.X, location.Y );
			//            Tile[]      staticTiles = map.Tiles.GetStaticTiles( location.X, location.Y, true );
			//
			//            Console.WriteLine("Player Location: {0}", location );
			//            Console.WriteLine("    Land Tile id={0} z={1} height={2}: ", playerTile.ID, playerTile.Z, playerTile.Height );
			//
			//            uint flags = (uint) TileData.LandTable[playerTile.ID & 0x3FFF].Flags;
			//            Console.WriteLine("    Land Flags: {0:x}", flags );
			//
			//            foreach( Tile staticTile in staticTiles )
			//            {
			//                Console.WriteLine("    Static Tile id={0} z={1} height={2}", staticTile.ID, staticTile.Z, staticTile.Height );
			//                flags = (uint) TileData.LandTable[staticTile.ID & 0x3FFF].Flags;
			//                Console.WriteLine("    Static Flags: {0:x}", flags );
			//            }

			foreach( EncounterElement element in encounter.Elements )
			{
				bool running = ((playerMobile.Direction & Direction.Running) > 0);

				bool foundQuadrant = false;

				if( running )
				{
					foundQuadrant = SpawnFinder.FindAhead(
					  playerMobile,
					  location,
					  ref spawnPoint,
					  encounter.LandType,
					  encounter.Distance,
					  element.Effect,
					  element.EffectHue
					  );
				}

				if( !foundQuadrant )
					if( !SpawnFinder.FindInwards(
						  playerMobile,
						  location,
						  ref spawnPoint,
						  encounter.LandType,
						  encounter.Distance,
						  element.Effect,
						  element.EffectHue
						  )
					  )
					{
						//----------------------------------------------------------
						// if we can't find a location, there's no chance we'll find any others: 
						// STOP! do not attempt to add any more elements to the encounter, there
						// simply is NO SPACE LEFT.
						//----------------------------------------------------------
						// Console.WriteLine("NO SPAWN LOCATION AVAILABLE");
						return;
					}

				GenerateEncounterRecursive(
					map,
					playerMobile,
					spawnPoint,
					cleanupList,
					encounterTemplate,
					element,
					null
					);
			}
		}
Example #7
0
		//----------------------------------------------------------------------
		//  Process New Encounter -- this fills up our records database,
		//    per facet, per region, per region name, of probability-organized
		//    enounters to pick from.
		//----------------------------------------------------------------------
		private static void ProcessNewEncounter( RandomEncounter encounter )
		{
			//------------------------------------------------------------------
			//  Previously encountered something pertaining to this facet, region,
			//  and region name...
			//------------------------------------------------------------------
			if( m_RegionHash.Contains( encounter.Key ) )
			{
				RegionRecord region = (RegionRecord)m_RegionHash[encounter.Key];

				region.AddEncounter( encounter );
			}
			//------------------------------------------------------------------
			//  Have never encountered anything for this facet, region, and region
			//  name:
			//------------------------------------------------------------------
			else
			{
				RegionRecord region = new RegionRecord( encounter.Key );

				region.AddEncounter( encounter );

				m_RegionHash[encounter.Key] = region;
			}
		}
Example #8
0
		//----------------------------------------------------------------------
		// Actual XML load-out and node iteration
		//----------------------------------------------------------------------
		private static bool LoadXml()
		{
			XmlLinePreservingDocument xmlDoc = new XmlLinePreservingDocument( m_EncountersFile );

			try
			{
				xmlDoc.DoLoad();

				string language = "en-US";
				string skipHidden = "true";
				string picker = "sqrt";
				string delay = "60";
				string interval = "1800";
				string cleanup = "300";
				string cleanupgrace = "1";
				string debug = "false";
				string debugEffect = "false";
				string RTFM = "true";

				//------------------------------------------------------------------
				// Pull out initial information for configuration tags
				//------------------------------------------------------------------

				XmlNode root = xmlDoc["RandomEncounters"];

				try { language = root.Attributes["language"].Value; }
				catch { }
				try { skipHidden = root.Attributes["skiphidden"].Value; }
				catch { }
				try { picker = root.Attributes["picker"].Value; }
				catch { }
				try { delay = root.Attributes["delay"].Value; }
				catch { }
				try { interval = root.Attributes["interval"].Value; }
				catch { }
				try { cleanup = root.Attributes["cleanup"].Value; }
				catch { }
				try { cleanupgrace = root.Attributes["cleanupGrace"].Value; }
				catch { }
				try { debug = root.Attributes["debug"].Value; }
				catch { }
				try { debugEffect = root.Attributes["debugEffect"].Value; }
				catch { }
				try { RTFM = root.Attributes["RTFM"].Value; }
				catch { }

				m_Language = new CultureInfo( language );
				m_SkipHidden = bool.Parse( skipHidden );
				m_Picker = picker;
				m_Delay = float.Parse( delay, m_Language );
				m_Cleanup = float.Parse( cleanup, m_Language );
				m_CleanupGrace = int.Parse( cleanupgrace, m_Language );
				m_Debug = bool.Parse( debug );
				m_DebugEffect = bool.Parse( debugEffect );

				bool rtfm = bool.Parse( RTFM );

				if( !rtfm )
				{
					Console.WriteLine(
						"\n" +
						"##### RandomEncounters: SYSTEM CONFIG FILE FOUND, HOWEVER IT APPEARS THAT YOU DID NOT ACTUALLY READ IT!\n\n" +
						"                        RandomEncounters will **NOT** work if you have not read and edited the config file.\n" +
						"                        It is suggested that you do so now; the file can be found here:\n\n" +
						"                        \"{0}\"\n",
						m_EncountersFile
						);

					throw new Exception( "RTFM" );
				}

				//  Break out our intervals into our acceptible set; careful here, 
				//  changing this to return less than 3 intervals will break other code
				//  Dungeon Wilderness Guarded House Jail
				{
					string[] tokens = interval.Split( new Char[] { ':' } );

					int n = tokens.Length < 3 ? 3 : tokens.Length;

					m_Intervals = new float[n];

					if( tokens.Length == 5 )
					{
						m_Intervals[4] = float.Parse( tokens[4], m_Language ); // Jail
					}
					if( tokens.Length >= 4 )
					{
						m_Intervals[3] = float.Parse( tokens[3], m_Language ); // House
					}
					if( tokens.Length >= 3 )
					{
						m_Intervals[0] = float.Parse( tokens[0], m_Language ); // Guarded
						m_Intervals[1] = float.Parse( tokens[1], m_Language ); // Guarded
						m_Intervals[2] = float.Parse( tokens[2], m_Language ); // Guarded
					}

					if( tokens.Length == 2 )
					{
						m_Intervals[0] = float.Parse( tokens[0], m_Language ); // Dungeon
						m_Intervals[1] = float.Parse( tokens[1], m_Language ); // Wilderness
						m_Intervals[2] = float.Parse( tokens[1], m_Language ); // Guarded
					}

					if( tokens.Length == 1 )
					{
						m_Intervals[0] = float.Parse( tokens[0], m_Language ); // Dungeon
						m_Intervals[1] = float.Parse( tokens[0], m_Language ); // Wilderness
						m_Intervals[2] = float.Parse( tokens[0], m_Language ); // Guarded
					}

				}

				XmlNodeList facetNodes = xmlDoc.GetElementsByTagName( "Facet" );
				//------------------------------------------------------------------
				// Iterate over facets
				//------------------------------------------------------------------
				foreach( XmlNode facetNode in facetNodes )
				{
					string facetName = "";

					try { facetName = facetNode.Attributes["name"].Value; }
					catch
					{
						Console.WriteLine(
							"RandomEncounters: Facet at {1} had no name. THIS IS ILLEGAL. IGNORED ENTIRE FACET!",
							facetNode.Attributes["lineNumber"].Value
							);
						continue;
					}

					XmlNodeList regionNodes = facetNode.SelectNodes( "./Region" );
					if( regionNodes.Count == 0 ) Console.WriteLine(
						   "RandomEncounters: Facet \"{0}\" at {1} had no elements. IGNORED.",
						   facetName,
						   facetNode.Attributes["lineNumber"].Value
						   );
					//--------------------------------------------------------------
					// Now over regions
					//--------------------------------------------------------------
					foreach( XmlNode regionNode in regionNodes )
					{
						string regionType = "Wilderness";
						string regionName = "default";
						string failed = "";

						try { regionType = regionNode.Attributes["type"].Value; }
						catch { failed = "type"; }
						try { regionName = regionNode.Attributes["name"].Value; }
						catch { ; }

						if( failed != "" )
						{
							Console.WriteLine( "Attempted to add an element without a {0} at {1}. IGNORING.",
								failed,
								regionNode.Attributes["lineNumber"].Value
								);
							return false;
						}


						XmlNodeList encounterNodes = regionNode.SelectNodes( "./Encounter" );
						if( encounterNodes.Count == 0 ) Console.WriteLine(
							   "RandomEncounters: {0} Region \"{1}\" at {2} had no elements. IGNORED.",
							   regionType,
							   regionName,
							   regionNode.Attributes["lineNumber"].Value
							   );

						//------------------------------------------------------
						// Now over encounters
						//------------------------------------------------------
						foreach( XmlNode encounterNode in encounterNodes )
						{
							string encounterProbability = "1.0";
							string encounterDistance = "7";
							string encounterLand = "AnyLand";
							string encounterTime = "AnyTime";
							string encounterWater = "false";
							string encounterLevel = "1";
							string encounterScale = "false";

							try { encounterDistance = encounterNode.Attributes["distance"].Value; }
							catch { }
							try { encounterProbability = encounterNode.Attributes["p"].Value; }
							catch { }
							try { encounterLand = encounterNode.Attributes["landType"].Value; }
							catch { }
							try { encounterWater = encounterNode.Attributes["water"].Value; }
							catch { }
							try { encounterTime = encounterNode.Attributes["time"].Value; }
							catch { }
							try { encounterLevel = encounterNode.Attributes["level"].Value; }
							catch { }
							try { encounterScale = encounterNode.Attributes["scaleUp"].Value; }
							catch { }

							if( bool.Parse( encounterWater ) == true )
							{
								if( m_Debug ) Console.WriteLine(
									 "RandomEncounters, WARNING: \"water\" tag is deprecated; use landType=\"Water\" instead"
									 );
								encounterLand = "Water";
							}

							string[] distance_tok = encounterDistance.Split( new Char[] { ':' } ); // splits to shortest:farthest, or just distance if no ':'

							string[] level_tok = encounterLevel.Split( new Char[] { ':' } );

							RandomEncounter randomEncounter = new RandomEncounter(
									encounterNode,
									facetName,
									regionType,
									regionName,
									encounterProbability,
									distance_tok[0],
									(distance_tok.Length > 1 ? distance_tok[1] : distance_tok[0]),
									encounterLand,
									encounterTime,
									level_tok[0],
									(level_tok.Length > 1 ? level_tok[1] : "Overall"),
									encounterScale
									);

							XmlNodeList elementNodes = encounterNode.SelectNodes( "Mobile | Item " );

							if( elementNodes.Count == 0 ) Console.WriteLine(
								   "RandomEncounters: Encounter on line {0} had no children. IGNORED.",
								   encounterNode.Attributes["lineNumber"].Value
								   );

							//----------------------------------------------
							// Now iterate over subelements
							//----------------------------------------------
							foreach( XmlNode elementNode in elementNodes )
								AddRecursiveMobilesAndItems(
									encounterNode,
									elementNode,
									randomEncounter
									);

							//------------------------------------------
							// Now they we've built it up, process it:
							//------------------------------------------
							ProcessNewEncounter( randomEncounter );
						}
					}
				}
				return true;
			}
			catch( Exception e )
			{
				Console.WriteLine( "RandomEncounters: Exception caught attempting to load file: " + m_EncountersFile );
				Console.WriteLine( "{0}", e );
				xmlDoc.Close();
				return false;
			}
		}
Example #9
0
		//----------------------------------------------------------------------
		//  Dump out text for debugging information
		//----------------------------------------------------------------------
		internal static void DumpEncounter( int depth, RandomEncounter encounter )
		{
			string prepend = "";
			for( int i = 0; i < depth; i++ ) prepend += "    ";

			Console.WriteLine( "{0}{1}", prepend, encounter );

			foreach( EncounterElement element in encounter.Elements )
			{
				DumpElementRecursive( 2, element );
			}
		}