/// <summary> /// Converts a BoxSpawn to an actual spawner object. This function is used to generate /// spawn groups created in Pandora's Box /// </summary> /// <param name="spawn">The BoxSpawn object describing the spawn that should be created</param> /// <returns>A Spawner object - null if not valid</returns> public static Item CreateBoxSpawn( BoxSpawn spawn ) { if ( spawn == null || spawn.Entries.Count == 0 ) return null; XmlSpawner spawner = new XmlSpawner(); spawner.Amount = spawn.Count; spawner.MaxCount = spawn.Count; spawner.MinDelay = TimeSpan.FromSeconds( spawn.MinDelay ); spawner.MaxDelay = TimeSpan.FromSeconds( spawn.MaxDelay ); spawner.Team = spawn.Team; spawner.HomeRange = spawn.HomeRange; spawner.Running = false; spawner.Group = spawn.Group; XmlSpawner.SpawnObject[] spawnObjects = new Server.Mobiles.XmlSpawner.SpawnObject[ spawn.Entries.Count ]; for ( int i = 0; i < spawnObjects.Length; i++ ) { BoxSpawnEntry entry = spawn.Entries[ i ] as BoxSpawnEntry; spawnObjects[ i ] = new Server.Mobiles.XmlSpawner.SpawnObject( entry.Type, entry.MaxCount ); } spawner.SpawnObjects = spawnObjects; return spawner; }
public KeywordTimer(XmlSpawner spawner, KeywordTag tag, TimeSpan delay, TimeSpan repeatdelay, string condition, int gotogroup) : base(delay) { Priority = TimerPriority.OneSecond; m_Tag = tag; m_Spawner = spawner; m_Condition = condition; m_Goto = gotogroup; m_Repeatdelay = repeatdelay; }
public static bool TestItemProperty(XmlSpawner spawner, Item ObjectPropertyItem, string testString, Mobile trigmob, out string status_str) { status_str = null; // now make sure the item itself is there if (ObjectPropertyItem == null || ObjectPropertyItem.Deleted) { status_str = "Trigger Object not found"; return false; } bool testreturn = CheckPropertyString(spawner, ObjectPropertyItem, testString, trigmob, out status_str); return testreturn; }
public static bool SpawnTypeKeyword(object invoker, XmlSpawner.SpawnObject TheSpawn, string typeName, string substitutedtypeName, bool requiresurface, List<XmlSpawner.SpawnPositionInfo> spawnpositioning, Mobile triggermob, Point3D location, Map map, out string status_str) { return SpawnTypeKeyword(invoker, TheSpawn, typeName, substitutedtypeName, requiresurface, spawnpositioning, triggermob, location, map, null, out status_str); }
// set property values with support for nested attributes public static string SetPropertyValue(XmlSpawner spawner, object o, string name, string value) { if (o == null) { return "Null object"; } if ( o != null && o is PlayerMobile && ((PlayerMobile)o).AccessLevel >= AccessLevel.Administrator ) return "Access denied"; Type ptype = null; object po = null; Type type = o.GetType(); PropertyInfo[] props = type.GetProperties(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public); // parse the strings of the form property.attribute into two parts // first get the property string[] arglist = ParseString(name, 2, "."); string propname = arglist[0]; string[] keywordargs = ParseString(propname, 4, ","); // check for special keywords if (keywordargs[0] == "ATTACHMENT") { if (keywordargs.Length < 4) { return "Invalid ATTACHMENT format"; } // syntax is ATTACHMENT,type,name,propname string apropname = keywordargs[3]; string aname = keywordargs[2]; Type attachtype = SpawnerType.GetType(keywordargs[1]); // allow empty string specifications to be used to indicate a null string which will match any name if (aname == "") aname = null; ArrayList attachments = XmlAttach.FindAttachments(o, attachtype, aname); if (attachments != null && attachments.Count > 0) { // change the object, object type, and propname to refer to the attachment o = attachments[0]; propname = apropname; if (o == null) { return "Null object"; } type = o.GetType(); props = type.GetProperties(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public); } else return "Attachment not found"; } else if (keywordargs[0] == "SKILL") { if (keywordargs.Length < 2) { return "Invalid SKILL format"; } bool found = true; try { SkillName skillname = (SkillName)Enum.Parse(typeof(SkillName), keywordargs[1], true); if (o is Mobile) { Skill skill = ((Mobile)o).Skills[skillname]; skill.Base = double.Parse(value); return "Property has been set."; } else return "Object is not mobile"; } catch { found = false; } if (!found) return "Invalid SKILL reference."; } else if (keywordargs[0] == "STEALABLE") { bool found = true; try { if (o is Item) { ItemFlags.SetStealable(o as Item, bool.Parse(value)); return "Property has been set."; } else return "Object is not an item"; } catch { found = false; } if (!found) return "Invalid Stealable assignment."; } // do a bit of parsing to handle array references string[] arraystring = propname.Split('['); int index = 0; if (arraystring.Length > 1) { // parse the property name from the indexing propname = arraystring[0]; // then parse to get the index value string[] arrayvalue = arraystring[1].Split(']'); if (arrayvalue.Length > 0) { try { index = int.Parse(arrayvalue[0]); } catch { } } } if (arglist.Length == 2) { PropertyInfo plookup = LookupPropertyInfo(spawner, type, propname); if (plookup != null) { //if ( !plookup.CanWrite ) //return "Property is read only."; if (BaseXmlSpawner.IsProtected(type, propname)) return "Property is protected."; ptype = plookup.PropertyType; po = plookup.GetValue(o, null); // now set the nested attribute using the new property list return (SetPropertyValue(spawner, po, arglist[1], value)); } else { // is a nested property with attributes so first get the property foreach (PropertyInfo p in props) { if (Insensitive.Equals(p.Name, propname)) { //CPA pattr = Properties.GetCPA( p ); //if ( pattr == null ) //return "Property not found."; //if ( !p.CanWrite ) //return "Property is read only."; if (BaseXmlSpawner.IsProtected(type, propname)) return "Property is protected."; ptype = p.PropertyType; po = p.GetValue(o, null); // now set the nested attribute using the new property list return (SetPropertyValue(spawner, po, arglist[1], value)); } } } } else { // its just a simple single property PropertyInfo plookup = LookupPropertyInfo(spawner, type, propname); if (plookup != null) { if (!plookup.CanWrite) return "Property is read only."; if (BaseXmlSpawner.IsProtected(type, propname)) return "Property is protected."; string returnvalue = InternalSetValue(null, o, plookup, value, false, index); return returnvalue; } else { // note, looping through all of the props turns out to be a significant performance bottleneck // good place for optimization foreach (PropertyInfo p in props) { if (Insensitive.Equals(p.Name, propname)) { if (!p.CanWrite) return "Property is read only."; if (BaseXmlSpawner.IsProtected(type, propname)) return "Property is protected."; string returnvalue = InternalSetValue(null, o, p, value, false, index); return returnvalue; } } } } return "Property not found."; }
public static void RemoveFromTagList(XmlSpawner spawner, KeywordTag tag) { for (int i = 0; i < spawner.m_KeywordTagList.Count; i++) { if (tag == spawner.m_KeywordTagList[i]) { spawner.m_KeywordTagList.RemoveAt(i); break; } } }
public static PropertyInfo LookupPropertyInfo(XmlSpawner spawner, Type type, string propname) { if (spawner == null || type == null || propname == null) return null; // look up the info in the current list if (spawner.PropertyInfoList == null) spawner.PropertyInfoList = new ArrayList(); PropertyInfo pinfo = null; TypeInfo tinfo = null; foreach (TypeInfo to in spawner.PropertyInfoList) { // check the type if (to.t == type) { // found it tinfo = to; // now search the property list foreach (PropertyInfo p in to.plist) { if (Insensitive.Equals(p.Name, propname)) { pinfo = p; } } } } // did we find the property? if (pinfo != null) { return pinfo; } else { // if it cant be found, then do the full search and add it to the list PropertyInfo[] props = type.GetProperties(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public); foreach (PropertyInfo p in props) { if (Insensitive.Equals(p.Name, propname)) { // did we find the type at least? if (tinfo == null) { // if not then add the type to the list tinfo = new TypeInfo(); tinfo.t = type; spawner.PropertyInfoList.Add(tinfo); } // and add the property to the tinfo property list tinfo.plist.Add(p); return p; } } } return null; }
public static KeywordTag GetFromTagList(XmlSpawner spawner, int serial) { for (int i = 0; i < spawner.m_KeywordTagList.Count; i++) { if (serial == ((KeywordTag)spawner.m_KeywordTagList[i]).Serial) { return ((KeywordTag)spawner.m_KeywordTagList[i]); } } return (null); }
public static string ApplySubstitution(XmlSpawner spawner, object o, Mobile trigmob, string typeName) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); // go through the string looking for instances of {keyword} string remaining = typeName; while (remaining != null && remaining.Length > 0) { int startindex = remaining.IndexOf('{'); if (startindex == -1 || startindex + 1 >= remaining.Length) { // if there are no more delimiters then append the remainder and finish sb.Append(remaining); break; } // might be a substitution, check for keywords int endindex = remaining.Substring(startindex + 1).IndexOf("}"); // if the ending delimiter cannot be found then just append and finish if (endindex == -1) { sb.Append(remaining); break; } // get the string up to the delimiter string firstpart = remaining.Substring(0, startindex); sb.Append(firstpart); string keypart = remaining.Substring(startindex + 1, endindex); // try to evaluate and then substitute the arg Type ptype; string value = ParseForKeywords(spawner, o, keypart.Trim(), trigmob, true, out ptype); // trim off the " from strings if (value != null) { value = value.Trim('"'); } // replace the parsed value for the keyword sb.Append(value); // continue processing the rest of the string if (endindex + startindex + 2 >= remaining.Length) break; remaining = remaining.Substring(endindex + startindex + 2, remaining.Length - endindex - startindex - 2); } return sb.ToString(); }
public static bool AddAttachmentToTarget(XmlSpawner spawner, object o, string[] keywordargs, string[] arglist, Mobile trigmob, object refobject, out string remainder, out string status_str) { remainder = ""; status_str = null; if (o == null || keywordargs == null || arglist == null) return false; // Use the format /ATTACH,drop_probability/attachmenttype,name[,args]/ // or /ATTACH,drop_probability/<attachmenttype,name[,args]/propname1/value1/propname2/value2/...>/ double drop_probability = 1; if (keywordargs.Length > 1) { bool converterror = false; try { drop_probability = Convert.ToDouble(keywordargs[1], CultureInfo.InvariantCulture); } catch { status_str = "Invalid drop probability : " + arglist[1]; converterror = true; } if (converterror) return false; } // o is the object to which the attachment will be attached // handle the nested item property specification using <> string attachargstring = null; // attachtypestr will be the actual attachment type to be created. In the simple form it will be arglist[1] // for the string /arg1/ATTACH/arg2/arg3/arg4/arg5 arglist [0] will contain ATTACH , arglist[1] will be arg2, // and arglist[2] will be arg3/arg4/arg5 // if nested property specs // arglist[1] will be <arg2 and arglist[2] will be arg3/ar4>/arg5 // the drop probability will be in probargs string[] probargs = ParseString(arglist[0], 2, ","); string attachtypestr = arglist[1]; // get the argument list after the < if any , note for the string /arg1/ATTACH/<arg2/arg3/arg4>/arg5 arglist [0] will contain ATTACH // arglist[1] will be <arg2 and arglist[2] will be arg3/ar4>/arg5 // but note arglist[1] could also be <arg2> // remainder will have ATTACH/<arg2/arg3/arg4>/arg5 // // can also deal with nested cases of ATTACH/<args/ADD/<args>> and ATTACH/<args/ADD/<args>/ADD/<args>> although there is no clear // reason why this syntax should be used at this time string addattachstr = arglist[1]; if (arglist.Length > 2) addattachstr = arglist[1] + "/" + arglist[2]; // check to see if the first char is a "<" if (addattachstr.IndexOf("<") == 0) { // attacharglist[1] will contain arg2/arg3/arg4>/arg5 // addattachstr should have the full list of args <arg2/arg3/arg4>/arg5 if they are there. In the case of /arg1/ADD/arg2 // it will just have arg2 string[] attacharglist = ParseString(addattachstr, 2, "<"); // take that argument list that should like like arg2/ag3/arg4>/arg5 // need to find the matching ">" //string[] attachargs = ParseString(attacharglist[1],2,">"); string[] attachargs = ParseToMatchingParen(attacharglist[1], '<', '>'); // and get the first part of the string without the > so attachargs[0] should be arg2/ag3/arg4 attachargstring = attachargs[0]; // and attachargs[1] should be the remainder if (attachargs.Length > 1) { // but have to get rid of any trailing / that might be after the > string[] trailstr = ParseSlashArgs(attachargs[1], 2); if (trailstr.Length > 1) remainder = trailstr[1]; else remainder = attachargs[1]; } else remainder = ""; // get the type info by pulling out the first arg in attachargstring string[] tempattacharg = ParseSlashArgs(attachargstring, 2); // and get the type info from it attachtypestr = tempattacharg[0]; } else { // otherwise its just a regular case with arglist[2] containing the rest of the arguments if (arglist.Length > 2) remainder = arglist[2]; else remainder = ""; } // test the drop probability if (Utility.RandomDouble() >= drop_probability) return true; Type type = null; if (attachtypestr != null) { try { type = SpawnerType.GetType(ParseObjectType(attachtypestr)); } catch { } } // if so then create it if (type != null && type.IsSubclassOf(typeof(XmlAttachment))) { object newo = XmlSpawner.CreateObject(type, attachtypestr, false, true); if (newo is XmlAttachment) { XmlAttachment attachment = newo as XmlAttachment; // could call applyobjectstringproperties on a nested propertylist here to set attachment attributes if (attachargstring != null) { ApplyObjectStringProperties(spawner, attachargstring, attachment, trigmob, refobject, out status_str); } // add the attachment to the target if (!XmlAttach.AttachTo(spawner, o, attachment)) { status_str = String.Format("Attachment {0} not added", attachtypestr); return false; } } else { status_str = "Invalid ATTACH. No such attachment : " + attachtypestr; return false; } } else { status_str = "Invalid ATTACH. No such attachment : " + attachtypestr; return false; } return true; }
// added in arg parsing to handle object property setting public static bool ApplyObjectStringProperties(XmlSpawner spawner, string str, object o, Mobile trigmob, object refobject, out string status_str) { status_str = null; if (str == null || str.Length <= 0 || o == null) return false; // object strings will be of the form "object/modifier" where the modifier string is of the form "propname/value/propname/value/..." // some keywords do not have value arguments so the modifier could take the form "propname/propname/value/..." // this is handled by parsing into both forms // make sure the string is properly terminated to assure proper parsing of any final keywords bool terminated = false; str = str.Trim(); if (str[str.Length - 1] != '/') { str += "/"; terminated = true; } string[] arglist; arglist = ParseSlashArgs(str, 2); string remainder = null; // place the modifier section of the string in remainder if (arglist.Length > 1) remainder = arglist[1]; bool no_error = true; // process the modifier string if there is anything while (arglist.Length > 1) { // place into arglist the parsed modifier up to this point // arglist[0] will contain the propname // arglist[1] will contain the value // arglist[2] will contain the reset of the modifier arglist = ParseSlashArgs(remainder, 3); // singlearglist will contain the propname and the remainder // for those keywords that do not have value args string[] singlearglist = ParseSlashArgs(remainder, 2); if (arglist.Length > 1) { // handle value keywords that may take comma args // itemarglist[1] will contain arg2/arg3/arg4>/arg5 // additemstr should have the full list of args <arg2/arg3/arg4>/arg5 if they are there. In the case of /arg1/ADD/arg2 // it will just have arg2 string[] groupedarglist = ParseString(arglist[1], 2, "["); // take that argument list that should like like arg2/ag3/arg4>/arg5 // need to find the matching ">" string[] groupargs = null; string groupargstring = null; if (groupedarglist.Length > 1) { groupargs = ParseToMatchingParen(groupedarglist[1], '[', ']'); // and get the first part of the string without the > so itemargs[0] should be arg2/ag3/arg4 groupargstring = groupargs[0]; } // need to handle comma args that may be grouped with the () such as the (ATTACHMENT,args) arg //string[] value_keywordargs = ParseString(groupedarglist[0],10,","); string[] value_keywordargs = groupedarglist[0].Trim().Split(','); if (groupargstring != null && groupargstring.Length > 0) { if (value_keywordargs != null && value_keywordargs.Length > 0) value_keywordargs[value_keywordargs.Length - 1] = groupargstring; } // handle propname keywords that may take comma args //string[] keywordargs = ParseString(arglist[0],10,","); string[] keywordargs = arglist[0].Trim().Split(','); // this quick optimization can determine whether this is a regular prop/value assignment // since most prop modification strings will use regular propnames and not keywords, it makes sense to check for that first if (value_keywordargs[0].Length > 0 && !Char.IsUpper(value_keywordargs[0][0]) && arglist[0].Length > 0 && !Char.IsUpper(arglist[0][0])) { // all of this code is also included in the keyword candidate tests // this is because regular props can also be entered with uppercase so the lowercase test is not definitive // restricted properties //if(arglist[0].ToLower() == "accesslevel") //{ // status_str = "accesslevel is a protected property"; // if(arglist.Length < 3) break; // remainder = arglist[2]; //} //else { // check for the literal char if (singlearglist[1] != null && singlearglist[1].Length > 0 && singlearglist[1][0] == '@') { string lstr = singlearglist[1]; if (terminated && lstr[lstr.Length - 1] == '/') lstr = lstr.Remove(lstr.Length - 1, 1); string result = SetPropertyValue(spawner, o, arglist[0], lstr.Remove(0, 1)); // see if it was successful if (result != "Property has been set.") { status_str = arglist[0] + " : " + result; no_error = false; } remainder = null; break; } else { string result = SetPropertyValue(spawner, o, arglist[0], arglist[1]); // see if it was successful if (result != "Property has been set.") { status_str = arglist[0] + " : " + result; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } } } else { if (IsValuemodKeyword(value_keywordargs[0])) { valuemodKeyword kw = (valuemodKeyword)valuemodKeywordHash[value_keywordargs[0]]; if (kw == valuemodKeyword.RND) { // generate a random number and use it as the property value. Use the format /RND,min,max/ if (value_keywordargs.Length > 2) { // get a random number string randvalue = "0"; try { randvalue = String.Format("{0}", Utility.RandomMinMax(int.Parse(value_keywordargs[1]), int.Parse(value_keywordargs[2]))); } catch { status_str = "Invalid RND args : " + arglist[1]; no_error = false; } // set the property value using the random number as the value string result = SetPropertyValue(spawner, o, arglist[0], randvalue); // see if it was successful if (result != "Property has been set.") { status_str = arglist[0] + " : " + result; no_error = false; } } else { status_str = "Invalid RND args : " + arglist[1]; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.RNDBOOL) { // generate a random bool and use it as the property value. Use the format /RNDBOOL/ string randvalue = Utility.RandomBool().ToString(); // set the property value using the random number as the value string result = SetPropertyValue(spawner, o, arglist[0], randvalue); // see if it was successful if (result != "Property has been set.") { status_str = arglist[0] + " : " + result; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.RNDLIST || kw == valuemodKeyword.RNDSTRLIST) { // generate a random number and use it as the property value. Use the format /RNDLIST,val1,val2,.../ if (value_keywordargs.Length > 1) { // compute a random index into the arglist int randindex = Utility.Random(1, value_keywordargs.Length - 1); // assign the list entry as the value string randvalue = value_keywordargs[randindex]; // set the property value string result = SetPropertyValue(spawner, o, arglist[0], randvalue); // see if it was successful if (result != "Property has been set.") { status_str = arglist[0] + " : " + result; no_error = false; } } else { status_str = "Invalid " + arglist[0] + " args : " + arglist[1]; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.MY) { // syntax is MY,property // note this will be an arg to some property if (value_keywordargs.Length > 1) { string resultstr = ApplyToProperty(spawner, o, o, value_keywordargs[1], arglist[0]); if (resultstr != null) { status_str = "MY error: " + resultstr; no_error = false; } } else { status_str = "Invalid MY args : " + arglist[1]; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.GET) { // syntax is GET,itemname[,itemtype],property // or GET,itemname[,itemtype],<ATTACHMENT,type,name,property> // note this will be an arg to some property if (value_keywordargs.Length > 2) { string propname = value_keywordargs[2]; string typestr = null; if (value_keywordargs.Length > 3) { propname = value_keywordargs[3]; typestr = value_keywordargs[2]; } // get the current property value //Type ptype; // get target item // is the itemname a serialno? object testitem = null; if (value_keywordargs[1].StartsWith("0x")) { int serial = -1; try { serial = Convert.ToInt32(value_keywordargs[1], 16); } catch { } if (serial >= 0) testitem = World.FindEntity(serial); } else { testitem = FindItemByName(spawner, value_keywordargs[1], typestr); } string resultstr = ApplyToProperty(spawner, testitem, o, propname, arglist[0]); if (resultstr != null) { status_str = "GET error: " + resultstr; no_error = false; } } else { status_str = "Invalid GET args : " + arglist[1]; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.GETVAR) { // syntax is GETVAR,varname if (value_keywordargs.Length > 1) { string varname = value_keywordargs[1]; // look for the xmllocalvariable attachment with the given name XmlLocalVariable var = (XmlLocalVariable)XmlAttach.FindAttachment(refobject, typeof(XmlLocalVariable), varname); if (var != null) { string result = SetPropertyValue(spawner, o, arglist[0], var.Data); // see if it was successful if (result != "Property has been set.") { status_str = arglist[0] + " : " + result; no_error = false; } } else { status_str = arglist[0] + " : No such var"; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else { status_str = "Invalid GETVAR args : " + arglist[1]; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.GETONMOB) { // syntax is GETONMOB,mobname[,mobtype],property // or GETONMOB,mobname[,mobtype],<ATTACHMENT,type,name,property> // note this will be an arg to some property if (value_keywordargs.Length > 2) { //if(trigmob != null && !trigmob.Deleted){ // get the current property value //Type ptype; // get target item string propname = value_keywordargs[2]; string typestr = null; if (value_keywordargs.Length > 3) { propname = value_keywordargs[3]; typestr = value_keywordargs[2]; } Mobile testmobile = FindMobileByName(spawner, value_keywordargs[1], typestr); string resultstr = ApplyToProperty(spawner, testmobile, o, propname, arglist[0]); if (resultstr != null) { status_str = "GETONMOB error: " + resultstr; no_error = false; } } else { status_str = "Invalid GETONMOB args : " + arglist[1]; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.GETONCARRIED) { // syntax is GETONCARRIED,itemname[,itemtype],property // or GETONCARRIED,itemname[,itemtype],<ATTACHMENT,type,name,property> // note this will be an arg to some property if (value_keywordargs.Length > 2) { if (trigmob != null && !trigmob.Deleted) { string propname = value_keywordargs[2]; string typestr = null; if (value_keywordargs.Length > 3) { propname = value_keywordargs[3]; typestr = value_keywordargs[2]; } // get the current property value //Type ptype; // get target item Item testitem = SearchMobileForItem(trigmob, ParseObjectType(value_keywordargs[1]), typestr, false); string resultstr = ApplyToProperty(spawner, testitem, o, propname, arglist[0]); if (resultstr != null) { status_str = "GETONCARRIED error: " + resultstr; no_error = false; } } else { no_error = false; } } else { status_str = "Invalid GETONCARRIED args : " + arglist[1]; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.GETONTRIGMOB) { // syntax is GETONTRIGMOB,property // or GETONTRIGMOB,<ATTACHMENT,type,name,property> // note this will be an arg to some property if (value_keywordargs.Length > 1) { if (trigmob != null && !trigmob.Deleted) { string resultstr = ApplyToProperty(spawner, trigmob, o, value_keywordargs[1], arglist[0]); if (resultstr != null) { status_str = "GETONTRIGMOB error: " + resultstr; no_error = false; } } else { no_error = false; } } else { status_str = "Invalid GETONTRIGMOB args : " + arglist[1]; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.GETONNEARBY) { // syntax is GETONNEARBY,range,name[,type][,searchcontainers],property // or GETONNEARBY,range,name[,type][,searchcontainers],[ATTACHMENT,type,name,property] // note this will be an arg to some property if (value_keywordargs.Length > 3) { string targetname = value_keywordargs[2]; string propname = value_keywordargs[3]; string typestr = null; bool searchcontainers = false; int range = -1; try { range = int.Parse(value_keywordargs[1]); } catch { } if (range < 0) { status_str = "invalid range in GETONNEARBY"; no_error = false; } if (value_keywordargs.Length > 4) { typestr = value_keywordargs[3]; propname = value_keywordargs[4]; } if (value_keywordargs.Length > 5) { try { searchcontainers = bool.Parse(value_keywordargs[3]); } catch { status_str = "invalid searchcontainer bool in GETONNEARBY"; no_error = false; } typestr = value_keywordargs[4]; propname = value_keywordargs[5]; } Type targettype = null; if (typestr != null) { targettype = SpawnerType.GetType(typestr); } if (no_error) { // get all of the nearby objects ArrayList nearbylist = GetNearbyObjects(spawner, targetname, targettype, typestr, range, searchcontainers,null); string resultstr = null; // apply the properties from the first valid thing on the list foreach (object nearbyobj in nearbylist) { resultstr = ApplyToProperty(spawner, nearbyobj, o, propname, arglist[0]); if (resultstr == null) break; } if (resultstr != null) { status_str = "GETONNEARBY error: " + resultstr; no_error = false; } } } else { status_str = "Invalid GETONNEARBY args : " + arglist[1]; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.GETONPARENT) { // syntax is GETONPARENT,property // or GETONPARENT,<ATTACHMENT,type,name,property> // note this will be an arg to some property if (value_keywordargs.Length > 1) { object parent = null; if (refobject is Item) { parent = ((Item)refobject).Parent; } else if (refobject is XmlAttachment) { parent = ((XmlAttachment)refobject).AttachedTo; } if (parent != null) { string resultstr = ApplyToProperty(spawner, parent, o, value_keywordargs[1], arglist[0]); if (resultstr != null) { status_str = "GETONPARENT error: " + resultstr; no_error = false; } } else { no_error = false; } } else { status_str = "Invalid GETONPARENT args : " + arglist[1]; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.GETONTHIS) { // syntax is GETONTHIS,property // or GETONTHIS,<ATTACHMENT,type,name,property> // note this will be an arg to some property if (value_keywordargs.Length > 1) { if (refobject != null) { string resultstr = ApplyToProperty(spawner, refobject, o, value_keywordargs[1], arglist[0]); if (resultstr != null) { status_str = "GETONTHIS error: " + resultstr; no_error = false; } } else { no_error = false; } } else { status_str = "Invalid GETONTHIS args : " + arglist[1]; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.GETONTAKEN) { // syntax is GETONTAKEN,property // or GETONTAKEN,<ATTACHMENT,type,name,property> // note this will be an arg to some property if (value_keywordargs.Length > 1) { // find the taken object Item taken = GetTaken(refobject); if (taken != null) { string resultstr = ApplyToProperty(spawner, taken, o, value_keywordargs[1], arglist[0]); if (resultstr != null) { status_str = "GETONTAKEN error: " + resultstr; no_error = false; } } else { no_error = false; } } else { status_str = "Invalid GETONTAKEN args : " + arglist[1]; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.GETONGIVEN) { // syntax is GETONGIVEN,property // or GETONGIVEN,<ATTACHMENT,type,name,property> // note this will be an arg to some property if (value_keywordargs.Length > 1) { // find the taken object Item taken = GetGiven(refobject); if (taken != null) { string resultstr = ApplyToProperty(spawner, taken, o, value_keywordargs[1], arglist[0]); if (resultstr != null) { status_str = "GETONGIVEN error: " + resultstr; no_error = false; } } else { no_error = false; } } else { status_str = "Invalid GETONGIVEN args : " + arglist[1]; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.GETONSPAWN) { // syntax is GETONSPAWN[,spawername],subgroup,property // or GETONSPAWN[,spawername],subgroup,<ATTACHMENT,type,name,property> // note this will be an arg to some property if (value_keywordargs.Length > 2) { string subgroupstr = value_keywordargs[1]; string propstr = value_keywordargs[2]; string spawnerstr = null; if (value_keywordargs.Length > 3) { spawnerstr = value_keywordargs[1]; subgroupstr = value_keywordargs[2]; propstr = value_keywordargs[3]; } // get the current property value //Type ptype; // get target object int subgroup = -1; try { subgroup = int.Parse(subgroupstr); } catch { } if (subgroup == -1) { status_str = "Invalid subgroup in GETONSPAWN"; no_error = false; } else { if (spawnerstr != null) { spawner = FindSpawnerByName(spawner, spawnerstr); if (spawner == null) { status_str = "Invalid spawnername in GETONSPAWN"; no_error = false; } } object targetobj = XmlSpawner.GetSpawned(spawner, subgroup); if (targetobj != null) { string resultstr = ApplyToProperty(spawner, targetobj, o, propstr, arglist[0]); if (resultstr != null) { status_str = "GETONSPAWN error: " + resultstr; no_error = false; } } else { no_error = false; } } } else { status_str = "Invalid GETONSPAWN args : " + arglist[1]; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.GETFROMFILE) { // syntax is GETFROMFILE,filename if (value_keywordargs.Length > 1) { string filename = value_keywordargs[1]; string filestring = null; // read in the string from the file if (System.IO.File.Exists(filename) == true) { try { // Create an instance of StreamReader to read from a file. // The using statement also closes the StreamReader. using (StreamReader sr = new StreamReader(filename)) { string line; // Read and display lines from the file until the end of // the file is reached. while ((line = sr.ReadLine()) != null) { filestring += line; } sr.Close(); } } catch { status_str = "GETFROMFILE error: " + filename; no_error = false; } // set the property value string result = SetPropertyValue(spawner, o, arglist[0], filestring); // see if it was successful if (result != "Property has been set.") { status_str = arglist[0] + " : " + result; no_error = false; } } } else { status_str = "Invalid GETFROMFILE args : " + arglist[1]; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.GETACCOUNTTAG) { // syntax is GETACCOUNTTAG,tagname if (value_keywordargs.Length > 1) { string tagname = value_keywordargs[1]; string tagvalue = null; // get the value of the account tag from the triggering mob if (trigmob != null && !trigmob.Deleted) { Account acct = trigmob.Account as Account; if (acct != null) { tagvalue = acct.GetTag(tagname); } } else { no_error = false; } if (tagvalue != null) { // set the property value string result = SetPropertyValue(spawner, o, arglist[0], tagvalue); // see if it was successful if (result != "Property has been set.") { status_str = arglist[0] + " : " + result; no_error = false; } } else { status_str = "Invalid GETACCOUNTTAG tagname : " + tagname; no_error = false; } } else { status_str = "Invalid GETACCOUNTTAG args : " + arglist[1]; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.MUL) { // increment the property value by the amount. Use the format propname/MUL,min,max/ or propname/MUL,value if (value_keywordargs.Length > 1) { // get a random number string incvalue = "0"; if (value_keywordargs.Length > 2) { try { int incarg0 = (int)(10000 * double.Parse(value_keywordargs[1])); int incarg1 = (int)(10000 * double.Parse(value_keywordargs[2])); incvalue = String.Format("{0}", Utility.RandomMinMax(incarg0, incarg1) / 10000.0); } catch { status_str = "Invalid MUL args : " + arglist[1]; no_error = false; } } else { incvalue = value_keywordargs[1]; } // get the current property value Type ptype; string tmpvalue = GetPropertyValue(spawner, o, arglist[0], out ptype); // see if it was successful if (ptype == null) { status_str = String.Format("Cant find {0}", arglist[0]); no_error = false; } else { string currentvalue = "0"; try { string[] arglist2 = ParseString(tmpvalue, 2, "="); string[] arglist3 = ParseString(arglist2[1], 2, " "); currentvalue = arglist3[0].Trim(); } catch { } string tmpstr = currentvalue; // should use the actual ptype info to do the multiplication. Maybe later. try { int tmpval = (int)(double.Parse(currentvalue) * double.Parse(incvalue)); tmpstr = tmpval.ToString(); } catch { status_str = "Invalid MUL args : " + arglist[1]; no_error = false; } // set the property value using the incremented value string result = SetPropertyValue(spawner, o, arglist[0], tmpstr); // see if it was successful if (result != "Property has been set.") { status_str = arglist[0] + " : " + result; no_error = false; } } } else { status_str = "Invalid MUL args : " + arglist[1]; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.INC) { // increment the property value by the amount. Use the format propname/INC,min,max/ or propname/INC,value if (value_keywordargs.Length > 1) { // get a random number string incvalue = "0"; if (value_keywordargs.Length > 2) { try { incvalue = String.Format("{0}", Utility.RandomMinMax(int.Parse(value_keywordargs[1]), int.Parse(value_keywordargs[2]))); } catch { status_str = "Invalid INC args : " + arglist[1]; no_error = false; } } else { incvalue = value_keywordargs[1]; } // get the current property value Type ptype; string tmpvalue = GetPropertyValue(spawner, o, arglist[0], out ptype); // see if it was successful if (ptype == null) { status_str = String.Format("Cant find {0}", arglist[0]); no_error = false; } else { string currentvalue = "0"; try { string[] arglist2 = ParseString(tmpvalue, 2, "="); string[] arglist3 = ParseString(arglist2[1], 2, " "); currentvalue = arglist3[0].Trim(); } catch { } string tmpstr = currentvalue; // should use the actual ptype info to do the addition. Maybe later. try { int tmpval = (int)(double.Parse(currentvalue) + double.Parse(incvalue)); tmpstr = tmpval.ToString(); } catch { status_str = "Invalid INC args : " + arglist[1]; no_error = false; } // set the property value using the incremented value string result = SetPropertyValue(spawner, o, arglist[0], tmpstr); // see if it was successful if (result != "Property has been set.") { status_str = arglist[0] + " : " + result; no_error = false; } } } else { status_str = "Invalid INC args : " + arglist[1]; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.MOB) { // lookup the mob id based on the name. format is /MOB,name[,type]/ if (value_keywordargs.Length > 1) { string typestr = null; if (value_keywordargs.Length > 2) { typestr = value_keywordargs[2]; } // lookup the name Mobile mob_id = null; try { mob_id = FindMobileByName(spawner, value_keywordargs[1], typestr); // the format of this will be 0xvalue "name" } catch { status_str = "Invalid MOB args : " + arglist[1]; no_error = false; } // set the property value using this format (M) id name string result = SetPropertyObject(spawner, o, arglist[0], mob_id); // see if it was successful if (result != "Property has been set.") { status_str = arglist[0] + " : " + result; no_error = false; } } else { no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.TRIGMOB) { string result = SetPropertyObject(spawner, o, arglist[0], trigmob); // see if it was successful if (result != "Property has been set.") { status_str = arglist[0] + " : " + result; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.AMOUNTCARRIED) { // syntax is AMOUNTCARRIED,itemtype int amount = 0; if (value_keywordargs.Length > 1) { string typestr = value_keywordargs[1]; // get the list of items being carried of the specified type Type targetType = SpawnerType.GetType(typestr); if (targetType != null && trigmob != null && trigmob.Backpack != null) { amount = trigmob.Backpack.GetAmount(targetType); } string result = SetPropertyValue(spawner, o, arglist[0], amount.ToString()); // see if it was successful if (result != "Property has been set.") { status_str = arglist[0] + " : " + result; no_error = false; } } else { status_str = "Invalid AMOUNTCARRIED args : " + arglist[1]; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.PLAYERSINRANGE) { // syntax is PLAYERSINRANGE,range int nplayers = 0; int range = 0; // get the number of players in range if (value_keywordargs.Length > 1) { try { range = int.Parse(value_keywordargs[1]); } catch { } } // count nearby players if (refobject is Item) { foreach (Mobile p in ((Item)refobject).GetMobilesInRange(range)) { if (p.Player && p.AccessLevel == AccessLevel.Player) nplayers++; } } else if (refobject is Mobile) { foreach (Mobile p in ((Mobile)refobject).GetMobilesInRange(range)) { if (p.Player && p.AccessLevel == AccessLevel.Player) nplayers++; } } string result = SetPropertyValue(spawner, o, arglist[0], nplayers.ToString()); // see if it was successful if (result != "Property has been set.") { status_str = arglist[0] + " : " + result; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.TRIGSKILL) { if (value_keywordargs.Length > 1) { if (spawner != null && spawner.TriggerSkill != null) { string skillstr = null; // syntax is TRIGSKILL,name|value|cap|base if (value_keywordargs[1].ToLower() == "name") { skillstr = spawner.TriggerSkill.Name; } else if (value_keywordargs[1].ToLower() == "value") { skillstr = spawner.TriggerSkill.Value.ToString(); } else if (value_keywordargs[1].ToLower() == "cap") { skillstr = spawner.TriggerSkill.Cap.ToString(); } else if (value_keywordargs[1].ToLower() == "base") { skillstr = spawner.TriggerSkill.Base.ToString(); } string result = SetPropertyValue(spawner, o, arglist[0], skillstr); // see if it was successful if (result != "Property has been set.") { status_str = arglist[0] + " : " + result; no_error = false; } } } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == valuemodKeyword.RANDNAME) { if (value_keywordargs.Length > 1) { string result = SetPropertyValue(spawner, o, arglist[0], NameList.RandomName(value_keywordargs[1])); // see if it was successful if (result != "Property has been set.") { status_str = arglist[0] + " : " + result; no_error = false; } } else { no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } } else if (IsTypemodKeyword(keywordargs[0])) { typemodKeyword kw = (typemodKeyword)typemodKeywordHash[keywordargs[0]]; if (kw == typemodKeyword.MUSIC) { SendMusicToPlayers(arglist[0], trigmob, refobject, out status_str); if (status_str != null) { no_error = false; } if (arglist.Length < 2) break; remainder = singlearglist[1]; } // // SOUND keyword // else if (kw == typemodKeyword.SOUND) { int sound = -1; // try to get the soundnumber argument if (keywordargs.Length < 2) { status_str = "Missing sound number"; no_error = false; } else { try { sound = int.Parse(keywordargs[1]); } catch { status_str = "Improper sound number format"; no_error = false; } } try { if (sound >= 0 && o is Mobile) { Effects.PlaySound(((Mobile)o).Location, ((Mobile)o).Map, sound); } else if (sound >= 0 && o is Item) { Effects.PlaySound(((Item)o).Location, ((Item)o).Map, sound); } } catch { } if (arglist.Length < 2) break; remainder = singlearglist[1]; } // // EFFECT keyword // else if (kw == typemodKeyword.EFFECT) { int effect = -1; int duration = 1; // syntax is EFFECT,itemid,duration,[x,y,z] // try to get the effect argument if (keywordargs.Length < 2) { status_str = "Missing effect number"; no_error = false; } else { try { effect = int.Parse(keywordargs[1]); } catch { status_str = "Improper effect number format"; no_error = false; } } if (keywordargs.Length > 2) { try { duration = int.Parse(keywordargs[2]); } catch { status_str = "Improper effect duration format"; no_error = false; } } // by default just use the spawn location Point3D eloc; Map emap = Map.Internal; if (o is Mobile) { eloc = ((Mobile)o).Location; emap = ((Mobile)o).Map; } else if (o is Item) { eloc = ((Item)o).Location; emap = ((Item)o).Map; } else { // should never get here eloc = new Point3D(0, 0, 0); } if (keywordargs.Length > 3) { // is this applied to the trig mob or to a location? if (keywordargs.Length > 5) { int x = 0; int y = 0; int z = 0; try { x = int.Parse(keywordargs[3]); y = int.Parse(keywordargs[4]); z = int.Parse(keywordargs[5]); } catch { status_str = "Improper effect location format"; } eloc = new Point3D(x, y, z); } } if (effect >= 0 && emap != Map.Internal) { Effects.SendLocationEffect(eloc, emap, effect, duration); } if (arglist.Length < 2) break; remainder = singlearglist[1]; } // // BOLTEFFECT keyword // else if (kw == typemodKeyword.BOLTEFFECT) { int sound = 0x29; int hue = 0; // syntax is BOLTEFFECT[,sound[,hue]] // try to get the effect argument if (keywordargs.Length > 1) { try { sound = int.Parse(keywordargs[1]); } catch { status_str = "Improper sound id"; no_error = false; } } if (keywordargs.Length > 2) { try { hue = int.Parse(keywordargs[2]); } catch { status_str = "Improper hue"; no_error = false; } } if (o is IEntity) { SendBoltEffect((IEntity)o, sound, hue); } if (arglist.Length < 2) break; remainder = singlearglist[1]; } // // MEFFECT keyword // else if (kw == typemodKeyword.MEFFECT) { int effect = -1; int duration = 0; int speed = 1; Point3D eloc1 = new Point3D(0, 0, 0); Point3D eloc2 = new Point3D(0, 0, 0); Map emap = Map.Internal; bool hasloc = false; // syntax is MEFFECT,itemid[,speed][,x,y,z][,x2,y2,z2] // try to get the effect argument if (keywordargs.Length < 2) { status_str = "Missing effect number"; no_error = false; } else { try { effect = int.Parse(keywordargs[1]); } catch { status_str = "Improper effect number format"; no_error = false; } } if (keywordargs.Length > 2) { try { speed = int.Parse(keywordargs[2]); } catch { status_str = "Improper effect speed format"; no_error = false; } } // by default just use the spawn location if (o is Mobile) { eloc2 = ((Mobile)o).Location; emap = ((Mobile)o).Map; } else if (o is Item) { eloc2 = ((Item)o).Location; emap = ((Item)o).Map; } if (keywordargs.Length > 8) { int x = 0; int y = 0; int z = 0; try { x = int.Parse(keywordargs[3]); y = int.Parse(keywordargs[4]); z = int.Parse(keywordargs[5]); } catch { status_str = "Improper effect location format"; } eloc1 = new Point3D(x, y, z); try { x = int.Parse(keywordargs[6]); y = int.Parse(keywordargs[7]); z = int.Parse(keywordargs[8]); } catch { status_str = "Improper effect location format"; } eloc2 = new Point3D(x, y, z); hasloc = true; } else if (keywordargs.Length > 5) { int x = 0; int y = 0; int z = 0; try { x = int.Parse(keywordargs[3]); y = int.Parse(keywordargs[4]); z = int.Parse(keywordargs[5]); } catch { status_str = "Improper effect location format"; } eloc1 = new Point3D(x, y, z); hasloc = true; } if (effect >= 0 && hasloc && emap != Map.Internal) { Effects.SendPacket(eloc1, emap, new HuedEffect(EffectType.Moving, -1, -1, effect, eloc1, eloc2, speed, duration, false, false, 0, 0)); } else if (effect >= 0 && refobject is IEntity && o is IEntity) { //Effects.SendLocationEffect(eloc, emap, effect, duration); //public static void SendMovingEffect( IEntity from, IEntity to, int itemID, int speed, int duration, bool fixedDirection, bool explodes ) Effects.SendMovingEffect((IEntity)refobject, (IEntity)o, effect, speed, duration, false, false); } if (arglist.Length < 2) break; remainder = singlearglist[1]; } // // PEFFECT keyword // else if (kw == typemodKeyword.PEFFECT) { int effect = -1; int duration = 1; // syntax is PEFFECT,itemid,duration,[x,y,z] // try to get the effect argument if (keywordargs.Length < 2) { status_str = "Missing effect number"; no_error = false; } else { try { effect = int.Parse(keywordargs[1]); } catch { status_str = "Improper effect number format"; no_error = false; } } if (keywordargs.Length > 2) { try { duration = int.Parse(keywordargs[2]); } catch { status_str = "Improper effect duration format"; no_error = false; } } // by default just use the spawn location Point3D eloc; Map emap = Map.Internal; if (o is Mobile) { eloc = ((Mobile)o).Location; emap = ((Mobile)o).Map; } else if (o is Item) { eloc = ((Item)o).Location; emap = ((Item)o).Map; } else { // should never get here eloc = new Point3D(0, 0, 0); } if (keywordargs.Length > 3) { // is this applied to the trig mob or to a location? if (keywordargs.Length > 5) { int x = 0; int y = 0; int z = 0; try { x = int.Parse(keywordargs[3]); y = int.Parse(keywordargs[4]); z = int.Parse(keywordargs[5]); } catch { status_str = "Improper effect location format"; } eloc = new Point3D(x, y, z); } } if (effect >= 0 && emap != Map.Internal) { Effects.SendLocationEffect(eloc, emap, effect, duration); } if (arglist.Length < 2) break; remainder = singlearglist[1]; } // // POISON keyword // else if (kw == typemodKeyword.POISON) { ApplyPoisonToPlayers(arglist[0], o as Mobile, o, out status_str); //ApplyPoisonToPlayers(arglist[0], trigmob, refobject, out status_str); if (status_str != null) { no_error = false; } if (arglist.Length < 2) break; remainder = singlearglist[1]; } else if (kw == typemodKeyword.DAMAGE) { ApplyDamageToPlayers(arglist[0], o as Mobile, o, out status_str); //ApplyDamageToPlayers(arglist[0], trigmob, refobject, out status_str); if (status_str != null) { no_error = false; } if (arglist.Length < 2) break; remainder = singlearglist[1]; } else if (kw == typemodKeyword.ADD) { no_error = AddItemToTarget(spawner, o, keywordargs, arglist, trigmob, refobject, false, out remainder, out status_str); } else if (kw == typemodKeyword.EQUIP) { no_error = AddItemToTarget(spawner, o, keywordargs, arglist, trigmob, refobject, true, out remainder, out status_str); } else if (kw == typemodKeyword.DELETE) { if (o is Item) { ((Item)o).Delete(); } else if (o is Mobile) { if (!((Mobile)o).Player) { ((Mobile)o).Delete(); } } else if (o is XmlAttachment) { ((XmlAttachment)o).Delete(); } if (arglist.Length < 2) break; remainder = singlearglist[1]; } else if (kw == typemodKeyword.KILL) { if (o is Mobile) { ((Mobile)o).Kill(); } if (arglist.Length < 2) break; remainder = singlearglist[1]; } else if (kw == typemodKeyword.UNEQUIP) { // syntax is UNEQUIP,layer[,delete] Layer layer = Layer.Invalid; bool remove = false; if (keywordargs.Length > 1) { try { layer = (Layer)Enum.Parse(typeof(Layer), keywordargs[1], true); } catch { status_str = "Invalid layer"; } } if (keywordargs.Length > 2) { if (keywordargs[2] == "delete") { remove = true; } } if (o is Mobile && layer != Layer.Invalid) { Mobile m = (Mobile)o; // go through all of the items on the mobile List<Item> packlist = m.Items; for (int i = 0; i < packlist.Count; ++i) { Item item = (Item)packlist[i]; // check the layer // if it matches then unequip it if (item.Layer == layer) { if (remove) { item.Delete(); } else { m.AddToBackpack(item); } } } } if (status_str != null) { no_error = false; } if (arglist.Length < 2) break; remainder = singlearglist[1]; } else if (kw == typemodKeyword.ATTACH) { no_error = AddAttachmentToTarget(spawner, o, keywordargs, arglist, trigmob, refobject, out remainder, out status_str); } else if (kw == typemodKeyword.MSG) { // syntax is MSG[,probability][,hue] // if the object is a mobile then display a msg over the mob or item double drop_probability = 1; int hue = 0x3b2; if (keywordargs.Length > 1) { try { drop_probability = Convert.ToDouble(keywordargs[1], CultureInfo.InvariantCulture); } catch { status_str = "Invalid msg probability : " + arglist[1]; no_error = false; } } if (keywordargs.Length > 2) { try { hue = int.Parse(keywordargs[2]); } catch { status_str = "Invalid MSG hue : " + arglist[1]; no_error = false; } } if (hue < 0) hue = 0; if (o is Mobile || o is Item) { string msgstr = arglist[1]; // test the drop probability if (Utility.RandomDouble() < drop_probability) { if (o is Mobile) ((Mobile)o).PublicOverheadMessage(MessageType.Regular, hue, false, msgstr); else if (o is Item) ((Item)o).PublicOverheadMessage(MessageType.Regular, hue, false, msgstr); } } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == typemodKeyword.ASCIIMSG) { // syntax is ASCIIMSG[,probability][,hue][,font] // if the object is a mobile then display a msg over the mob or item double drop_probability = 1; int hue = 0x3b2; int font = 3; if (keywordargs.Length > 1) { try { drop_probability = Convert.ToDouble(keywordargs[1], CultureInfo.InvariantCulture); } catch { status_str = "Invalid msg probability : " + arglist[1]; no_error = false; } } if (keywordargs.Length > 2) { try { hue = int.Parse(keywordargs[2]); } catch { status_str = "Invalid MSG hue : " + arglist[1]; no_error = false; } } if (keywordargs.Length > 3) { try { font = int.Parse(keywordargs[3]); } catch { status_str = "Invalid MSG font : " + arglist[1]; no_error = false; } } if (hue < 0) hue = 0; if (font < 0) font = 0; if (o is Mobile || o is Item) { string msgstr = arglist[1]; // test the drop probability if (Utility.RandomDouble() < drop_probability) { if (o is Mobile) PublicOverheadMobileMessage((Mobile)o, MessageType.Regular, hue, font, msgstr, true); else if (o is Item) PublicOverheadItemMessage((Item)o, MessageType.Regular, hue, font, msgstr); } } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == typemodKeyword.SENDMSG) { // syntax is SENDMSG[,probability][,hue]/msg // if the object is a mobile then display a msg over the mob or item double drop_probability = 1; int hue = 0x3b2; int font = 3; if (keywordargs.Length > 1) { try { drop_probability = Convert.ToDouble(keywordargs[1], CultureInfo.InvariantCulture); } catch { status_str = "Invalid msg probability : " + arglist[1]; no_error = false; } } if (keywordargs.Length > 2) { try { hue = int.Parse(keywordargs[2]); } catch { status_str = "Invalid SENDMSG hue : " + arglist[1]; no_error = false; } } if (hue < 0) hue = 0; if (o is Mobile) { string msgstr = arglist[1]; // test the drop probability if (Utility.RandomDouble() < drop_probability) { ((Mobile)o).Send(new UnicodeMessage(Serial.MinusOne, -1, MessageType.Regular, hue, font, "ENU", "System", msgstr)); } } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == typemodKeyword.SENDASCIIMSG) { // syntax is SENDASCIIMSG[,probability][,hue][,font] // if the object is a mobile then display a msg over the mob or item double drop_probability = 1; int hue = 0x3b2; int font = 3; if (keywordargs.Length > 1) { try { drop_probability = Convert.ToDouble(keywordargs[1], CultureInfo.InvariantCulture); } catch { status_str = "Invalid msg probability : " + arglist[1]; no_error = false; } } if (keywordargs.Length > 2) { try { hue = int.Parse(keywordargs[2]); } catch { status_str = "Invalid MSG hue : " + arglist[1]; no_error = false; } } if (keywordargs.Length > 3) { try { font = int.Parse(keywordargs[3]); } catch { status_str = "Invalid MSG font : " + arglist[1]; no_error = false; } } if (hue < 0) hue = 0; if (font < 0) font = 0; if (o is Mobile) { string msgstr = arglist[1]; // test the drop probability if (Utility.RandomDouble() < drop_probability) { ((Mobile)o).Send(new AsciiMessage(Serial.MinusOne, -1, MessageType.Regular, hue, font, "System", msgstr)); } } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == typemodKeyword.SAY) { // if the object is a mobile then display a msg over the mob double drop_probability = 1; if (keywordargs.Length > 1) { try { drop_probability = Convert.ToDouble(keywordargs[1], CultureInfo.InvariantCulture); } catch { status_str = "Invalid say probability : " + arglist[1]; no_error = false; } } if (o is Mobile) { string msgstr = arglist[1]; // test the drop probability if (Utility.RandomDouble() < drop_probability) { ((Mobile)o).Say(msgstr); } } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == typemodKeyword.SPEECH) { // syntax is SPEECH[,probability][,keywordnumber] // if the object is a mobile then have it speak with optional keyword arg double drop_probability = 1; if (keywordargs.Length > 1) { try { drop_probability = Convert.ToDouble(keywordargs[1], CultureInfo.InvariantCulture); } catch { status_str = "Invalid speech probability : " + arglist[1]; no_error = false; } } int keyword_number = -1; if (keywordargs.Length > 2) { try { keyword_number = int.Parse(keywordargs[2]); } catch { status_str = "Invalid keyword number : " + arglist[1]; no_error = false; } } if (o is Mobile) { string msgstr = arglist[1]; // test the drop probability if (Utility.RandomDouble() < drop_probability) { int[] keywordarray = new int[] { }; if (keyword_number >= 0) { keywordarray = new int[] { keyword_number }; } ((Mobile)o).DoSpeech(msgstr, keywordarray, MessageType.Regular, 0x3B2); } } if (arglist.Length < 3) break; remainder = arglist[2]; } else if (kw == typemodKeyword.OFFSET) { // syntax is OFFSET,x,y[,z] // shift the location of the object by the specified amount int xoffset = 0; int yoffset = 0; int zoffset = 0; if (keywordargs.Length > 2) { try { xoffset = int.Parse(keywordargs[1]); yoffset = int.Parse(keywordargs[2]); } catch { status_str = "Invalid xy offset : " + arglist[1]; no_error = false; } } if (keywordargs.Length > 3) { try { zoffset = int.Parse(keywordargs[3]); } catch { status_str = "Invalid zoffset : " + arglist[1]; no_error = false; } } if (o is Mobile) { Point3D loc = ((Mobile)o).Location; ((Mobile)o).Location = new Point3D(loc.X + xoffset, loc.Y + yoffset, loc.Z + zoffset); } else if (o is Item) { Point3D loc = ((Item)o).Location; ((Item)o).Location = new Point3D(loc.X + xoffset, loc.Y + yoffset, loc.Z + zoffset); } if (arglist.Length < 2) break; remainder = singlearglist[1]; } else if (kw == typemodKeyword.ANIMATE) { // syntax is ANIMATE,action[,framecount][,repeatcount][,forward true/false][,repeat true/false][delay] // Animate( int action, int frameCount, int repeatCount, bool forward, bool repeat, int delay ) int action = -1; int framecount = 7; int repeatcount = 1; bool forward = true; bool repeat = false; int delay = 0; if (keywordargs.Length > 1) { try { action = int.Parse(keywordargs[1]); } catch { status_str = "Invalid action : " + arglist[1]; no_error = false; } } if (keywordargs.Length > 2) { try { framecount = int.Parse(keywordargs[2]); } catch { status_str = "Invalid framecount : " + arglist[1]; no_error = false; } } if (keywordargs.Length > 3) { try { repeatcount = int.Parse(keywordargs[3]); } catch { status_str = "Invalid repeatcount : " + arglist[1]; no_error = false; } } if (keywordargs.Length > 4) { try { forward = bool.Parse(keywordargs[4]); } catch { status_str = "Invalid forward : " + arglist[1]; no_error = false; } } if (keywordargs.Length > 5) { try { repeat = bool.Parse(keywordargs[5]); } catch { status_str = "Invalid repeat : " + arglist[1]; no_error = false; } } if (keywordargs.Length > 6) { try { delay = int.Parse(keywordargs[6]); } catch { status_str = "Invalid delay : " + arglist[1]; no_error = false; } } if (o is Mobile && action >= 0) { ((Mobile)o).Animate(action, framecount, repeatcount, forward, repeat, delay); } if (arglist.Length < 2) break; remainder = singlearglist[1]; } else if (kw == typemodKeyword.BCAST) { // syntax is BCAST[,hue][,font]/message int hue = 0x482; int font = -1; // default unicode messages if (keywordargs.Length > 1) { try { hue = int.Parse(keywordargs[1]); } catch { status_str = "Invalid hue : " + arglist[1]; no_error = false; } } if (keywordargs.Length > 2) { try { font = int.Parse(keywordargs[2]); } catch { status_str = "Invalid font : " + arglist[1]; no_error = false; } } if (font >= 0) { // broadcast an ascii message to all players BroadcastAsciiMessage(AccessLevel.Player, hue, font, arglist[1]); } else { // broadcast a message to all players CommandHandlers.BroadcastMessage(AccessLevel.Player, hue, arglist[1]); } if (arglist.Length < 3) break; remainder = arglist[2]; } } //else // check for protected properties // if(arglist[0].ToLower() == "accesslevel") //{ // status_str = "accesslevel is a protected property"; // if(arglist.Length < 3) break; // remainder = arglist[2]; //} else { // check for the literal char if (singlearglist[1] != null && singlearglist[1].Length > 0 && singlearglist[1][0] == '@') { string lstr = singlearglist[1]; if (terminated && lstr[lstr.Length - 1] == '/') lstr = lstr.Remove(lstr.Length - 1, 1); string result = SetPropertyValue(spawner, o, arglist[0], lstr.Remove(0, 1)); // see if it was successful if (result != "Property has been set.") { status_str = arglist[0] + " : " + result; no_error = false; } remainder = null; break; } else { string result = SetPropertyValue(spawner, o, arglist[0], arglist[1]); // see if it was successful if (result != "Property has been set.") { status_str = arglist[0] + " : " + result; no_error = false; } if (arglist.Length < 3) break; remainder = arglist[2]; } } } } } return (no_error); }
public static void AddToRecentSpawnerSearchList(XmlSpawner spawner, XmlSpawner target) { if (spawner == null || target == null) return; if (spawner.RecentSpawnerSearchList == null) { spawner.RecentSpawnerSearchList = new ArrayList(); } spawner.RecentSpawnerSearchList.Add(target); // check the length and truncate if it gets too long if (spawner.RecentSpawnerSearchList.Count > 100) { spawner.RecentSpawnerSearchList.RemoveAt(0); } }
public static void AddSpawnItem(XmlSpawner spawner, object invoker, XmlSpawner.SpawnObject theSpawn, Item item, Point3D location, Map map, Mobile trigmob, bool requiresurface, List<XmlSpawner.SpawnPositionInfo> spawnpositioning, string propertyString, bool smartspawn, out string status_str) { status_str = null; if (item == null || theSpawn == null) return; // add the item to the spawned list theSpawn.SpawnedObjects.Add(item); item.Spawner = spawner; if (spawner != null) { // this is being called by a spawner so use spawner information for placement if (!spawner.Deleted) { // set the item amount if (spawner.StackAmount > 1 && item.Stackable) { item.Amount = spawner.StackAmount; } // if this is in any container such as a pack then add to the container. if (spawner.Parent is Container) { Container c = (Container)spawner.Parent; Point3D loc = spawner.Location; if (!smartspawn) { item.OnBeforeSpawn(loc, map); } item.Location = loc; // check to see whether we drop or add the item based on the spawnrange // this will distribute multiple items around the spawn point, and allow precise // placement of single spawns at the spawn point if (spawner.SpawnRange > 0) c.DropItem(item); else c.AddItem(item); } else { // if the spawn entry is in a subgroup and has a packrange, then get the packcoord Point3D packcoord = Point3D.Zero; if (theSpawn.PackRange >= 0 && theSpawn.SubGroup > 0) { packcoord = spawner.GetPackCoord(theSpawn.SubGroup); } Point3D loc = spawner.GetSpawnPosition(requiresurface, theSpawn.PackRange, packcoord, spawnpositioning); if (!smartspawn) { item.OnBeforeSpawn(loc, map); } // standard placement for all items in the world item.MoveToWorld(loc, map); } } else { // if the spawner has already been deleted then delete the item since it cannot be cleaned up by spawner deletion any longer item.Delete(); return; } } else { if (!smartspawn) { item.OnBeforeSpawn(location, map); } // use the location and map info passed in // this allows AddSpawnItem to be called by objects other than spawners as long as they pass in a valid SpawnObject item.MoveToWorld(location, map); } // clear the taken flag on all newly spawned items ItemFlags.SetTaken(item, false); if (!smartspawn) { item.OnAfterSpawn(); } // apply the parsed arguments from the typestring using setcommand // be sure to do this after setting map and location so that errors dont place the mob on the internal map BaseXmlSpawner.ApplyObjectStringProperties(spawner, propertyString, item, trigmob, spawner, out status_str); // if the object has an OnAfterSpawnAndModify method, then invoke it //InvokeOnAfterSpawnAndModify(item); }
public static void AddSpawnItem(XmlSpawner spawner, XmlSpawner.SpawnObject theSpawn, Item item, Point3D location, Map map, Mobile trigmob, bool requiresurface, List<XmlSpawner.SpawnPositionInfo> spawnpositioning, string propertyString, bool smartspawn, out string status_str) { AddSpawnItem(spawner, spawner, theSpawn, item, location, map, trigmob, requiresurface, spawnpositioning, propertyString, smartspawn, out status_str); }
public static void AddSpawnItem(XmlSpawner spawner, object invoker, XmlSpawner.SpawnObject theSpawn, Item item, Point3D location, Map map, Mobile trigmob, bool requiresurface, string propertyString, out string status_str) { AddSpawnItem(spawner, invoker, theSpawn, item, location, map, trigmob, requiresurface, null, propertyString, false, out status_str); }
public static Mobile FindMobileByName(XmlSpawner fromspawner, string name, string typestr) { if (name == null) return (Mobile)null; int count = 0; Mobile foundmobile = FindInRecentMobileSearchList(fromspawner, name, typestr); if (foundmobile != null) return foundmobile; Type targettype = null; if (typestr != null) { targettype = SpawnerType.GetType(typestr); } // search through all mobiles in the world and find one with a matching name foreach (Mobile mobile in World.Mobiles.Values) { Type mobtype = mobile.GetType(); if (!mobile.Deleted && (typestr == null || (mobtype != null && targettype != null && (mobtype.Equals(targettype) || mobtype.IsSubclassOf(targettype)))) && ((name.Length == 0 || String.Compare(mobile.Name, name, true) == 0))) { foundmobile = mobile; count++; // added the break in to return the first match instead of forcing uniqueness (overrides the count test) break; } //if(count > 1) break; } // if a unique item is found then success if (count == 1) { // add this to the recent search list AddToRecentMobileSearchList(fromspawner, foundmobile); return (foundmobile); } else return (Mobile)null; }
public static XmlSpawner FindSpawnerByName(XmlSpawner fromspawner, string name) { if (name == null) return (XmlSpawner)null; int count = 0; // do a quick search through the recent search list to see if it is there XmlSpawner foundspawner = FindInRecentSpawnerSearchList(fromspawner, name); if (foundspawner != null) return foundspawner; // search through all xmlspawners in the world and find one with a matching name foreach (Item item in World.Items.Values) { if (item is XmlSpawner) { XmlSpawner spawner = (XmlSpawner)item; if (!spawner.Deleted && (String.Compare(spawner.Name, name, true) == 0)) { foundspawner = spawner; count++; // added the break in to return the first match instead of forcing uniqueness (overrides the count test) break; } //if(count > 1) break; } } // if a unique item is found then success if (count == 1) { // add this to the recent search list AddToRecentSpawnerSearchList(fromspawner, foundspawner); return (foundspawner); } else return (XmlSpawner)null; }
// ------------------------------------------------------------- // End modified Beta-36 Properties.cs code // ------------------------------------------------------------- public static string ApplyToProperty(XmlSpawner spawner, object getobject, object setobject, string getpropertystring, string setpropertystring) { Type ptype; string getvalue = GetPropertyValue(spawner, getobject, getpropertystring, out ptype); if (getvalue == null) { return "Null object or property"; } if (ptype == null) { return getvalue; } string value2 = ParseGetValue(getvalue, ptype); if (value2 != null) { // set the property value using returned get value as the the value string result = SetPropertyValue(spawner, setobject, setpropertystring, value2); // see if it was successful if (result != "Property has been set.") { return setpropertystring + " : " + result; } } return null; }
public static string GetPropertyValue(XmlSpawner spawner, object o, string name, out Type ptype) { ptype = null; if (o == null || name == null) return null; Type type = o.GetType(); object po = null; if ( o != null && o is PlayerMobile && ((PlayerMobile)o).AccessLevel >= AccessLevel.Administrator ) return "Access denied"; PropertyInfo[] props = null; try { props = type.GetProperties(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public); } catch { Console.WriteLine("GetProperties error with type {0}", type); return null; } // parse the strings of the form property.attribute into two parts // first get the property string[] arglist = ParseString(name, 2, "."); string propname = arglist[0]; // parse up to 4 comma separated args for special keyword properties string[] keywordargs = ParseString(propname, 4, ","); // check for special keywords if (keywordargs[0] == "ATTACHMENT") { // syntax is ATTACHMENT,type,name,property if (keywordargs.Length < 4) { return "Invalid ATTACHMENT format"; } string apropname = keywordargs[3]; string aname = keywordargs[2]; Type attachtype = SpawnerType.GetType(keywordargs[1]); // allow empty string specifications to be used to indicate a null string which will match any name if (aname == "") aname = null; ArrayList attachments = XmlAttach.FindAttachments(o, attachtype, aname); if (attachments != null && attachments.Count > 0) { string getvalue = GetPropertyValue(spawner, attachments[0], apropname, out ptype); return getvalue; } else return "Attachment not found"; } else if (keywordargs[0] == "SKILL") { // syntax is SKILL,skillname if (keywordargs.Length < 2) { return "Invalid SKILL format"; } bool found = true; try { SkillName skillname = (SkillName)Enum.Parse(typeof(SkillName), keywordargs[1], true); if (o is Mobile) { Skill skill = ((Mobile)o).Skills[skillname]; ptype = skill.Value.GetType(); return String.Format("{0} = {1}", skillname, skill.Value); } else return "Object is not mobile"; } catch { found = false; } if (!found) return "Skill not found."; } else if (keywordargs[0] == "SERIAL") { bool found = true; try { if (o is Mobile) { ptype = ((Mobile)o).Serial.GetType(); return String.Format("Serial = {0}", ((Mobile)o).Serial); } else if (o is Item) { ptype = ((Item)o).Serial.GetType(); return String.Format("Serial = {0}", ((Item)o).Serial); } else return "Object is not item/mobile"; } catch { found = false; } if (!found) return "Serial not found."; } else if (keywordargs[0] == "TYPE") { ptype = typeof(Type); return String.Format("Type = {0}", o.GetType().Name); } else if (keywordargs[0] == "STEALABLE") { bool found = true; try { if (o is Item) { ptype = typeof(bool); return String.Format("Stealable = {0}", ItemFlags.GetStealable(o as Item)); } else return "Object is not an item"; } catch { found = false; } if (!found) return "Stealable flag not found."; } // do a bit of parsing to handle array references string[] arraystring = arglist[0].Split('['); int index = -1; if (arraystring.Length > 1) { // parse the property name from the indexing propname = arraystring[0]; // then parse to get the index value string[] arrayvalue = arraystring[1].Split(']'); if (arrayvalue.Length > 0) { try { index = int.Parse(arrayvalue[0]); } catch { } } } if (arglist.Length == 2) { // use the lookup table for optimization if possible PropertyInfo plookup = LookupPropertyInfo(spawner, type, propname); if (plookup != null) { if (!plookup.CanRead) return "Property is write only."; //if ( BaseXmlSpawner.IsProtected(type, propname) ) //return "Property is protected."; ptype = plookup.PropertyType; if (ptype.IsPrimitive) { po = plookup.GetValue(o, null); } else if ((ptype.GetInterface("IList") != null) && index >= 0) { try { object arrayvalue = plookup.GetValue(o, null); po = ((IList)arrayvalue)[index]; } catch { } } else { po = plookup.GetValue(o, null); } // now set the nested attribute using the new property list return (GetPropertyValue(spawner, po, arglist[1], out ptype)); } else { // is a nested property with attributes so first get the property foreach (PropertyInfo p in props) { //if ( Insensitive.Equals( p.Name, arglist[0] ) ) if (Insensitive.Equals(p.Name, propname)) { if (!p.CanRead) return "Property is write only."; //if ( BaseXmlSpawner.IsProtected(type, propname) ) //return "Property is protected."; ptype = p.PropertyType; if (ptype.IsPrimitive) { po = p.GetValue(o, null); } else if ((ptype.GetInterface("IList") != null) && index >= 0) { try { object arrayvalue = p.GetValue(o, null); po = ((IList)arrayvalue)[index]; } catch { } } else { po = p.GetValue(o, null); } // now set the nested attribute using the new property list return (GetPropertyValue(spawner, po, arglist[1], out ptype)); } } } } else { // use the lookup table for optimization if possible PropertyInfo plookup = LookupPropertyInfo(spawner, type, propname); if (plookup != null) { if (!plookup.CanRead) return "Property is write only."; ptype = plookup.PropertyType; return InternalGetValue(o, plookup, index); } else { // its just a simple single property foreach (PropertyInfo p in props) { //if ( Insensitive.Equals( p.Name, name ) ) if (Insensitive.Equals(p.Name, propname)) { if (!p.CanRead) return "Property is write only."; ptype = p.PropertyType; return InternalGetValue(o, p, index); } } } } return "Property not found."; }
public static bool AddItemToTarget(XmlSpawner spawner, object o, string[] keywordargs, string[] arglist, Mobile trigmob, object refobject, bool equip, out string remainder, out string status_str) { remainder = ""; status_str = null; if (o == null || keywordargs == null || arglist == null) return false; // if the object is a mobile then add the item in the next arg to its pack. Use the format /ADD,drop_probability/itemtype/ // or /ADD,drop_probability/<itemtype/propname1/value1/propname2/value2/...>/ double drop_probability = 1; if (keywordargs.Length > 1) { bool converterror = false; try { drop_probability = Convert.ToDouble(keywordargs[1], CultureInfo.InvariantCulture); } catch { status_str = "Invalid drop probability : " + arglist[1]; converterror = true; } if (converterror) return false; } Mobile m = null; if (o is Mobile || (o is Container)) { Container pack = null; if (o is Mobile) { m = (Mobile)o; if (!m.Deleted) { pack = m.Backpack; // auto add a pack if the mob doesnt have one if (pack == null) { pack = new Backpack(); m.AddItem(pack); } } } else { pack = o as Container; } if (pack != null) { // handle the nested item property specification using <> string itemargstring = null; // itemtypestr will be the actual item type to be created. In the simple form it will be arglist[1] // for the string /arg1/ADD/arg2/arg3/arg4/arg5 arglist [0] will contain ADD , arglist[1] will be arg2, // and arglist[2] will be arg3/arg4/arg5 // if nested property specs // arglist[1] will be <arg2 and arglist[2] will be arg3/ar4>/arg5 // the drop probability will be in probargs string[] probargs = ParseCommaArgs(arglist[0], 2); string itemtypestr = arglist[1]; // get the argument list after the < if any , note for the string /arg1/ADD/<arg2/arg3/arg4>/arg5 arglist [0] will contain ADD // arglist[1] will be <arg2 and arglist[2] will be arg3/ar4>/arg5 // but note arglist[1] could also be <arg2> // remainder will have ADD/<arg2/arg3/arg4>/arg5 // // also need to deal with nested cases of ADD/<args/ADD/<args>> and ADD/<args/ADD/<args>/ADD<args>> string additemstr = arglist[1]; if (arglist.Length > 2) additemstr = arglist[1] + "/" + arglist[2]; // check to see if the first char is a "<" if (additemstr.IndexOf("<") == 0) { // itemarglist[1] will contain arg2/arg3/arg4>/arg5 // additemstr should have the full list of args <arg2/arg3/arg4>/arg5 if they are there. In the case of /arg1/ADD/arg2 // it will just have arg2 string[] itemarglist = ParseString(additemstr, 2, "<"); // take that argument list that should like like arg2/ag3/arg4>/arg5 // need to find the matching ">" //string[] itemargs = ParseString(itemarglist[1],2,">"); string[] itemargs = ParseToMatchingParen(itemarglist[1], '<', '>'); // and get the first part of the string without the > so itemargs[0] should be arg2/ag3/arg4 itemargstring = itemargs[0]; // and itemargs[1] should be the remainder if (itemargs.Length > 1) { // but have to get rid of any trailing / that might be after the > string[] trailstr = ParseSlashArgs(itemargs[1], 2); if (trailstr.Length > 1) remainder = trailstr[1]; else remainder = itemargs[1]; } else remainder = ""; // get the type info by pulling out the first arg in itemargstring string[] tempitemarg = ParseSlashArgs(itemargstring, 2); // and get the type info from it itemtypestr = tempitemarg[0]; } else { // otherwise its just a regular case with arglist[2] containing the rest of the arguments if (arglist.Length > 2) remainder = arglist[2]; else remainder = ""; } // test the drop probability if (Utility.RandomDouble() >= drop_probability) return true; // is it a valid item specification? string baseitemtype = ParseObjectType(itemtypestr); if (IsSpecialItemKeyword(baseitemtype)) { // itemtypestr will have the form keyword[,x[,y]] string[] itemkeywordargs = ParseCommaArgs(itemtypestr, 3); itemKeyword kw = (itemKeyword)itemKeywordHash[baseitemtype]; switch (kw) { // deal with the special keywords case itemKeyword.ARMOR: { // syntax is ARMOR,min,max //get the min,max if (itemkeywordargs.Length == 3) { int min = 0; int max = 0; bool converterror = false; try { min = int.Parse(itemkeywordargs[1]); } catch { status_str = "Invalid ARMOR args : " + itemtypestr; converterror = true; } try { max = int.Parse(itemkeywordargs[2]); } catch { status_str = "Invalid ARMOR args : " + itemtypestr; converterror = true; } if (converterror) return false; Item item = MagicArmor(min, max, false, false); if (item != null) { if (equip && m != null) { if (!m.EquipItem(item)) pack.DropItem(item); } else { pack.DropItem(item); } // could call applyobjectstringproperties on a nested propertylist here to set item attributes if (itemargstring != null) { ApplyObjectStringProperties(spawner, itemargstring, item, trigmob, refobject, out status_str); } } } else { status_str = "ARMOR takes 2 args : " + itemtypestr; return false; } break; } case itemKeyword.WEAPON: { // syntax is WEAPON,min,max //get the min,max if (itemkeywordargs.Length == 3) { int min = 0; int max = 0; bool converterror = false; try { min = int.Parse(itemkeywordargs[1]); } catch { status_str = "Invalid WEAPON args : " + itemtypestr; converterror = true; } try { max = int.Parse(itemkeywordargs[2]); } catch { status_str = "Invalid WEAPON args : " + itemtypestr; converterror = true; } if (converterror) return false; Item item = MagicWeapon(min, max, false); if (item != null) { if (equip && m != null) { if (!m.EquipItem(item)) pack.DropItem(item); } else pack.DropItem(item); // could call applyobjectstringproperties on a nested propertylist here to set item attributes if (itemargstring != null) { ApplyObjectStringProperties(spawner, itemargstring, item, trigmob, refobject, out status_str); } } } else { status_str = "WEAPON takes 2 args : " + itemtypestr; return false; } break; } case itemKeyword.JEWELRY: { // syntax is JEWELRY,min,max //get the min,max if (itemkeywordargs.Length == 3) { int min = 0; int max = 0; bool converterror = false; try { min = int.Parse(itemkeywordargs[1]); } catch { status_str = "Invalid JEWELRY args : " + itemtypestr; converterror = true; } try { max = int.Parse(itemkeywordargs[2]); } catch { status_str = "Invalid JEWELRY args : " + itemtypestr; converterror = true; } if (converterror) return false; Item item = MagicJewelry(min, max); if (item != null) { if (equip && m != null) { if (!m.EquipItem(item)) pack.DropItem(item); } else pack.DropItem(item); // could call applyobjectstringproperties on a nested propertylist here to set item attributes if (itemargstring != null) { ApplyObjectStringProperties(spawner, itemargstring, item, trigmob, refobject, out status_str); } } } else { status_str = "JEWELRY takes 2 args : " + itemtypestr; return false; } break; } case itemKeyword.SHIELD: { // syntax is SHIELD,min,max //get the min,max if (itemkeywordargs.Length == 3) { int min = 0; int max = 0; bool converterror = false; try { min = int.Parse(itemkeywordargs[1]); } catch { status_str = "Invalid SHIELD args : " + itemtypestr; converterror = true; } try { max = int.Parse(itemkeywordargs[2]); } catch { status_str = "Invalid SHIELD args : " + itemtypestr; converterror = true; } if (converterror) return false; Item item = MagicShield(min, max); if (item != null) { if (equip && m != null) { if (!m.EquipItem(item)) pack.DropItem(item); } else pack.DropItem(item); // could call applyobjectstringproperties on a nested propertylist here to set item attributes if (itemargstring != null) { ApplyObjectStringProperties(spawner, itemargstring, item, trigmob, refobject, out status_str); } } } else { status_str = "SHIELD takes 2 args : " + itemtypestr; return false; } break; } case itemKeyword.JARMOR: { // syntax is JARMOR,min,max //get the min,max if (itemkeywordargs.Length == 3) { int min = 0; int max = 0; bool converterror = false; try { min = int.Parse(itemkeywordargs[1]); } catch { status_str = "Invalid JARMOR args : " + itemtypestr; converterror = true; } try { max = int.Parse(itemkeywordargs[2]); } catch { status_str = "Invalid JARMOR args : " + itemtypestr; converterror = true; } if (converterror) return false; Item item = MagicArmor(min, max, true, true); if (item != null) { if (equip && m != null) { if (!m.EquipItem(item)) pack.DropItem(item); } else pack.DropItem(item); // could call applyobjectstringproperties on a nested propertylist here to set item attributes if (itemargstring != null) { ApplyObjectStringProperties(spawner, itemargstring, item, trigmob, refobject, out status_str); } } } else { status_str = "JARMOR takes 2 args : " + itemtypestr; return false; } break; } case itemKeyword.SARMOR: { // syntax is SARMOR,min,max //get the min,max if (itemkeywordargs.Length == 3) { int min = 0; int max = 0; bool converterror = false; try { min = int.Parse(itemkeywordargs[1]); } catch { status_str = "Invalid SARMOR args : " + itemtypestr; converterror = true; } try { max = int.Parse(itemkeywordargs[2]); } catch { status_str = "Invalid SARMOR args : " + itemtypestr; converterror = true; } if (converterror) return false; Item item = MagicArmor(min, max, false, true); if (item != null) { if (equip && m != null) { if (!m.EquipItem(item)) pack.DropItem(item); } else pack.DropItem(item); // could call applyobjectstringproperties on a nested propertylist here to set item attributes if (itemargstring != null) { ApplyObjectStringProperties(spawner, itemargstring, item, trigmob, refobject, out status_str); } } } else { status_str = "SARMOR takes 2 args : " + itemtypestr; return false; } break; } case itemKeyword.JWEAPON: { // syntax is JWEAPON,min,max //get the min,max if (itemkeywordargs.Length == 3) { int min = 0; int max = 0; bool converterror = false; try { min = int.Parse(itemkeywordargs[1]); } catch { status_str = "Invalid JWEAPON args : " + itemtypestr; converterror = true; } try { max = int.Parse(itemkeywordargs[2]); } catch { status_str = "Invalid JWEAPON args : " + itemtypestr; converterror = true; } if (converterror) return false; Item item = MagicWeapon(min, max, true); if (item != null) { if (equip && m != null) { if (!m.EquipItem(item)) pack.DropItem(item); } else pack.DropItem(item); // could call applyobjectstringproperties on a nested propertylist here to set item attributes if (itemargstring != null) { ApplyObjectStringProperties(spawner, itemargstring, item, trigmob, refobject, out status_str); } } } else { status_str = "JWEAPON takes 2 args : " + itemtypestr; return false; } break; } case itemKeyword.SCROLL: { // syntax is SCROLL,mincircle,maxcircle //get the min,max if (itemkeywordargs.Length == 3) { int minCircle = 0; int maxCircle = 0; bool converterror = false; try { minCircle = int.Parse(itemkeywordargs[1]); } catch { status_str = "Invalid SCROLL args : " + itemtypestr; converterror = true; } try { maxCircle = int.Parse(itemkeywordargs[2]); } catch { status_str = "Invalid SCROLL args : " + itemtypestr; converterror = true; } if (converterror) return false; int circle = Utility.RandomMinMax(minCircle, maxCircle); int min = (circle - 1) * 8; Item item = Loot.RandomScroll(min, min + 7, SpellbookType.Regular); if (item != null) { pack.DropItem(item); // could call applyobjectstringproperties on a nested propertylist here to set item attributes if (itemargstring != null) { ApplyObjectStringProperties(spawner, itemargstring, item, trigmob, refobject, out status_str); } } } else { status_str = "SCROLL takes 2 args : " + itemtypestr; return false; } break; } case itemKeyword.POTION: { // syntax is POTION Item item = Loot.RandomPotion(); if (item != null) { pack.DropItem(item); // could call applyobjectstringproperties on a nested propertylist here to set item attributes if (itemargstring != null) { ApplyObjectStringProperties(spawner, itemargstring, item, trigmob, refobject, out status_str); } } break; } case itemKeyword.TAKEN: { // syntax is TAKEN Item item = GetTaken(refobject); if (item != null) { pack.DropItem(item); // could call applyobjectstringproperties on a nested propertylist here to set item attributes if (itemargstring != null) { ApplyObjectStringProperties(spawner, itemargstring, item, trigmob, refobject, out status_str); } } break; } case itemKeyword.GIVEN: { // syntax is GIVEN Item item = GetGiven(refobject); if (item != null) { pack.DropItem(item); // could call applyobjectstringproperties on a nested propertylist here to set item attributes if (itemargstring != null) { ApplyObjectStringProperties(spawner, itemargstring, item, trigmob, refobject, out status_str); } } break; } case itemKeyword.LOOT: { // syntax is LOOT,methodname if (itemkeywordargs.Length == 2) { Item item = null; // look up the method Type ltype = typeof(Loot); if (ltype != null) { MethodInfo method = null; try { // get the zero-arg method with the specified name method = ltype.GetMethod(itemkeywordargs[1], new Type[0]); } catch { } if (method != null && method.IsStatic) { ParameterInfo[] pinfo = method.GetParameters(); // check to make sure the method for this object has the right args if (pinfo.Length == 0) { // method must be public static with no arguments returning an Item class object try { item = method.Invoke(null, null) as Item; } catch { } } else { status_str = "LOOT method must be zero arg : " + itemtypestr; return false; } } else { status_str = "LOOT no valid method found : " + itemtypestr; return false; } } if (item != null) { pack.DropItem(item); // could call applyobjectstringproperties on a nested propertylist here to set item attributes if (itemargstring != null) { ApplyObjectStringProperties(spawner, itemargstring, item, trigmob, refobject, out status_str); } } } else { status_str = "LOOT takes 1 arg : " + itemtypestr; return false; } break; } case itemKeyword.NECROSCROLL: { // syntax is NECROSCROLL,index if (itemkeywordargs.Length == 2) { int index = 0; bool converterror = false; try { index = int.Parse(itemkeywordargs[1]); } catch { status_str = "Invalid NECROSCROLL args : " + itemtypestr; converterror = true; } if (converterror) return false; if (Core.AOS) { Item item = Loot.Construct(Loot.NecromancyScrollTypes, index); if (item != null) { pack.DropItem(item); // could call applyobjectstringproperties on a nested propertylist here to set item attributes if (itemargstring != null) { ApplyObjectStringProperties(spawner, itemargstring, item, trigmob, refobject, out status_str); } } } } else { status_str = "NECROSCROLL takes 1 arg : " + itemtypestr; return false; } break; } case itemKeyword.LOOTPACK: { // syntax is LOOTPACK,type if (itemkeywordargs.Length == 2) { LootPack lootpack = null; string loottype = itemkeywordargs[1]; if (loottype.ToLower() == "poor") { lootpack = LootPack.Poor; } else if (loottype.ToLower() == "meager") { lootpack = LootPack.Meager; } else if (loottype.ToLower() == "average") { lootpack = LootPack.Average; } else if (loottype.ToLower() == "rich") { lootpack = LootPack.Rich; } else if (loottype.ToLower() == "filthyrich") { lootpack = LootPack.FilthyRich; } else if (loottype.ToLower() == "ultrarich") { lootpack = LootPack.UltraRich; } else if (loottype.ToLower() == "superboss") { lootpack = LootPack.SuperBoss; } else { status_str = "Invalid LOOTPACK type: " + loottype; return false; } int m_KillersLuck = 0; if (trigmob != null) { m_KillersLuck = LootPack.GetLuckChanceForKiller(trigmob); } bool converterror = false; try { // generate the nospawn component of the lootpack lootpack.Generate(m, pack, false, m_KillersLuck); // generate the spawn component (basically gold) requires a mobile and wont work in containers // because Generate does a test for TryDropItem for stackables which requires a valid mob argument, // any stackable generated in a container will fail // so just test for a valid mobile and only do the atspawn generate for them. if (m != null) lootpack.Generate(m, pack, true, m_KillersLuck); } catch { status_str = "Unable to add LOOTPACK"; converterror = true; } if (converterror) return false; } else { status_str = "LOOTPACK takes 1 arg : " + itemtypestr; return false; } break; } } } else { Type type = null; try { type = SpawnerType.GetType(ParseObjectType(itemtypestr)); } catch { } // if so then create it if (type != null) { object newo = XmlSpawner.CreateObject(type, itemtypestr); if (newo is Item) { Item item = newo as Item; if (equip && m != null) { if (!m.EquipItem(item)) pack.DropItem(item); } else pack.DropItem(item); // could call applyobjectstringproperties on a nested propertylist here to set item attributes if (itemargstring != null) { ApplyObjectStringProperties(spawner, itemargstring, item, trigmob, refobject, out status_str); } } else { status_str = "Invalid ADD. No such item : " + itemtypestr; if (newo is BaseCreature) ((BaseCreature)newo).Delete(); return false; } } else { status_str = "Invalid ADD. No such item : " + itemtypestr; return false; } } } else { status_str = "Invalid ADD. mobile has no pack."; if (arglist.Length < 3) return false; remainder = arglist[2]; return false; } } else { status_str = "Invalid ADD. must be mobile or container."; if (arglist.Length < 3) return false; remainder = arglist[2]; return false; } return true; }
public static string ParseForKeywords(XmlSpawner spawner, object o, string valstr, Mobile trigmob, bool literal, out Type ptype) { ptype = null; if (valstr == null || valstr.Length <= 0) return null; string str = valstr.Trim(); // look for keywords // need to handle the case of nested arglists like arg,arg,<arg,arg> // handle value keywords that may take comma args // itemarglist[1] will contain arg2/arg3/arg4>/arg5 // additemstr should have the full list of args <arg2/arg3/arg4>/arg5 if they are there. In the case of /arg1/ADD/arg2 // it will just have arg2 string[] groupedarglist = ParseString(str, 2, "["); // take that argument list that should like like arg2/ag3/arg4>/arg5 // need to find the matching ">" string[] groupargs = null; string groupargstring = null; if (groupedarglist.Length > 1) { groupargs = ParseToMatchingParen(groupedarglist[1], '[', ']'); // and get the first part of the string without the > so itemargs[0] should be arg2/ag3/arg4 groupargstring = groupargs[0]; } // need to handle comma args that may be grouped with the () such as the (ATTACHMENT,args) arg //string[] arglist = ParseString(groupedarglist[0],4,","); string[] arglist = groupedarglist[0].Trim().Split(','); if (groupargstring != null && groupargstring.Length > 0) { if (arglist != null && arglist.Length > 0) arglist[arglist.Length - 1] = groupargstring; } string pname = arglist[0].Trim(); char startc = str[0]; // first see whether it is a standard numeric value if ((startc == '.') || (startc == '-') || (startc == '+') || (startc >= '0' && startc <= '9')) { // determine the type if (str.IndexOf(".") >= 0) { ptype = typeof(Double); } else { ptype = typeof(Int32); } return str; } else // or a string if (startc == '"' || startc == '(') { ptype = typeof(String); return str; } else // or an enum if (startc == '#') { ptype = typeof(String); return str.Substring(1); } // or a bool else if ((str.ToLower()) == "true" || (str.ToLower() == "false")) { ptype = typeof(Boolean); return str; } // then look for a keyword else if (IsValueKeyword(pname)) { valueKeyword kw = (valueKeyword)valueKeywordHash[pname]; //if(pname == "GETONMOB" && arglist.Length > 2) if ((kw == valueKeyword.GETONMOB) && arglist.Length > 2) { // syntax is GETONMOB,mobname[,mobtype],property string propname = arglist[2]; string typestr = null; if (arglist.Length > 3) { typestr = arglist[2]; propname = arglist[3]; } Mobile testmobile = FindMobileByName(spawner, arglist[1], typestr); string getvalue = GetPropertyValue(spawner, testmobile, propname, out ptype); return ParseGetValue(getvalue, ptype); } else if ((kw == valueKeyword.GET) && arglist.Length > 2) { // syntax is GET,itemname[,itemtype],property string propname = arglist[2]; string typestr = null; if (arglist.Length > 3) { typestr = arglist[2]; propname = arglist[3]; } // is the itemname a serialno? object testitem = null; if (arglist[1].StartsWith("0x")) { int serial = -1; try { serial = Convert.ToInt32(arglist[1], 16); } catch { } if (serial >= 0) testitem = World.FindEntity(serial); } else { testitem = FindItemByName(spawner, arglist[1], typestr); } string getvalue = GetPropertyValue(spawner, testitem, propname, out ptype); return ParseGetValue(getvalue, ptype); } else if ((kw == valueKeyword.GETONCARRIED) && arglist.Length > 2) { // syntax is GETONCARRIED,itemname[,itemtype],property string propname = arglist[2]; string typestr = null; // if the itemtype arg has been specified then check it if (arglist.Length > 3) { propname = arglist[3]; typestr = arglist[2]; } Item testitem = SearchMobileForItem(trigmob, ParseObjectType(arglist[1]), typestr, false); string getvalue = GetPropertyValue(spawner, testitem, propname, out ptype); return ParseGetValue(getvalue, ptype); } else if ((kw == valueKeyword.GETONNEARBY) && arglist.Length > 3) { // syntax is GETONNEARBY,range,name[,type][,searchcontainers],property // or GETONNEARBY,range,name[,type][,searchcontainers],[ATTACHMENT,type,name,property] string targetname = arglist[2]; string propname = arglist[3]; string typestr = null; bool searchcontainers = false; int range = -1; try { range = int.Parse(arglist[1]); } catch { } if (arglist.Length > 4) { typestr = arglist[3]; propname = arglist[4]; } if (arglist.Length > 5) { try { searchcontainers = bool.Parse(arglist[4]); } catch { } propname = arglist[5]; } Type targettype = null; if (typestr != null) { targettype = SpawnerType.GetType(typestr); } if (range >= 0) { // get all of the nearby objects ArrayList nearbylist = GetNearbyObjects(spawner, targetname, targettype, typestr, range, searchcontainers, null); // apply the properties from the first valid thing on the list foreach (object nearbyobj in nearbylist) { string getvalue = GetPropertyValue(spawner, nearbyobj, propname, out ptype); return ParseGetValue(getvalue, ptype); } } else return null; } else if ((kw == valueKeyword.GETONTRIGMOB) && arglist.Length > 1) { // syntax is GETONTRIGMOB,property string getvalue = GetPropertyValue(spawner, trigmob, arglist[1], out ptype); return ParseGetValue(getvalue, ptype); } else if ((kw == valueKeyword.GETVAR) && arglist.Length > 1) { // syntax is GETVAR,varname string varname = arglist[1]; if (o is XmlAttachment) o = ((XmlAttachment)o).AttachedTo; // look for the xmllocalvariable attachment with the given name XmlLocalVariable var = (XmlLocalVariable)XmlAttach.FindAttachment(o, typeof(XmlLocalVariable), varname); if (var != null) { return var.Data; } else { return null; } } else if ((kw == valueKeyword.GETONPARENT) && arglist.Length > 1) { // syntax is GETONPARENT,property string getvalue = null; if (o is Item) { getvalue = GetPropertyValue(spawner, ((Item)o).Parent, arglist[1], out ptype); } else if (o is XmlAttachment) { getvalue = GetPropertyValue(spawner, ((XmlAttachment)o).AttachedTo, arglist[1], out ptype); } return ParseGetValue(getvalue, ptype); } else if ((kw == valueKeyword.GETONGIVEN) && arglist.Length > 1) { // syntax is GETONGIVEN,property Item taken = null; if (o is XmlAttachment) { taken = GetGiven(((XmlAttachment)o).AttachedTo); } else { taken = GetGiven(o); } string getvalue = GetPropertyValue(spawner, taken, arglist[1], out ptype); return ParseGetValue(getvalue, ptype); } else if ((kw == valueKeyword.GETONTAKEN) && arglist.Length > 1) { // syntax is GETONTAKEN,property Item taken = null; if (o is XmlAttachment) { taken = GetTaken(((XmlAttachment)o).AttachedTo); } else { taken = GetTaken(o); } string getvalue = GetPropertyValue(spawner, taken, arglist[1], out ptype); return ParseGetValue(getvalue, ptype); } else if ((kw == valueKeyword.GETONTHIS) && arglist.Length > 1) { // syntax is GETONTHIS,property string getvalue = GetPropertyValue(spawner, o, arglist[1], out ptype); return ParseGetValue(getvalue, ptype); } else if ((kw == valueKeyword.GETONSPAWN) && arglist.Length > 2) { // syntax is GETONSPAWN[,spawnername],subgroup,property // get the target from the spawn list string subgroupstr = arglist[1]; string propstr = arglist[2]; string spawnerstr = null; if (arglist.Length > 3) { spawnerstr = arglist[1]; subgroupstr = arglist[2]; propstr = arglist[3]; } int subgroup = -1; try { subgroup = int.Parse(subgroupstr); } catch { } if (subgroup == -1) return null; if (spawnerstr != null) { spawner = FindSpawnerByName(spawner, spawnerstr); } // check for the special COUNT property keyword if (propstr == "COUNT") { ptype = typeof(int); // get all of the currently active spawns with the specified subgroup ArrayList so = XmlSpawner.GetSpawnedList(spawner, subgroup); if (so == null) return "0"; // and return the count return so.Count.ToString(); } else { object targetobj = XmlSpawner.GetSpawned(spawner, subgroup); if (targetobj == null) return null; string getvalue = GetPropertyValue(spawner, targetobj, propstr, out ptype); return ParseGetValue(getvalue, ptype); } } else if ((kw == valueKeyword.GETFROMFILE) && arglist.Length > 1) { // syntax is GETFROMFILE,filename ptype = typeof(string); string filename = arglist[1]; string filestring = null; // read in the string from the file if (System.IO.File.Exists(filename) == true) { try { // Create an instance of StreamReader to read from a file. // The using statement also closes the StreamReader. using (StreamReader sr = new StreamReader(filename)) { string line; // Read and display lines from the file until the end of // the file is reached. while ((line = sr.ReadLine()) != null) { filestring += line; } sr.Close(); } } catch { } } return filestring; } else if ((kw == valueKeyword.GETACCOUNTTAG) && arglist.Length > 1) { // syntax is GETACCOUNTTAG,tagname ptype = typeof(string); string tagname = arglist[1]; string tagvalue = null; // get the value of the account tag from the triggering mob if (trigmob != null && !trigmob.Deleted) { Account acct = trigmob.Account as Account; if (acct != null) { tagvalue = '"' + acct.GetTag(tagname) + '"'; } } return tagvalue; } else if ((kw == valueKeyword.RND) && arglist.Length > 2) { // syntax is RND,min,max string randvalue = "0"; ptype = typeof(Int32); try { randvalue = String.Format("{0}", Utility.RandomMinMax(int.Parse(arglist[1]), int.Parse(arglist[2]))); } catch { } // return the random number as the value return randvalue; } else if ((kw == valueKeyword.RNDBOOL)) { // syntax is RNDBOOL ptype = typeof(bool); // return the random number as the value return Utility.RandomBool().ToString(); } else if ((kw == valueKeyword.RNDLIST) && arglist.Length > 1) { // syntax is RNDLIST,val1,val2,... ptype = typeof(Int32); // compute a random index into the arglist int randindex = Utility.Random(1, arglist.Length - 1); // return the list entry as the value return arglist[randindex]; } else if ((kw == valueKeyword.RNDSTRLIST) && arglist.Length > 1) { // syntax is RNDSTRLIST,val1,val2,... ptype = typeof(string); // compute a random index into the arglist int randindex = Utility.Random(1, arglist.Length - 1); // return the list entry as the value return arglist[randindex]; } else if ((kw == valueKeyword.AMOUNTCARRIED) && arglist.Length > 1) { // syntax is AMOUNTCARRIED,itemtype ptype = typeof(Int32); int amount = 0; string typestr = arglist[1]; if (typestr != null) { // get the list of items being carried of the specified type Type targetType = SpawnerType.GetType(typestr); if (targetType != null && trigmob != null && trigmob.Backpack != null) { amount = trigmob.Backpack.GetAmount(targetType); } } return amount.ToString(); } else if ((kw == valueKeyword.PLAYERSINRANGE) && arglist.Length > 1) { // syntax is PLAYERSINRANGE,range ptype = typeof(Int32); int nplayers = 0; int range = 0; // get the number of players in range try { range = int.Parse(arglist[1]); } catch { } // count nearby players if (o is Item) { foreach (Mobile p in ((Item)o).GetMobilesInRange(range)) { if (p.Player && p.AccessLevel == AccessLevel.Player) nplayers++; } } else if (o is Mobile) { foreach (Mobile p in ((Mobile)o).GetMobilesInRange(range)) { if (p.Player && p.AccessLevel == AccessLevel.Player) nplayers++; } } return nplayers.ToString(); } else if ((kw == valueKeyword.TRIGSKILL) && arglist.Length > 1) { if (spawner != null && spawner.TriggerSkill != null) { // syntax is TRIGSKILL,name|value|cap|base if (arglist[1].ToLower() == "name") { ptype = typeof(string); return spawner.TriggerSkill.Name; } else if (arglist[1].ToLower() == "value") { ptype = typeof(double); return spawner.TriggerSkill.Value.ToString(); } else if (arglist[1].ToLower() == "cap") { ptype = typeof(double); return spawner.TriggerSkill.Cap.ToString(); } else if (arglist[1].ToLower() == "base") { ptype = typeof(double); return spawner.TriggerSkill.Base.ToString(); } } return null; } if ((kw == valueKeyword.RANDNAME) && arglist.Length > 1) { // syntax is RANDNAME,nametype return NameList.RandomName(arglist[1]); } else { // an invalid keyword format will be passed as literal return str; } } else if (literal) { ptype = typeof(String); return str; } else { // otherwise treat it as a property name string result = GetPropertyValue(spawner, o, pname, out ptype); return ParseGetValue(result, ptype); } }
public static bool CheckPropertyString(XmlSpawner spawner, object o, string testString, Mobile trigmob, out string status_str) { status_str = null; if (o == null) return false; if (testString == null || testString.Length < 1) { status_str = "Null property test string"; return false; } // parse the property test string for and(&)/or(|) operators string[] arglist = ParseString(testString, 2, "&|"); if (arglist.Length < 2) { bool returnval = CheckSingleProperty(spawner, o, testString, trigmob, out status_str); // simple conditional test with no and/or operators return returnval; } else { // test each half independently and combine the results bool first = CheckSingleProperty(spawner, o, arglist[0], trigmob, out status_str); // this will recursively parse the property test string with implicit nesting for multiple logical tests of the // form A * B * C * D being grouped as A * (B * (C * D)) bool second = CheckPropertyString(spawner, o, arglist[1], trigmob, out status_str); int andposition = testString.IndexOf("&"); int orposition = testString.IndexOf("|"); // combine them based upon the operator if ((andposition > 0 && orposition <= 0) || (andposition > 0 && andposition < orposition)) { // and operator return (first && second); } else if ((orposition > 0 && andposition <= 0) || (orposition > 0 && orposition < andposition)) { // or operator return (first || second); } else { // should never get here return false; } } }
public static string SetPropertyObject(XmlSpawner spawner, object o, string name, object value) { if (o == null) { return "Null object"; } if ( o != null && o is PlayerMobile && ((PlayerMobile)o).AccessLevel >= AccessLevel.Administrator ) return "Access denied"; Type ptype = null; object po = null; Type type = o.GetType(); PropertyInfo[] props = type.GetProperties(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public); // parse the strings of the form property.attribute into two parts // first get the property string[] arglist = ParseString(name, 2, "."); if (arglist.Length == 2) { // is a nested property with attributes so first get the property // use the lookup table for optimization if possible PropertyInfo plookup = LookupPropertyInfo(spawner, type, arglist[0]); if (plookup != null) { //if ( !plookup.CanWrite ) //return "Property is read only."; if (BaseXmlSpawner.IsProtected(type, arglist[0])) return "Property is protected."; ptype = plookup.PropertyType; po = plookup.GetValue(o, null); // now set the nested attribute using the new property list return (SetPropertyObject(spawner, po, arglist[1], value)); } else { foreach (PropertyInfo p in props) { if (Insensitive.Equals(p.Name, arglist[0])) { //if ( !p.CanWrite ) //return "Property is read only."; if (BaseXmlSpawner.IsProtected(type, arglist[0])) return "Property is protected."; ptype = p.PropertyType; po = p.GetValue(o, null); // now set the nested attribute using the new property list return (SetPropertyObject(spawner, po, arglist[1], value)); } } } } else { // its just a simple single property // use the lookup table for optimization if possible PropertyInfo plookup = LookupPropertyInfo(spawner, type, name); if (plookup != null) { if (!plookup.CanWrite) return "Property is read only."; if (BaseXmlSpawner.IsProtected(type, name)) return "Property is protected."; if (plookup.PropertyType == typeof(Server.Mobile)) { plookup.SetValue(o, value, null); return "Property has been set."; } else { return "Property is not of type Mobile."; } } else { foreach (PropertyInfo p in props) { if (Insensitive.Equals(p.Name, name)) { if (!p.CanWrite) return "Property is read only."; if (BaseXmlSpawner.IsProtected(type, name)) return "Property is protected."; if (p.PropertyType == typeof(Server.Mobile)) { p.SetValue(o, value, null); return "Property has been set."; } else { return "Property is not of type Mobile."; } } } } } return "Property not found."; }
public static bool CheckSingleProperty(XmlSpawner spawner, object o, string testString, Mobile trigmob, out string status_str) { status_str = null; if (o == null || testString == null || testString.Length == 0) return false; //get the prop name and test value // format will be prop=prop, or prop>prop, prop<prop, prop!prop // also support the 'not' operator ~ at the beginning of a test, like ~prop=prop testString = testString.Trim(); bool invertreturn = false; if (testString.Length > 0 && testString[0] == '~') { invertreturn = true; testString = testString.Substring(1, testString.Length - 1); } string[] arglist = ParseString(testString, 2, "=><!"); if (arglist.Length < 2) { status_str = "invalid property string : " + testString; return false; } bool hasequal = false; bool hasnotequals = false; bool hasgreaterthan = false; bool haslessthan = false; if (testString.IndexOf("=") > 0) { hasequal = true; } else if (testString.IndexOf("!") > 0) { hasnotequals = true; } else if (testString.IndexOf(">") > 0) { hasgreaterthan = true; } else if (testString.IndexOf("<") > 0) { haslessthan = true; } // does it have a valid operator? if (!hasequal && !hasgreaterthan && !haslessthan && !hasnotequals) return false; Type ptype1; Type ptype2; string value1 = ParseForKeywords(spawner, o, arglist[0].Trim(), trigmob, false, out ptype1); // see if it was successful if (ptype1 == null) { status_str = arglist[0] + " : " + value1; return invertreturn; //return false; } string value2 = ParseForKeywords(spawner, o, arglist[1].Trim(), trigmob, false, out ptype2); // see if it was successful if (ptype2 == null) { status_str = arglist[1] + " : " + value2; return invertreturn; //return false; } // look for hex numeric specifications int base1 = 10; int base2 = 10; if (IsNumeric(ptype1) && value1.StartsWith("0x")) { base1 = 16; } if (IsNumeric(ptype2) && value2.StartsWith("0x")) { base2 = 16; } // and do the type dependent comparisons if (ptype2 == typeof(TimeSpan) || ptype1 == typeof(TimeSpan)) { if (hasequal) { try { if (TimeSpan.Parse(value1) == TimeSpan.Parse(value2)) return !invertreturn; } catch { status_str = "invalid timespan comparison : {0}" + testString; } } else if (hasnotequals) { try { if (TimeSpan.Parse(value1) != TimeSpan.Parse(value2)) return !invertreturn; } catch { status_str = "invalid timespan comparison : {0}" + testString; } } else if (hasgreaterthan) { try { if (TimeSpan.Parse(value1) > TimeSpan.Parse(value2)) return !invertreturn; } catch { status_str = "invalid timespan comparison : {0}" + testString; } } else if (haslessthan) { try { if (TimeSpan.Parse(value1) < TimeSpan.Parse(value2)) return !invertreturn; } catch { status_str = "invalid timespan comparison : {0}" + testString; } } } else // and do the type dependent comparisons if (ptype2 == typeof(DateTime) || ptype1 == typeof(DateTime)) { if (hasequal) { try { if (DateTime.Parse(value1) == DateTime.Parse(value2)) return !invertreturn; } catch { status_str = "invalid DateTime comparison : {0}" + testString; } } else if (hasnotequals) { try { if (DateTime.Parse(value1) != DateTime.Parse(value2)) return !invertreturn; } catch { status_str = "invalid DateTime comparison : {0}" + testString; } } else if (hasgreaterthan) { try { if (DateTime.Parse(value1) > DateTime.Parse(value2)) return !invertreturn; } catch { status_str = "invalid DateTime comparison : {0}" + testString; } } else if (haslessthan) { try { if (DateTime.Parse(value1) < DateTime.Parse(value2)) return !invertreturn; } catch { status_str = "invalid DateTime comparison : {0}" + testString; } } } else // and do the type dependent comparisons if (IsNumeric(ptype2) && IsNumeric(ptype1)) { if (hasequal) { try { if (Convert.ToInt64(value1, base1) == Convert.ToInt64(value2, base2)) return !invertreturn; } catch { status_str = "invalid int comparison : {0}" + testString; } } else if (hasnotequals) { try { if (Convert.ToInt64(value1, base1) != Convert.ToInt64(value2, base2)) return !invertreturn; } catch { status_str = "invalid int comparison : {0}" + testString; } } else if (hasgreaterthan) { try { if (Convert.ToInt64(value1, base1) > Convert.ToInt64(value2, base2)) return !invertreturn; } catch { status_str = "invalid int comparison : {0}" + testString; } } else if (haslessthan) { try { if (Convert.ToInt64(value1, base1) < Convert.ToInt64(value2, base2)) return !invertreturn; } catch { status_str = "invalid int comparison : {0}" + testString; } } } else if ((ptype2 == typeof(double)) && IsNumeric(ptype1)) { if (hasequal) { try { if (Convert.ToInt64(value1, base1) == double.Parse(value2)) return !invertreturn; } catch { status_str = "invalid int comparison : {0}" + testString; } } else if (hasnotequals) { try { if (Convert.ToInt64(value1, base1) != double.Parse(value2)) return !invertreturn; } catch { status_str = "invalid int comparison : {0}" + testString; } } else if (hasgreaterthan) { try { if (Convert.ToInt64(value1, base1) > double.Parse(value2)) return !invertreturn; } catch { status_str = "invalid int comparison : {0}" + testString; } } else if (haslessthan) { try { if (Convert.ToInt64(value1, base1) < double.Parse(value2)) return !invertreturn; } catch { status_str = "invalid int comparison : {0}" + testString; } } } else if ((ptype1 == typeof(double)) && IsNumeric(ptype2)) { if (hasequal) { try { if (double.Parse(value1) == Convert.ToInt64(value2, base2)) return !invertreturn; } catch { status_str = "invalid int comparison : {0}" + testString; } } else if (hasnotequals) { try { if (double.Parse(value1) != Convert.ToInt64(value2, base2)) return !invertreturn; } catch { status_str = "invalid int comparison : {0}" + testString; } } else if (hasgreaterthan) { try { if (double.Parse(value1) > Convert.ToInt64(value2, base2)) return !invertreturn; } catch { status_str = "invalid int comparison : {0}" + testString; } } else if (haslessthan) { try { if (double.Parse(value1) < Convert.ToInt64(value2, base2)) return !invertreturn; } catch { status_str = "invalid int comparison : {0}" + testString; } } } else if ((ptype1 == typeof(double)) && (ptype2 == typeof(double))) { if (hasequal) { try { if (double.Parse(value1) == double.Parse(value2)) return !invertreturn; } catch { status_str = "invalid int comparison : {0}" + testString; } } else if (hasnotequals) { try { if (double.Parse(value1) != double.Parse(value2)) return !invertreturn; } catch { status_str = "invalid int comparison : {0}" + testString; } } else if (hasgreaterthan) { try { if (double.Parse(value1) > double.Parse(value2)) return !invertreturn; } catch { status_str = "invalid int comparison : {0}" + testString; } } else if (haslessthan) { try { if (double.Parse(value1) < double.Parse(value2)) return !invertreturn; } catch { status_str = "invalid int comparison : {0}" + testString; } } } else if (ptype2 == typeof(Boolean) && ptype1 == typeof(Boolean)) { if (hasequal) { try { if (Convert.ToBoolean(value1) == Convert.ToBoolean(value2)) return !invertreturn; } catch (Exception se) { status_str = "invalid bool comparison : {0}" + testString + se.Message; } } else if (hasnotequals) { try { if (Convert.ToBoolean(value1) != Convert.ToBoolean(value2)) return !invertreturn; } catch (Exception se) { status_str = "invalid bool comparison : {0}" + testString + se.Message; } } } else if (ptype2 == typeof(Double) || ptype2 == typeof(Double)) { if (hasequal) { try { if (Convert.ToDouble(value1) == Convert.ToDouble(value2)) return !invertreturn; } catch { status_str = "invalid double comparison : {0}" + testString; } } else if (hasnotequals) { try { if (Convert.ToDouble(value1) != Convert.ToDouble(value2)) return !invertreturn; } catch { status_str = "invalid double comparison : {0}" + testString; } } else if (hasgreaterthan) { try { if (Convert.ToDouble(value1) > Convert.ToDouble(value2)) return !invertreturn; } catch { status_str = "invalid double comparison : {0}" + testString; } } else if (haslessthan) { try { if (Convert.ToDouble(value1) < Convert.ToDouble(value2)) return !invertreturn; } catch { status_str = "invalid double comparison : {0}" + testString; } } } else { // by default just do a string comparison if (hasequal) { if (value1 == value2) return !invertreturn; } else if (hasnotequals) { if (value1 != value2) return !invertreturn; } } return invertreturn; }
public static bool SpawnTypeKeyword(object invoker, XmlSpawner.SpawnObject TheSpawn, string typeName, string substitutedtypeName, bool requiresurface, Mobile triggermob, Point3D location, Map map, XmlGumpCallback gumpcallback, out string status_str) { return SpawnTypeKeyword(invoker, TheSpawn, typeName, substitutedtypeName, requiresurface, null, triggermob, location, map, gumpcallback, out status_str); }
public static Mobile FindInRecentMobileSearchList(XmlSpawner spawner, string name, string typestr) { if (spawner == null || name == null || spawner.RecentMobileSearchList == null) return null; ArrayList deletelist = null; Mobile foundmobile = null; Type targettype = null; if (typestr != null) { targettype = SpawnerType.GetType(typestr); } foreach (Mobile m in spawner.RecentMobileSearchList) { if (m.Deleted) { // clean it up if (deletelist == null) deletelist = new ArrayList(); deletelist.Add(m); } else if (name.Length == 0 || String.Compare(m.Name, name, true) == 0) { if (typestr == null || (m.GetType() != null && targettype != null && (m.GetType().Equals(targettype) || m.GetType().IsSubclassOf(targettype)))) { foundmobile = m; break; } } } if (deletelist != null) { foreach (Mobile i in deletelist) spawner.RecentMobileSearchList.Remove(i); } return (foundmobile); }
public static bool SpawnTypeKeyword(object invoker, XmlSpawner.SpawnObject TheSpawn, string typeName, string substitutedtypeName, bool requiresurface, List<XmlSpawner.SpawnPositionInfo> spawnpositioning, Mobile triggermob, Point3D location, Map map, XmlGumpCallback gumpcallback, out string status_str) { status_str = null; if (typeName == null || TheSpawn == null || substitutedtypeName == null) return false; XmlSpawner spawner = invoker as XmlSpawner; // check for any special keywords that might appear in the type such as SET, GIVE, or TAKE if (IsTypeKeyword(typeName)) { typeKeyword kw = (typeKeyword)typeKeywordHash[typeName]; switch (kw) { case typeKeyword.SET: { // the syntax is SET/prop/value/prop2/value... // check for the SET,itemname[,itemtype]/prop/value form is used string[] arglist = ParseSlashArgs(substitutedtypeName, 3); string[] keywordargs = ParseString(arglist[0], 3, ","); if (keywordargs.Length > 1) { string typestr = null; if (keywordargs.Length > 2) { typestr = keywordargs[2]; } // is the itemname a serialno? object setitem = null; if (keywordargs[1].StartsWith("0x")) { int serial = -1; try { serial = Convert.ToInt32(keywordargs[1], 16); } catch { } if (serial >= 0) setitem = World.FindEntity(serial); } else { // just look it up by name setitem = FindItemByName(spawner, keywordargs[1], typestr); } if (setitem == null) { status_str = "cant find unique item :" + keywordargs[1]; return false; } else { ApplyObjectStringProperties(spawner, substitutedtypeName, setitem, triggermob, invoker, out status_str); } } else if (spawner != null) { ApplyObjectStringProperties(spawner, substitutedtypeName, spawner.SetItem, triggermob, invoker, out status_str); } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.SETONMOB: { // the syntax is SETONMOB,mobname[,mobtype]/prop/value/prop2/value... string[] arglist = ParseSlashArgs(substitutedtypeName, 3); Mobile mob = null; if (arglist.Length > 0) { string[] keywordargs = ParseString(arglist[0], 3, ","); if (keywordargs.Length > 1) { string typestr = null; if (keywordargs.Length > 2) { typestr = keywordargs[2]; } mob = FindMobileByName(spawner, keywordargs[1], typestr); if (mob == null) { status_str = String.Format("named mob '{0}' not found", keywordargs[1]); } } else { status_str = "missing mob name in SETONMOB"; } } if (mob != null) { ApplyObjectStringProperties(spawner, substitutedtypeName, mob, triggermob, invoker, out status_str); } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.SETONTHIS: { // the syntax is SETONTHIS/prop/value/prop2/value... //string [] arglist = ParseString(substitutedtypeName,3,"/"); if (invoker != null) { ApplyObjectStringProperties(spawner, substitutedtypeName, invoker, triggermob, invoker, out status_str); } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.SETONTRIGMOB: { // the syntax is SETONTRIGMOB/prop/value/prop2/value... ApplyObjectStringProperties(spawner, substitutedtypeName, triggermob, triggermob, invoker, out status_str); TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.SETACCOUNTTAG: { // the syntax is SETACCOUNTTAG,tagname/value string[] arglist = ParseSlashArgs(substitutedtypeName, 2); if (arglist.Length > 1) { string[] objstr = ParseString(arglist[0], 2, ","); if (objstr.Length < 2) { status_str = "missing tagname in SETACCOUNTTAG"; return false; } string tagname = objstr[1]; string tagval = arglist[1]; // set the tag value // get the value of the account tag from the triggering mob if (triggermob != null && !triggermob.Deleted) { Account acct = triggermob.Account as Account; if (acct != null) { acct.SetTag(tagname, tagval); } } } else { status_str = "no value assigned to SETACCOUNTTAG"; return false; } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.SETVAR: { // the syntax is SETVAR,varname/value string[] arglist = ParseSlashArgs(substitutedtypeName, 2); if (arglist.Length > 1) { string[] objstr = ParseString(arglist[0], 2, ","); if (objstr.Length < 2) { status_str = "missing varname in SETVAR"; return false; } string varname = objstr[1]; string varval = arglist[1]; // find the xmllocalvariable attachment with that name XmlLocalVariable a = (XmlLocalVariable)XmlAttach.FindAttachment(invoker, typeof(XmlLocalVariable), varname); if (a == null) { // doesnt already exist so add it XmlAttach.AttachTo(invoker, new XmlLocalVariable(varname, varval)); } else { a.Data = varval; } } else { status_str = "no value assigned to SETVAR"; return false; } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.SETONNEARBY: { // the syntax is SETONNEARBY,range,name[,type][,searchcontainers][,proptest]/prop/value/prop/value... string[] arglist = ParseSlashArgs(substitutedtypeName, 3); string typestr = null; string targetname = null; string proptest = null; int range = -1; bool searchcontainers = false; if (arglist.Length > 0) { string[] objstr = ParseString(arglist[0], 6, ","); if (objstr.Length < 3) { status_str = "missing range or name in SETONNEARBY"; return false; } try { range = int.Parse(objstr[1]); } catch { } if (range < 0) { status_str = "invalid range in SETONNEARBY"; return false; } targetname = objstr[2]; if (objstr.Length > 3) { typestr = objstr[3]; } if (objstr.Length > 4) { try { searchcontainers = bool.Parse(objstr[4]); } catch { } } if (objstr.Length > 5) { proptest = objstr[5]; } } else { status_str = "missing args to SETONNEARBY"; return false; } Type targettype = null; if (typestr != null) { targettype = SpawnerType.GetType(typestr); } ArrayList nearbylist = GetNearbyObjects(invoker, targetname, targettype, typestr, range, searchcontainers, proptest); // apply the properties to everything on the list foreach (object nearbyobj in nearbylist) { ApplyObjectStringProperties(spawner, substitutedtypeName, nearbyobj, triggermob, invoker, out status_str); } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.SETONPETS: { // the syntax is SETONPETS,range/prop/value/prop/value... string[] arglist = ParseSlashArgs(substitutedtypeName, 3); string typestr = "BaseCreature"; string targetname = null; int range = -1; bool searchcontainers = false; if (arglist.Length > 0) { string[] objstr = ParseString(arglist[0], 2, ","); if (objstr.Length < 2) { status_str = "missing range or name in SETONPETS"; return false; } try { range = int.Parse(objstr[1]); } catch { } if (range < 0) { status_str = "invalid range in SETONPETS"; return false; } } else { status_str = "missing args to SETONPETS"; return false; } Type targettype = null; if (typestr != null) { targettype = SpawnerType.GetType(typestr); } // get all of the nearby pets ArrayList nearbylist = GetNearbyObjects(triggermob, targetname, targettype, typestr, range, searchcontainers, null); // apply the properties to everything on the list foreach (object nearbyobj in nearbylist) { // is this a pet of the triggering mob BaseCreature pet = nearbyobj as BaseCreature; if (pet != null && pet.Controlled && pet.ControlMaster == triggermob) { ApplyObjectStringProperties(spawner, substitutedtypeName, nearbyobj, triggermob, invoker, out status_str); } } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.SETONCARRIED: { // the syntax is SETONCARRIED,itemname[,itemtype][,equippedonly]/prop/value/prop2/value... // or SETONCARRIED,itemname[,itemtype]/prop/value // first find the carried item string[] arglist = ParseSlashArgs(substitutedtypeName, 3); string typestr = null; string itemname = null; bool equippedonly = false; if (arglist.Length > 0) { string[] objstr = ParseString(arglist[0], 4, ","); if (objstr.Length < 2) { status_str = "missing itemname in SETONCARRIED"; return false; } itemname = objstr[1]; if (objstr.Length > 2) { typestr = objstr[2]; } if (objstr.Length > 3) { if (objstr[3].ToLower() == "equippedonly") { equippedonly = true; } else { try { equippedonly = bool.Parse(objstr[3]); } catch { } } } } else { status_str = "missing args to SETONCARRIED"; return false; } Item testitem = SearchMobileForItem(triggermob, ParseObjectType(itemname), typestr, false, equippedonly); ApplyObjectStringProperties(spawner, substitutedtypeName, testitem, triggermob, invoker, out status_str); TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.SETONSPAWN: { // the syntax is SETONSPAWN[,spawnername],subgroup/prop/value/prop2/value... // or SETONSPAWN[,spawnername],subgroup/prop/value // first find the spawn int subgroup = -1; string[] arglist = ParseSlashArgs(substitutedtypeName, 3); XmlSpawner targetspawner = spawner; if (arglist.Length > 0) { string[] keywordargs = ParseString(arglist[0], 3, ","); if (keywordargs.Length < 2) { status_str = "missing subgroup in SETONSPAWN"; return false; } else { string subgroupstr = keywordargs[1]; string spawnerstr = null; if (keywordargs.Length > 2) { spawnerstr = keywordargs[1]; subgroupstr = keywordargs[2]; } if (spawnerstr != null) { targetspawner = FindSpawnerByName(spawner, spawnerstr); } try { subgroup = int.Parse(subgroupstr); } catch { } } } if (subgroup == -1) { status_str = "invalid subgroup in SETONSPAWN"; return false; } ArrayList spawnedlist = XmlSpawner.GetSpawnedList(targetspawner, subgroup); if (spawnedlist == null) return true; foreach (object targetobj in spawnedlist) { if (targetobj == null) return true; // dont apply it to keyword tags if (targetobj is KeywordTag) continue; // set the properties on the target object ApplyObjectStringProperties(spawner, substitutedtypeName, targetobj, triggermob, spawner, out status_str); } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.SETONSPAWNENTRY: { // the syntax is SETONSPAWNENTRY[,spawnername],entrystring/prop/value/prop2/value... // find the spawn entry string entrystring = null; string[] arglist = ParseSlashArgs(substitutedtypeName, 3); XmlSpawner targetspawner = spawner; if (arglist.Length > 0) { string[] keywordargs = ParseString(arglist[0], 3, ","); if (keywordargs.Length < 2) { status_str = "missing entrystring in SETONSPAWNENTRY"; return false; } else { entrystring = keywordargs[1]; string spawnerstr = null; if (keywordargs.Length > 2) { spawnerstr = keywordargs[1]; entrystring = keywordargs[2]; } if (spawnerstr != null) { targetspawner = FindSpawnerByName(spawner, spawnerstr); } } } if (entrystring == null || entrystring.Length == 0) { status_str = "invalid entrystring in SETONSPAWNENTRY"; return false; } int entryindex = -1; // is the entrystring a number? if (entrystring[0] >= '0' && entrystring[0] <= '9') { try { entryindex = int.Parse(entrystring); } catch { } } if (targetspawner == null || targetspawner.SpawnObjects == null) return true; for (int i = 0; i < targetspawner.SpawnObjects.Length; i++) { XmlSpawner.SpawnObject targetobj = targetspawner.SpawnObjects[i]; // is this references by entrystring or entryindex? if ((entryindex == i) || (entryindex == -1 && targetobj != null && targetobj.TypeName != null && targetobj.TypeName.IndexOf(entrystring) >= 0)) { // set the properties on the spawn entry object ApplyObjectStringProperties(spawner, substitutedtypeName, targetobj, triggermob, spawner, out status_str); } } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.SETONPARENT: { // the syntax is SETONPARENT/prop/value/prop2/value... string[] arglist = ParseSlashArgs(substitutedtypeName, 3); if (invoker != null && (invoker is Item)) { ApplyObjectStringProperties(spawner, substitutedtypeName, ((Item)invoker).Parent, triggermob, invoker, out status_str); } else if (invoker != null && (invoker is XmlAttachment)) { ApplyObjectStringProperties(spawner, substitutedtypeName, ((XmlAttachment)invoker).Attached, triggermob, invoker, out status_str); } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.GIVE: { string[] arglist = ParseSlashArgs(substitutedtypeName, 3); string remainder; if (arglist.Length > 1) { // check for any special keywords such as the additem option or the subproperty specification // note this will be an arg to some property string[] keywordargs = ParseString(arglist[0], 2, ","); AddItemToTarget(spawner, triggermob, keywordargs, arglist, triggermob, invoker, false, out remainder, out status_str); } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.TAKE: { // syntax TAKE[,prob[,quantity[,true,[type]]]]/itemname string[] arglist = ParseSlashArgs(substitutedtypeName, 3); string targetName; string typestr = null; if (arglist.Length > 1) { targetName = arglist[1]; } else { status_str = "invalid TAKE specification"; return false; } string[] keywordargs = ParseString(arglist[0], 5, ","); double drop_probability = 1; int quantity = 0; bool banksearch = false; Item savedItem = null; if (keywordargs.Length > 1) { bool converterror = false; try { drop_probability = Convert.ToDouble(keywordargs[1], CultureInfo.InvariantCulture); } catch { status_str = "Invalid TAKE probability : " + arglist[1]; converterror = true; } if (converterror) return false; } if (keywordargs.Length > 2) { bool converterror = false; try { quantity = int.Parse(keywordargs[2]); } catch { status_str = "Invalid TAKE quantity : " + arglist[1]; converterror = true; } if (converterror) return false; } if (keywordargs.Length > 3) { bool converterror = false; try { banksearch = bool.Parse(keywordargs[3]); } catch { status_str = "Invalid TAKE bankflag : " + arglist[1]; converterror = true; } if (converterror) return false; } if (keywordargs.Length > 4) { typestr = keywordargs[4]; } if (drop_probability == 1 || Utility.RandomDouble() < drop_probability) { // search the trigger mob for the named item Item itemTarget = SearchMobileForItem(triggermob, targetName, typestr, banksearch); // found the item so get rid of it if (itemTarget != null) { // if a quantity was specified and the item is stackable, then try to take the quantity if (quantity > 0 && itemTarget.Stackable) { // create a copy of the stacked item to be saved //savedItem = itemTarget.Dupe(0); savedItem = Mobile.LiftItemDupe(itemTarget, itemTarget.Amount); if (savedItem != null) { savedItem.Internalize(); } int totaltaken = 0; int remaining = itemTarget.Amount - quantity; if (remaining <= 0) { int taken = itemTarget.Amount; totaltaken += taken; itemTarget.Delete(); while (remaining < 0) { quantity -= taken; // if didnt get the full amount then keep looking for other stacks itemTarget = SearchMobileForItem(triggermob, targetName, typestr, banksearch); if (itemTarget == null) break; remaining = itemTarget.Amount - quantity; if (remaining <= 0) { taken = itemTarget.Amount; totaltaken += taken; itemTarget.Delete(); } else { totaltaken += quantity; itemTarget.Amount = remaining; } } } else { totaltaken = quantity; itemTarget.Amount = remaining; } if (savedItem != null) { savedItem.Amount = totaltaken; } } else { // dont save quest holders if (itemTarget is XmlQuestBook || itemTarget is IXmlQuest) { itemTarget.Delete(); } else savedItem = itemTarget; } // if the saved item was being held then release it otherwise the player can take it back if (triggermob != null && triggermob.Holding == savedItem) { triggermob.Holding = null; } XmlSaveItem si = (XmlSaveItem)XmlAttach.FindAttachment(invoker, typeof(XmlSaveItem), "Taken"); if (si == null) { XmlAttach.AttachTo(invoker, new XmlSaveItem("Taken", savedItem, triggermob)); } else { si.SavedItem = savedItem; si.WasOwnedBy = triggermob; } } } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.TAKEBYTYPE: { // syntax TAKEBYTYPE[,prob[,quantity[,true]]]/itemtype string[] arglist = ParseSlashArgs(substitutedtypeName, 3); string targetName; if (arglist.Length > 1) { targetName = arglist[1]; } else { status_str = "invalid TAKEBYTYPE specification"; return false; } string[] keywordargs = ParseString(arglist[0], 4, ","); double drop_probability = 1; int quantity = 0; bool banksearch = false; Item savedItem = null; if (keywordargs.Length > 1) { bool converterror = false; try { drop_probability = Convert.ToDouble(keywordargs[1], CultureInfo.InvariantCulture); } catch { status_str = "Invalid TAKEBYTYPE probability : " + arglist[1]; converterror = true; } if (converterror) return false; } if (keywordargs.Length > 2) { bool converterror = false; try { quantity = int.Parse(keywordargs[2]); } catch { status_str = "Invalid TAKEBYTYPE quantity : " + arglist[1]; converterror = true; } if (converterror) return false; } if (keywordargs.Length > 3) { bool converterror = false; try { banksearch = bool.Parse(keywordargs[3]); } catch { status_str = "Invalid TAKEBYTYPE bankflag : " + arglist[1]; converterror = true; } if (converterror) return false; } if (drop_probability == 1 || Utility.RandomDouble() < drop_probability) { // search the trigger mob for the named item Item itemTarget = SearchMobileForItemType(triggermob, targetName, banksearch); // found the item so get rid of it if (itemTarget != null) { // if a quantity was specified and the item is stackable, then try to take the quantity if (quantity > 0 && itemTarget.Stackable) { // create a copy of the stacked item to be saved //savedItem = itemTarget.Dupe(0); savedItem = Mobile.LiftItemDupe(itemTarget, itemTarget.Amount); if (savedItem != null) { savedItem.Internalize(); } int totaltaken = 0; int remaining = itemTarget.Amount - quantity; if (remaining <= 0) { int taken = itemTarget.Amount; totaltaken += taken; itemTarget.Delete(); while (remaining < 0) { quantity -= taken; // if didnt get the full amount then keep looking for other stacks itemTarget = SearchMobileForItemType(triggermob, targetName, banksearch); if (itemTarget == null) break; remaining = itemTarget.Amount - quantity; if (remaining <= 0) { taken = itemTarget.Amount; totaltaken += taken; itemTarget.Delete(); } else { totaltaken += quantity; itemTarget.Amount = remaining; } } } else { totaltaken = quantity; itemTarget.Amount = remaining; } if (savedItem != null) { savedItem.Amount = totaltaken; } } else { // dont save quest holders if (itemTarget is XmlQuestBook || itemTarget is XmlQuestHolder || itemTarget is XmlQuestToken) { itemTarget.Delete(); } else savedItem = itemTarget; } } // is there an existing xmlsaveitem attachment XmlSaveItem si = (XmlSaveItem)XmlAttach.FindAttachment(invoker, typeof(XmlSaveItem), "Taken"); if (si == null) { XmlAttach.AttachTo(invoker, new XmlSaveItem("Taken", savedItem, triggermob)); } else { si.SavedItem = savedItem; si.WasOwnedBy = triggermob; } } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.GUMP: { // the syntax is GUMP,title,type/string // can alternatively accept a gump constructor name // GUMP,title,type,constructorname/string string[] arglist = ParseSlashArgs(substitutedtypeName, 3); string gumpText; if (arglist.Length > 1) { gumpText = arglist[1]; } else { status_str = "invalid GUMP specification"; return false; } string[] gumpkeywordargs = ParseString(arglist[0], 4, ","); string gumpTitle = ""; int gumpNumber = 0; // 0=simple text gump, 1=yes/no gump, 2=reply gump, 3=quest gump if (gumpkeywordargs.Length > 2) { gumpTitle = gumpkeywordargs[1]; bool converterror = false; try { gumpNumber = int.Parse(gumpkeywordargs[2]); } catch { status_str = "Invalid GUMP args"; converterror = true; } if (converterror) return false; } else { status_str = "invalid GUMP specification"; return false; } string gumptypestr = "XmlSimpleGump"; // default gump constructor if (gumpkeywordargs.Length > 3) { // get the gump constructor type gumptypestr = gumpkeywordargs[3].Trim(); } Type type = null; if (gumptypestr != null) { try { type = SpawnerType.GetType(gumptypestr); } catch { } } if (type == null) { status_str = "invalid GUMP constructor : " + gumptypestr; return false; } // prepare the keyword tag for the gump KeywordTag newtag = new KeywordTag(substitutedtypeName, spawner, 1); if (triggermob != null && !triggermob.Deleted && (triggermob is PlayerMobile)) { object newgump = null; object[] gumpargs = new object[7]; gumpargs[0] = invoker; gumpargs[1] = gumpText; gumpargs[2] = gumpTitle; gumpargs[3] = gumpNumber; gumpargs[4] = newtag; gumpargs[5] = triggermob; gumpargs[6] = gumpcallback; //spawner.TriggerMob.SendGump( new XmlSimpleGump(this, gumpText,gumpTitle, gumpType )); try { newgump = Activator.CreateInstance(type, gumpargs); } catch { status_str = "Error in creating gump type : " + gumptypestr; newtag.Delete(); return false; } if (newgump != null) { if (newgump is Gump) { triggermob.SendGump((Gump)newgump); } else if (newgump is Item) { ((Item)newgump).Delete(); status_str = gumptypestr + " is not a Gump type"; newtag.Delete(); return false; } else if (newgump is Mobile) { ((Mobile)newgump).Delete(); status_str = gumptypestr + " is not a Gump type"; newtag.Delete(); return false; } else { status_str = gumptypestr + " is not a Gump type"; newtag.Delete(); return false; } } } TheSpawn.SpawnedObjects.Add(newtag); break; } case typeKeyword.BROWSER: { // the syntax is BROWSER/url string[] arglist = ParseSlashArgs(substitutedtypeName, 2); string url; if (arglist.Length > 1) { if (arglist[1] != null && arglist[1].Length > 0 && arglist[1][0] == '@') { url = arglist[1].Substring(1); } else url = arglist[1]; } else { status_str = "invalid BROWSER specification"; return false; } if (triggermob != null && !triggermob.Deleted && (triggermob is PlayerMobile)) { triggermob.LaunchBrowser(url); } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.SENDMSG: { // the syntax is SENDMSG[,hue]/string string[] arglist = ParseSlashArgs(substitutedtypeName, 3); // check for literal string msgText; int hue = 0x3B2; int font = 3; if (arglist.Length > 0) { string[] keywordargs = ParseString(arglist[0], 2, ","); if (keywordargs.Length > 1) { try { hue = int.Parse(keywordargs[1]); } catch { status_str = "invalid hue arg to SENDMSG"; } } } if (arglist.Length > 1) { if (arglist[1] != null && arglist[1].Length > 0 && arglist[1][0] == '@') { arglist = ParseSlashArgs(substitutedtypeName, 2); msgText = arglist[1].Substring(1); } else msgText = arglist[1]; } else { status_str = "invalid SENDMSG specification"; return false; } if (triggermob != null && !triggermob.Deleted && (triggermob is PlayerMobile)) { //triggermob.SendMessage(msgText); triggermob.Send(new UnicodeMessage(Serial.MinusOne, -1, MessageType.Regular, hue, font, "ENU", "System", msgText)); } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.SENDASCIIMSG: { // the syntax is SENDASCIIMSG[,hue][,font#]/string string[] arglist = ParseSlashArgs(substitutedtypeName, 3); // check for literal string msgText; int hue = 0x3B2; int font = 3; if (arglist.Length > 0) { string[] keywordargs = ParseString(arglist[0], 3, ","); if (keywordargs.Length > 1) { try { hue = int.Parse(keywordargs[1]); } catch { status_str = "invalid hue arg to SENDASCIIMSG"; } } if (keywordargs.Length > 2) { try { font = int.Parse(keywordargs[2]); } catch { status_str = "invalid font arg to SENDASCIIMSG"; } } } if (arglist.Length > 1) { if (arglist[1] != null && arglist[1].Length > 0 && arglist[1][0] == '@') { arglist = ParseSlashArgs(substitutedtypeName, 2); msgText = arglist[1].Substring(1); } else msgText = arglist[1]; } else { status_str = "invalid SENDASCIIMSG specification"; return false; } if (triggermob != null && !triggermob.Deleted && (triggermob is PlayerMobile)) { triggermob.Send(new AsciiMessage(Serial.MinusOne, -1, MessageType.Regular, hue, font, "System", msgText)); } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.WAITUNTIL: { // the syntax is WAITUNTIL[,delay][,timeout][/condition][/thendogroup] string[] arglist = ParseSlashArgs(substitutedtypeName, 4); double delay = 0; double timeout = 0; string condition = null; int gotogroup = -1; if (arglist.Length > 0) { string[] keywordargs = ParseString(arglist[0], 3, ","); if (keywordargs.Length > 1) { try { delay = double.Parse(keywordargs[1]); } catch { status_str = "invalid delay arg to WAITUNTIL"; } } if (keywordargs.Length > 2) { try { timeout = double.Parse(keywordargs[2]); } catch { status_str = "invalid timeout arg to WAITUNTIL"; } } } if (arglist.Length > 1) { condition = arglist[1]; } if (arglist.Length > 2) { try { gotogroup = int.Parse(arglist[2]); } catch { status_str = "invalid goto arg to WAITUNTIL"; } } if (status_str != null) { return false; } // suppress sequential advancement //spawner.HoldSequence = true; TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner, TimeSpan.FromMinutes(delay), TimeSpan.FromMinutes(timeout), condition, gotogroup)); break; } case typeKeyword.WHILE: { // the syntax is WHILE/condition/dogroup string[] arglist = ParseSlashArgs(substitutedtypeName, 4); string condition = null; int gotogroup = -1; if (arglist.Length < 3) { status_str = "insufficient args to WHILE"; } else { condition = arglist[1]; try { gotogroup = int.Parse(arglist[2]); } catch { status_str = "invalid dogroup arg to WHILE"; } } if (status_str != null) { return false; } // test the condition if (TestItemProperty(spawner, spawner, condition, triggermob, out status_str)) { // try to spawn the dogroup if (spawner != null && !spawner.Deleted) { if (gotogroup >= 0) { // spawn the subgroup spawner.SpawnSubGroup(gotogroup); // advance the sequence to that group //spawner.SequentialSpawn = gotogroup; } // and suppress sequential advancement spawner.HoldSequence = true; } } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.IF: { // the syntax is IF/condition/thengroup [/elsegroup] string[] arglist = ParseSlashArgs(substitutedtypeName, 5); string condition = null; int thengroup = -1; int elsegroup = -1; if (arglist.Length < 3) { status_str = "insufficient args to IF"; } else { condition = arglist[1]; try { thengroup = int.Parse(arglist[2]); } catch { status_str = "invalid thengroup arg to IF"; } } if (arglist.Length > 3) { try { elsegroup = int.Parse(arglist[3]); } catch { status_str = "invalid elsegroup arg to IF"; } } if (status_str != null) { return false; } // test the condition if (TestItemProperty(spawner, spawner, condition, triggermob, out status_str)) { // try to spawn the thengroup if (thengroup >= 0 && spawner != null && !spawner.Deleted) { // spawn the subgroup spawner.SpawnSubGroup(thengroup); // advance the sequence to that group //spawner.SequentialSpawn = thengroup; } // and suppress sequential advancement //spawner.HoldSequence = true; } else { // try to spawn the elsegroup if (elsegroup >= 0 && spawner != null && !spawner.Deleted) { // spawn the subgroup spawner.SpawnSubGroup(elsegroup); // advance the sequence to that group //spawner.SequentialSpawn = elsegroup; } // and suppress sequential advancement //spawner.HoldSequence = true; } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.DESPAWN: { // the syntax is DESPAWN[,spawnername],subgroup // first find the spawner and group int subgroup = -1; string[] arglist = ParseSlashArgs(substitutedtypeName, 3); XmlSpawner targetspawner = spawner; if (arglist.Length > 0) { string[] keywordargs = ParseString(arglist[0], 3, ","); if (keywordargs.Length < 2) { status_str = "missing subgroup in DESPAWN"; return false; } else { string subgroupstr = keywordargs[1]; string spawnerstr = null; if (keywordargs.Length > 2) { spawnerstr = keywordargs[1]; subgroupstr = keywordargs[2]; } if (spawnerstr != null) { targetspawner = FindSpawnerByName(spawner, spawnerstr); } try { subgroup = int.Parse(subgroupstr); } catch { } } } if (subgroup == -1) { status_str = "invalid subgroup in DESPAWN"; return false; } if (targetspawner != null) { targetspawner.ClearSubgroup(subgroup); } else { status_str = "invalid spawner in DESPAWN"; return false; } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.SPAWN: { // the syntax is SPAWN[,spawnername],subgroup // first find the spawner and group int subgroup = -1; string[] arglist = ParseSlashArgs(substitutedtypeName, 3); XmlSpawner targetspawner = spawner; if (arglist.Length > 0) { string[] keywordargs = ParseString(arglist[0], 3, ","); if (keywordargs.Length < 2) { status_str = "missing subgroup in SPAWN"; return false; } else { string subgroupstr = keywordargs[1]; string spawnerstr = null; if (keywordargs.Length > 2) { spawnerstr = keywordargs[1]; subgroupstr = keywordargs[2]; } if (spawnerstr != null) { targetspawner = FindSpawnerByName(spawner, spawnerstr); } try { subgroup = int.Parse(subgroupstr); } catch { } } } if (subgroup == -1) { status_str = "invalid subgroup in SPAWN"; return false; } if (targetspawner != null) { if (spawner != targetspawner) { // allow spawning of other spawners to be forced and ignore the normal loop protection targetspawner.SpawnSubGroup(subgroup, false, true); } else { targetspawner.SpawnSubGroup(subgroup); } } else { status_str = "invalid spawner in SPAWN"; return false; } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.GOTO: { // the syntax is GOTO/subgroup string[] arglist = ParseSlashArgs(substitutedtypeName, 3); int group = -1; if (arglist.Length < 2) { status_str = "insufficient args to GOTO"; } else { try { group = int.Parse(arglist[1]); } catch { status_str = "invalid subgroup arg to GOTO"; } } if (status_str != null) { return false; } // move the sequence to the specified subgroup if (group >= 0 && spawner != null && !spawner.Deleted) { // note, this will activate sequential spawning if it wasnt already set spawner.SequentialSpawn = group; // and suppress sequential advancement so that the specified group is the next to spawn spawner.HoldSequence = true; } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner, 2)); break; } case typeKeyword.COMMAND: { // the syntax is COMMAND/commandstring string[] arglist = ParseSlashArgs(substitutedtypeName, 3); if (arglist.Length > 0) { // mod to use a dummy char to issue commands if (CommandMobileName != null) { Mobile dummy = FindMobileByName(spawner, CommandMobileName, "Mobile"); if (dummy != null) { CommandSystem.Handle(dummy, String.Format("{0}{1}", CommandSystem.Prefix, arglist[1])); } } else if (triggermob != null && !triggermob.Deleted) { CommandSystem.Handle(triggermob, String.Format("{0}{1}", CommandSystem.Prefix, arglist[1])); } } else { status_str = "insufficient args to COMMAND"; } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.MUSIC: { // the syntax is MUSIC,name,range string[] arglist = ParseSlashArgs(substitutedtypeName, 3); if (arglist.Length > 0) { SendMusicToPlayers(arglist[0], triggermob, invoker, out status_str); if (status_str != null) { return false; } } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.SOUND: { string[] arglist = ParseSlashArgs(substitutedtypeName, 3); if (arglist.Length > 0) { // Syntax is SOUND,soundnumber string[] keywordargs = ParseString(arglist[0], 3, ","); int sound = -1; // try to get the soundnumber argument if (keywordargs.Length < 2) { status_str = "Missing sound number"; } else { try { sound = int.Parse(keywordargs[1]); } catch { status_str = "Improper sound number format"; } } if (sound >= 0 && spawner != null && !spawner.Deleted) { Effects.PlaySound(spawner.Location, spawner.Map, sound); } if (status_str != null) { return false; } } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } // // MEFFECT keyword // case typeKeyword.MEFFECT: { string[] arglist = ParseSlashArgs(substitutedtypeName, 3); if (arglist.Length > 0) { string[] keywordargs = ParseString(arglist[0], 9, ","); if (keywordargs.Length < 9) { status_str = "Missing args"; } else { int effect = -1; int duration = 0; int speed = 1; Point3D eloc1 = new Point3D(0, 0, 0); Point3D eloc2 = new Point3D(0, 0, 0); Map emap = Map.Internal; // syntax is MEFFECT,itemid,speed,x,y,z,x2,y2,z2 // try to get the effect argument try { effect = int.Parse(keywordargs[1]); } catch { status_str = "Improper effect number format"; } try { speed = int.Parse(keywordargs[2]); } catch { status_str = "Improper effect speed format"; } int x = 0; int y = 0; int z = 0; try { x = int.Parse(keywordargs[3]); y = int.Parse(keywordargs[4]); z = int.Parse(keywordargs[5]); } catch { status_str = "Improper effect location format"; } eloc1 = new Point3D(x, y, z); try { x = int.Parse(keywordargs[6]); y = int.Parse(keywordargs[7]); z = int.Parse(keywordargs[8]); } catch { status_str = "Improper effect location format"; } eloc2 = new Point3D(x, y, z); if (effect >= 0 && emap != Map.Internal) { Effects.SendPacket(eloc1, emap, new HuedEffect(EffectType.Moving, -1, -1, effect, eloc1, eloc2, speed, duration, false, false, 0, 0)); } } if (status_str != null) { return false; } } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.EFFECT: { string[] arglist = ParseSlashArgs(substitutedtypeName, 3); if (spawner == null || spawner.Deleted) return false; if (arglist.Length > 0) { string[] keywordargs = ParseString(arglist[0], 6, ","); int effect = -1; int duration = 1; // syntax is EFFECT,itemid,duration[,x,y,z] or EFFECT,itemid,duration[,trigmob] // try to get the effect argument // some interesting effects are explosion(14013,15), sparkle(14155,15), explosion2(14000,13) if (keywordargs.Length < 3) { status_str = "Missing effect number and duration"; } else { try { effect = int.Parse(keywordargs[1]); } catch { status_str = "Improper effect number format"; } try { duration = int.Parse(keywordargs[2]); } catch { status_str = "Improper effect duration format"; } } // by default just use the spawner location Point3D eloc = spawner.Location; Map emap = spawner.Map; if (keywordargs.Length > 3) { // is this applied to the trig mob or to a location? if (keywordargs.Length > 5) { int x = spawner.Location.X; int y = spawner.Location.Y; int z = spawner.Location.Z; try { x = int.Parse(keywordargs[3]); y = int.Parse(keywordargs[4]); z = int.Parse(keywordargs[5]); } catch { status_str = "Improper effect location format"; } eloc = new Point3D(x, y, z); } } if (status_str != null) { return false; } if (effect >= 0) { Effects.SendLocationEffect(eloc, emap, effect, duration); } } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.POISON: { // the syntax is POISON,name,range string[] arglist = ParseSlashArgs(substitutedtypeName, 3); if (arglist.Length > 0) { ApplyPoisonToPlayers(arglist[0], triggermob, invoker, out status_str); if (status_str != null) { return false; } } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.DAMAGE: { // the syntax is DAMAGE,damage,phys,fire,cold,pois,energy[,range] string[] arglist = ParseSlashArgs(substitutedtypeName, 3); if (arglist.Length > 0) { ApplyDamageToPlayers(arglist[0], triggermob, invoker, out status_str); if (status_str != null) { return false; } } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.RESURRECT: { // the syntax is RESURRECT[,range][,PETS] string[] arglist = ParseSlashArgs(substitutedtypeName, 3); if (arglist.Length > 0) { ResurrectPlayers(arglist[0], triggermob, invoker, out status_str); if (status_str != null) { return false; } } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } case typeKeyword.CAST: { string[] arglist = ParseSlashArgs(substitutedtypeName, 3); // Syntax is CAST,spellnumber[,arg] or CAST,spellname[,arg] string[] keywordargs = ParseString(arglist[0], 3, ","); int spellnumber = 0; bool hasnumber = true; // try it as spellnumber if (keywordargs.Length > 1) { try { spellnumber = int.Parse(keywordargs[1]); } catch { hasnumber = false; } } else { status_str = "invalid CAST specification"; // note that returning true means that Spawn will assume that it worked and will not try to recast return true; } // call this with the 3 argument version that includes the bodytype arg int keywordarg2 = 0; if (keywordargs.Length > 2) { try { keywordarg2 = int.Parse(keywordargs[2]); } catch { } } Spell spell = null; // the trigger mob will cast the spells Mobile caster = triggermob; if (caster == null) { // note that returning true means that Spawn will assume that it worked and will not try to recast return true; } // make the placeholder wand to avoid reagent and mana use // this has been removed because Divinity doesn't have ClumsyWand //BaseWand cwand = new ClumsyWand(); //cwand.Parent = caster; BaseWand cwand = null; spell = null; /*if (hasnumber) { spell = SpellRegistry.NewSpell(spellnumber, caster, cwand); } else { spell = SpellRegistry.NewSpell(keywordargs[1], caster, cwand); }*/ if (spell != null) { bool casterror = false; try { // deal with the 3 types of spells, mob targeted, location targeted, and self targeted // dont go through all of the warm up stuff, get right to the casting spell.State = SpellState.Sequencing; Type spelltype = spell.GetType(); // deal with any special cases here if (spelltype == typeof(Server.Spells.Seventh.PolymorphSpell)) { if (keywordarg2 == 0) { // this is invalid so dont cast throw (new ArgumentNullException()); } object[] polyargs = new object[3]; polyargs[0] = caster; polyargs[1] = cwand; polyargs[2] = keywordarg2; spell = (Spell)Activator.CreateInstance(spelltype, polyargs); if (spell == null) { throw (new ArgumentNullException()); } spell.State = SpellState.Sequencing; } MethodInfo spelltargetmethod = null; // get the targeting method from the spell // note, the precedence is important as the target call should override oncast if it is present if (spelltype != null && (spelltargetmethod = spelltype.GetMethod("Target")) != null) { } // if it doesnt have it then check for self targeted types else if (spelltype != null && (spelltargetmethod = spelltype.GetMethod("OnCast")) != null) { } else { throw (new ArgumentNullException()); } // Get the parameters for the target method. ParameterInfo[] spelltargetparms = spelltargetmethod.GetParameters(); // target will have one parm // selftarg will have none object[] targetargs = null; // check the parameters if (spelltargetparms != null && spelltargetparms.Length > 0) { if (spelltargetparms[0].ParameterType == typeof(Server.Mobile)) { // set the target parameter targetargs = new object[1]; targetargs[0] = triggermob; } else if (spelltargetparms[0].ParameterType == typeof(Server.IPoint3D)) { // set the target parameter targetargs = new object[1]; // pick a random point around the caster int range = keywordarg2; if (range == 0) range = 1; int randx = Utility.RandomMinMax(-range, range); int randy = Utility.RandomMinMax(-range, range); if (randx == 0 && randy == 0) randx = 1; targetargs[0] = new Point3D(triggermob.Location.X + randx, triggermob.Location.Y + randy, triggermob.Location.Z); } else { // dont handle any other types of args throw (new ArgumentNullException()); } } // set the spell on the caster caster.Spell = spell; // invoke the spell method with the appropriate args spelltargetmethod.Invoke(spell, targetargs); // get rid of the placeholder wand if (cwand != null && !cwand.Deleted) cwand.Delete(); } catch { status_str = "bad spell call : " + spell.Name; casterror = true; // get rid of the placeholder wand if (cwand != null && !cwand.Deleted) cwand.Delete(); } if (casterror) return true; } else { status_str = "spell invalid or disabled : " + keywordargs[1]; //return true; } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); // note that returning true means that Spawn assume that it worked and will not try to recast break; } case typeKeyword.BCAST: { // syntax is BCAST[,hue][,font]/message string[] arglist = ParseSlashArgs(substitutedtypeName, 3); int hue = 0x482; int font = -1; if (arglist.Length > 0) { string[] keywordargs = ParseString(arglist[0], 3, ","); if (keywordargs.Length > 1) { try { hue = int.Parse(keywordargs[1]); } catch { status_str = "invalid hue arg to BCAST"; } } if (keywordargs.Length > 2) { try { font = int.Parse(keywordargs[2]); } catch { status_str = "invalid font arg to BCAST"; } } } if (arglist.Length > 1) { string msg = arglist[1]; if (arglist[1] != null && arglist[1].Length > 0 && arglist[1][0] == '@') { arglist = ParseSlashArgs(substitutedtypeName, 2); msg = arglist[1].Substring(1); } if (font >= 0) { // broadcast an ascii message to all players BroadcastAsciiMessage(AccessLevel.Player, hue, font, msg); } else { // standard unicode message format CommandHandlers.BroadcastMessage(AccessLevel.Player, hue, msg); } } else { status_str = "missing msg arg in BCAST"; return false; } TheSpawn.SpawnedObjects.Add(new KeywordTag(substitutedtypeName, spawner)); break; } default: { status_str = "unrecognized keyword"; // should never get here break; } } // indicate successful keyword spawn return true; } else if (IsSpecialItemKeyword(typeName)) { // these are special keyword item drops string[] arglist = ParseSlashArgs(substitutedtypeName, 2); string itemtypestr = arglist[0]; string baseitemtype = typeName; // itemtypestr will have the form keyword[,x[,y]] string[] itemkeywordargs = ParseString(itemtypestr, 3, ","); // deal with the special keywords itemKeyword kw = (itemKeyword)itemKeywordHash[baseitemtype]; switch (kw) { case itemKeyword.ARMOR: { // syntax is ARMOR,min,max //get the min,max if (itemkeywordargs.Length == 3) { int min = 0; int max = 0; bool converterror = false; try { min = int.Parse(itemkeywordargs[1]); } catch { status_str = "Invalid ARMOR args : " + itemtypestr; converterror = true; } try { max = int.Parse(itemkeywordargs[2]); } catch { status_str = "Invalid ARMOR args : " + itemtypestr; converterror = true; } if (converterror) return false; Item item = MagicArmor(min, max, false, false); if (item != null) { AddSpawnItem(spawner, TheSpawn, item, location, map, triggermob, requiresurface, spawnpositioning, substitutedtypeName, out status_str); } } else { status_str = "ARMOR takes 2 args : " + itemtypestr; return false; } break; } case itemKeyword.WEAPON: { // syntax is WEAPON,min,max //get the min,max if (itemkeywordargs.Length == 3) { int min = 0; int max = 0; bool converterror = false; try { min = int.Parse(itemkeywordargs[1]); } catch { status_str = "Invalid WEAPON args : " + itemtypestr; converterror = true; } try { max = int.Parse(itemkeywordargs[2]); } catch { status_str = "Invalid WEAPON args : " + itemtypestr; converterror = true; } if (converterror) return false; Item item = MagicWeapon(min, max, false); if (item != null) { AddSpawnItem(spawner, TheSpawn, item, location, map, triggermob, requiresurface, spawnpositioning, substitutedtypeName, out status_str); } } else { status_str = "WEAPON takes 2 args : " + itemtypestr; return false; } break; } case itemKeyword.JARMOR: { // syntax is JARMOR,min,max //get the min,max if (itemkeywordargs.Length == 3) { int min = 0; int max = 0; bool converterror = false; try { min = int.Parse(itemkeywordargs[1]); } catch { status_str = "Invalid JARMOR args : " + itemtypestr; converterror = true; } try { max = int.Parse(itemkeywordargs[2]); } catch { status_str = "Invalid JARMOR args : " + itemtypestr; converterror = true; } if (converterror) return false; Item item = MagicArmor(min, max, true, true); if (item != null) { AddSpawnItem(spawner, TheSpawn, item, location, map, triggermob, requiresurface, spawnpositioning, substitutedtypeName, out status_str); } } else { status_str = "JARMOR takes 2 args : " + itemtypestr; return false; } break; } case itemKeyword.JWEAPON: { // syntax is JWEAPON,min,max //get the min,max if (itemkeywordargs.Length == 3) { int min = 0; int max = 0; bool converterror = false; try { min = int.Parse(itemkeywordargs[1]); } catch { status_str = "Invalid JWEAPON args : " + itemtypestr; converterror = true; } try { max = int.Parse(itemkeywordargs[2]); } catch { status_str = "Invalid JWEAPON args : " + itemtypestr; converterror = true; } if (converterror) return false; Item item = MagicWeapon(min, max, true); if (item != null) { AddSpawnItem(spawner, TheSpawn, item, location, map, triggermob, requiresurface, spawnpositioning, substitutedtypeName, out status_str); } } else { status_str = "JWEAPON takes 2 args : " + itemtypestr; return false; } break; } case itemKeyword.SARMOR: { // syntax is SARMOR,min,max //get the min,max if (itemkeywordargs.Length == 3) { int min = 0; int max = 0; bool converterror = false; try { min = int.Parse(itemkeywordargs[1]); } catch { status_str = "Invalid SARMOR args : " + itemtypestr; converterror = true; } try { max = int.Parse(itemkeywordargs[2]); } catch { status_str = "Invalid SARMOR args : " + itemtypestr; converterror = true; } if (converterror) return false; Item item = MagicArmor(min, max, false, true); if (item != null) { AddSpawnItem(spawner, TheSpawn, item, location, map, triggermob, requiresurface, spawnpositioning, substitutedtypeName, out status_str); } } else { status_str = "SARMOR takes 2 args : " + itemtypestr; return false; } break; } case itemKeyword.SHIELD: { // syntax is SHIELD,min,max //get the min,max if (itemkeywordargs.Length == 3) { int min = 0; int max = 0; bool converterror = false; try { min = int.Parse(itemkeywordargs[1]); } catch { status_str = "Invalid SHIELD args : " + itemtypestr; converterror = true; } try { max = int.Parse(itemkeywordargs[2]); } catch { status_str = "Invalid SHIELD args : " + itemtypestr; converterror = true; } if (converterror) return false; Item item = MagicShield(min, max); if (item != null) { AddSpawnItem(spawner, TheSpawn, item, location, map, triggermob, requiresurface, spawnpositioning, substitutedtypeName, out status_str); } } else { status_str = "SHIELD takes 2 args : " + itemtypestr; return false; } break; } case itemKeyword.JEWELRY: { // syntax is JEWELRY,min,max //get the min,max if (itemkeywordargs.Length == 3) { int min = 0; int max = 0; bool converterror = false; try { min = int.Parse(itemkeywordargs[1]); } catch { status_str = "Invalid JEWELRY args : " + itemtypestr; converterror = true; } try { max = int.Parse(itemkeywordargs[2]); } catch { status_str = "Invalid JEWELRY args : " + itemtypestr; converterror = true; } if (converterror) return false; Item item = MagicJewelry(min, max); if (item != null) { AddSpawnItem(spawner, TheSpawn, item, location, map, triggermob, requiresurface, spawnpositioning, substitutedtypeName, out status_str); } } else { status_str = "JEWELRY takes 2 args : " + itemtypestr; return false; } break; } case itemKeyword.SCROLL: { // syntax is SCROLL,mincircle,maxcircle //get the min,max if (itemkeywordargs.Length == 3) { int minCircle = 0; int maxCircle = 0; bool converterror = false; try { minCircle = int.Parse(itemkeywordargs[1]); } catch { status_str = "Invalid SCROLL args : " + itemtypestr; converterror = true; } try { maxCircle = int.Parse(itemkeywordargs[2]); } catch { status_str = "Invalid SCROLL args : " + itemtypestr; converterror = true; } if (converterror) return false; int circle = Utility.RandomMinMax(minCircle, maxCircle); int min = (circle - 1) * 8; Item item = Loot.RandomScroll(min, min + 7, SpellbookType.Regular); if (item != null) { AddSpawnItem(spawner, TheSpawn, item, location, map, triggermob, requiresurface, spawnpositioning, substitutedtypeName, out status_str); } } else { status_str = "SCROLL takes 2 args : " + itemtypestr; return false; } break; } case itemKeyword.LOOT: { // syntax is LOOT,methodname if (itemkeywordargs.Length == 2) { Item item = null; // look up the method Type ltype = typeof(Loot); if (ltype != null) { MethodInfo method = null; try { // get the zero arg method with the specified name method = ltype.GetMethod(itemkeywordargs[1], new Type[0]); } catch { } if (method != null && method.IsStatic) { ParameterInfo[] pinfo = method.GetParameters(); // check to make sure the method for this object has the right args if (pinfo.Length == 0) { // method must be public static with no arguments returning an Item class object try { item = method.Invoke(null, null) as Item; } catch { } } else { status_str = "LOOT method must be zero arg : " + itemtypestr; return false; } } else { status_str = "LOOT no valid method found : " + itemtypestr; return false; } } if (item != null) { AddSpawnItem(spawner, TheSpawn, item, location, map, triggermob, requiresurface, spawnpositioning, substitutedtypeName, out status_str); } } else { status_str = "LOOT takes 1 arg : " + itemtypestr; return false; } break; } case itemKeyword.POTION: { // syntax is POTION Item item = Loot.RandomPotion(); if (item != null) { AddSpawnItem(spawner, TheSpawn, item, location, map, triggermob, requiresurface, spawnpositioning, substitutedtypeName, out status_str); } break; } case itemKeyword.TAKEN: { // syntax is TAKEN // find the XmlSaveItem attachment Item item = GetTaken(invoker); if (item != null) { AddSpawnItem(spawner, invoker, TheSpawn, item, location, map, triggermob, requiresurface, spawnpositioning, substitutedtypeName, out status_str); } break; } case itemKeyword.GIVEN: { // syntax is GIVEN // find the XmlSaveItem attachment Item item = GetGiven(invoker); if (item != null) { AddSpawnItem(spawner, invoker, TheSpawn, item, location, map, triggermob, requiresurface, spawnpositioning, substitutedtypeName, out status_str); } break; } case itemKeyword.NECROSCROLL: { // syntax is NECROSCROLL,index if (itemkeywordargs.Length == 2) { int necroindex = 0; bool converterror = false; try { necroindex = int.Parse(itemkeywordargs[1]); } catch { status_str = "Invalid NECROSCROLL args : " + itemtypestr; converterror = true; } if (converterror) return false; if (Core.AOS) { Item item = Loot.Construct(Loot.NecromancyScrollTypes, necroindex); if (item != null) { AddSpawnItem(spawner, TheSpawn, item, location, map, triggermob, requiresurface, spawnpositioning, substitutedtypeName, out status_str); } } } else { status_str = "NECROSCROLL takes 1 arg : " + itemtypestr; return false; } break; } case itemKeyword.MULTIADDON: { // syntax is MULTIADDON,filename if (itemkeywordargs.Length == 2) { string filename = itemkeywordargs[1]; // read in the multi.txt file Item item = XmlSpawnerAddon.ReadMultiFile(filename, out status_str); if (item != null) { AddSpawnItem(spawner, TheSpawn, item, location, map, triggermob, requiresurface, spawnpositioning, substitutedtypeName, out status_str); } } else { status_str = "MULTIADDON takes 1 arg : " + itemtypestr; return false; } break; } default: { status_str = "unrecognized keyword"; // should never get here break; } } return true; } else { // should never get here status_str = "unrecognized keyword"; return false; } }
public static XmlSpawner FindInRecentSpawnerSearchList(XmlSpawner spawner, string name) { if (spawner == null || name == null || spawner.RecentSpawnerSearchList == null) return null; ArrayList deletelist = null; XmlSpawner foundspawner = null; foreach (XmlSpawner s in spawner.RecentSpawnerSearchList) { if (s.Deleted) { // clean it up if (deletelist == null) deletelist = new ArrayList(); deletelist.Add(s); } else if (String.Compare(s.Name, name, true) == 0) { foundspawner = s; break; } } if (deletelist != null) { foreach (XmlSpawner i in deletelist) spawner.RecentSpawnerSearchList.Remove(i); } return (foundspawner); }
public static bool TestMobProperty(XmlSpawner spawner, Mobile mobile, string testString, Mobile trigmob, out string status_str) { status_str = null; // now make sure the mobile itself is there if (mobile == null || mobile.Deleted) { return false; } bool testreturn = CheckPropertyString(spawner, mobile, testString, trigmob, out status_str); return testreturn; }
public static Item FindItemByName(XmlSpawner fromspawner, string name, string typestr) { if (name == null) return (Item)null; int count = 0; Item founditem = FindInRecentItemSearchList(fromspawner, name, typestr); if (founditem != null) { return founditem; } Type targettype = null; if (typestr != null) { targettype = SpawnerType.GetType(typestr); } // search through all items in the world and find the first one with a matching name foreach (Item item in World.Items.Values) { Type itemtype = item.GetType(); if (typestr == null || (itemtype != null && targettype != null && (itemtype.Equals(targettype) || itemtype.IsSubclassOf(targettype)))) { if (!item.Deleted && (name.Length == 0 || String.Compare(item.Name, name, true) == 0)) { founditem = item; count++; // added the break in to return the first match instead of forcing uniqueness (overrides the count test) break; } } //if(count > 1) break; } // if a unique item is found then success if (count == 1) { // add this to the recent search list AddToRecentItemSearchList(fromspawner, founditem); return (founditem); } else return (Item)null; }