//---------------------------------------------------------------------- // Pick() -- this takes an element description and returns a copy with // its min-max range converted to an actual; nothing big here //---------------------------------------------------------------------- public ArrayList Pick() { ArrayList pickedElements = new ArrayList(); //----------------------------------------------------------------- // for elements that may not be present (indicated by a p value), // then we check p, not on a per-n basis, but rather for the whole // set: //----------------------------------------------------------------- if (Utility.RandomDouble() > Probability) { return(pickedElements); // empty list okay } int n = Utility.RandomMinMax(m_Min, m_Max); string[] picks = m_PickFrom.Split(new Char [] { ',' }); string pick = ""; for (int i = 0; i < n; i++) { if (picks.Length == 1) { pick = picks[0]; } else if (picks.Length >= 2) { pick = picks[Utility.RandomMinMax(0, picks.Length - 1)]; } EncounterElement pickedElement = new EncounterElement( m_XmlNode, "1", pick, m_ID.ToString(), m_Min.ToString(), m_Max.ToString(), m_ForceAttack.ToString(), m_Effect.ToString(), m_EffectHue.ToString() ); pickedElement.m_N = n; foreach (EncounterElement childElement in m_Elements) { ArrayList pickedChildElements = childElement.Pick(); foreach (EncounterElement pickedChildElement in pickedChildElements) { pickedElement.m_Elements.Add(pickedChildElement); } } pickedElements.Add(pickedElement); } return(pickedElements); // empty list okay }
//---------------------------------------------------------------------- // Pick() -- this takes an element description and returns a copy with // its min-max range converted to an actual; nothing big here //---------------------------------------------------------------------- public ArrayList Pick() { ArrayList pickedElements = new ArrayList(); //----------------------------------------------------------------- // for elements that may not be present (indicated by a p value), // then we check p, not on a per-n basis, but rather for the whole // set: //----------------------------------------------------------------- if( Utility.RandomDouble() > Probability) return pickedElements; // empty list okay int n = Utility.RandomMinMax( m_Min, m_Max ); string[] picks = m_PickFrom.Split(new Char [] {','}); string pick =""; for( int i=0; i<n; i++ ) { if (picks.Length==1) pick = picks[0]; else if (picks.Length>=2) pick = picks[Utility.RandomMinMax( 0, picks.Length-1)]; EncounterElement pickedElement = new EncounterElement( m_XmlNode, "1", pick, m_ID.ToString(), m_Min.ToString(), m_Max.ToString(), m_ForceAttack.ToString(), m_Effect.ToString(), m_EffectHue.ToString() ); pickedElement.m_N = n; foreach( EncounterElement childElement in m_Elements ) { ArrayList pickedChildElements = childElement.Pick(); foreach( EncounterElement pickedChildElement in pickedChildElements ) { pickedElement.m_Elements.Add( pickedChildElement ); } } pickedElements.Add( pickedElement ); } return pickedElements; // empty list okay }
//--------------------------------------------------------------------- public void AddElement( EncounterElement element ) { m_Elements.Add( element ); }
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 ); } }
//---------------------------------------------------------------------- // Record a property modification to an Item or mobile //---------------------------------------------------------------------- private static void AddProp( XmlNode parentNode, XmlNode childNode, EncounterElement element ) { Console.WriteLine( "Adding property to " + parentNode.Name ); }
//---------------------------------------------------------------------- // Now we recursively decend the Mobile/Item hierarchy, allowing sub // containment (when it makes sense): //---------------------------------------------------------------------- private static void AddRecursiveMobilesAndItems( XmlNode parentNode, XmlNode childNode, IElementContainer elementContainer ) { bool reject = false; string probability = "1.0"; string pick = ""; string n = "1"; string id = "0"; string forceAttack = "false"; string effectStr = "None"; try { probability = childNode.Attributes["p"].Value; } catch { } try { n = childNode.Attributes["n"].Value; } catch { } try { id = childNode.Attributes["id"].Value; } catch { } try { forceAttack = childNode.Attributes["forceAttack"].Value; } catch { } try { effectStr = childNode.Attributes["effect"].Value; } catch { } string[] effectOptions = effectStr.Split( ':' ); string effect = effectOptions[0]; string effectHue = "0"; if( effectOptions.Length > 1 ) effectHue = effectOptions[1]; try { pick = childNode.Attributes["pick"].Value; } catch { Console.WriteLine( "Attempted to add an element without a pick at {0}. IGNORING.", childNode.Attributes["lineNumber"].Value ); return; } if( parentNode.Name == "Item" && childNode.Name == "Mobile" ) reject = true; //------------------------------------------------------------------ // I anticpate more rejection reasons; in any case, the message is decoupled // entirely from the reason... //------------------------------------------------------------------ if( reject ) { Console.WriteLine( "RandomEncounters: Tried to add {0} \"{1}\" to {2} at {3}. THIS IS ILLEGAL. IGNORED.", childNode.Name, pick, parentNode.Name, childNode.Attributes["lineNumber"].Value ); return; } string[] tokens = n.Split( new Char[] { ':' } ); // splits to min:max, or just n if no ':' EncounterElement newElement = new EncounterElement( childNode, probability, pick, id, tokens[0], (tokens.Length > 1 ? tokens[1] : tokens[0]), forceAttack, effect, effectHue ); XmlNodeList subNodes = childNode.SelectNodes( "Mobile | Item | Prop" ); //---------------------------------------------- // Now iterate over subelements //---------------------------------------------- foreach( XmlNode subNode in subNodes ) { if( subNode.Name == "Prop" ) AddProp( childNode, subNode, newElement ); else AddRecursiveMobilesAndItems( childNode, subNode, newElement ); } elementContainer.AddElement( newElement ); }
//---------------------------------------------------------------------- // Dump out text for debugging information -- recursive version //---------------------------------------------------------------------- internal static void DumpElementRecursive( int depth, EncounterElement element ) { string prepend = ""; for( int i = 0; i < depth; i++ ) prepend += " "; Console.WriteLine( "{0}{1}", prepend, element ); foreach( EncounterElement childElement in element.Elements ) { DumpElementRecursive( depth + 1, childElement ); } }
//--------------------------------------------------------------------- public void AddElement(EncounterElement element) { m_Elements.Add(element); }