New to version 3.19 from version 3.11updated 2/27/07
Bug Fixes- fixed a possible exploit with the TAKE keyword in which players could hold an item on the cursor and prevent the item from being taken (thanks to DazedAndConfused for pointing this out).
- fixed a possible crash when using the SET keyword with no args in an XmlDialog Action field (thanks to morganm for pointing this out).
- fixed a bug in which assigning an extremely large expiration time to questholders could cause a crash (thanks to koluch for pointing this out). Expiration times are now capped at 100 years. This is a particular issue for playermade quests, since it is possible for players to enter such extreme expiration times.
- modified the [WriteMulti command to support staff names that have spaces in them when accessing files (thanks to Xavier_WER for the suggestion).
- modified the spawner Reset function to properly reset the refractory period for triggered spawners if that was set (thanks to Vladimir for pointing that out).
- fixed a possible crash bug with the playermade questholder editing gump (thanks to Auriel for pointing it out).
- fixed a problem with MinD, MaxD, or Rng values for individual spawn entries being inappropriately cleared when editing an entry string with the text entry book.- modified the ASCIIMSG keyword to deal with text sometimes not being visible to all nearby players (thanks to aph for pointing this out).
- fixed a crash bug with xmlfind when using an invalid region (thanks to seirge for pointing this out).
- fixed a possible crash bug with improperly formatted TriggerOnCarried strings (thanks to XavierWER for pointing this out).
- fixed a problem with the Repeatable flag on quests not being restored across restarts when set to false (thanks to Vladimir for pointing this out). This led to people sometimes being able to repeat non-repeatable quests.
- fixed a possible crash bug when using '[xmlsave'- fixed a problem with skill triggering not recognizing min/max skill value limits when combined with the '+' or '-' arguments for skill use success/failure (thanks to Lara for pointing this out).
- fixed a bug with COLLECTNAMED objectives not being displayed properly in the quest status gump. (thanks to Discord for pointing that out).
- fixed a problem with the [xmladd gump not refreshing properly after adding a spawner or adding a spawn entry from item/mobile selection gump. For example, it would reset the AutoNumbering checkbox after placing a spawner.
Modified Features- Name tests have been modified to support a special wildcard "*" that will match any name. (thanks to Kaon for the suggestion)
There are three types of name argument that can be used in tests and keywords
1) standard non-empty name argument (match specific named objects)
2) empty name argument (match only unnamed objects)
3) special * name argument (match objects with any name)
This should work anywhere that a name argument is normally required.
So, for example using a TriggerOnCarried string of
*,heavycrossbowwould allow triggering when the player was carrying a heavy crossbow regardless of the name.
- added the AllowCarried flag to the XmlUse attachment that toggles the ability to use an item when carried by the player using it. (true by default).
- modified the XmlDeathAction attachment to support multiple actions in a single Action specification. Just separate the multiple actions with semicolons.
- disabled the SpawnIdleTime feature. This feature was designed to reposition spawns that had been around for more than the SpawnIdleTime (72 hours by default) under the assumption that they might not be accessible for players to kill. I found it to be more trouble than it was worth. I'll think about a different way of testing for inaccessible spawns.
- modified smartspawning so that mobs that are below maximum hits, stamina, or mana will not be despawned (thanks to Kamuflaro for the suggestion). The previous test only looked at hits.
- extended existing support for accessing Array type properties to all other List types, including Arrays, and ArrayLists. For example, to get the name of the first attacker on a mobiles aggressors list you could use
[xmlget aggressors[0].attacker.namewhere aggressors is a List type property on mobiles, and attacker.name is a property on one of the elements in the list.
The same syntax can be used to refer to such properties in spawner entries and property tests.
- the XmlLifeDrain attachment now gives a message and adds effects just like the default succubus life drain attack.- added optional args for specifying hue and font in the BCAST keyword (thanks to Xavier_WER for the suggestion). The new syntax is
BCAST[,hue][,font]/messageNote that this uses the same hues and fonts as the SENDASCIIMSG and ASCIIMSG keywords,
SENDASCIIMSG[,probability][,hue][,font]/message textASCIIMSG[,probability][,hue][,font]/textso you can use them to test out various text/color combinations without having to actually broadcast to see what it looks like.

Unicode font (the default) can be specified with a font type of -1. So to specify colored unicode broadcast messages, use
BCAST,33,-1/System is going down now- default spawn placement will now automatically take into consideration the CanSwim and CantWalk mobile properties when calculating valid spawn locations. This will allow water creatures to automatically be allowed to spawn on water without having to explictly inform the spawner with '*' or #WET, and will prevent creatures that cant walk from being spawned on land.
- slight change to the DAMAGE keyword to allow a range value of 0. Previously range had to be greater than zero.
- custom regions that get registered after initialization will now be detected and can be used by region spawners.- added support for assigning a mobile used to allow spawners to issue commands using the "COMMAND/commandstring" keyword by assigning the name of the mobile in the static CommandMobileName variable at line 341 in basexmlspawner.cs.
Commands in RunUO are required to have a mobile associated with their execution to allow accesslevel verification. This mobile will be used to issue all commands executed with the COMMAND keyword. The accesslevel of the mobile will determine the commands that can be issued.
This mobile can be a dummy character/creature that was created just for this purpose, or an existing character.
The commandstring is any string that you would normally type on the command line (without the command prefix).
CODE |
private static string CommandMobileName = null;
|
If the value is left null, then the COMMAND keyword will only work with triggered spawners when the triggering player has sufficient accesslevel to issue the command.
- modified random subgroup spawning. Subgroups that cannot be completely spawned will not be selected for random spawning. All spawn entries in the subgroup have to be below their individual maxcount, and fully spawning the subgroup cannot exceed the overall spawner maxcount. Previously those subgroups would simply spawn the entries of the subgroup that could be spawned.
This will apply to both random and sequential spawning but note that forced subgroup spawning, as part of a conditional statement, for example, will still allow partial spawning of the target subgroup.
- made the SENDMSG and SENDASCIIMSG keywords usable as value type keywords and not just standalone keywords. so you can do things like
SETONNEARBY,5,,playermobile/SENDMSG/Greetings friends
to send messages to all nearby players (thanks to snicker7 for the suggestion).
The syntax for these keywords is
SENDMSG[,probability][,hue]/message text
SENDASCIIMSG[,probability][,hue][,font]/message text
- modified questholders to prevent snooping by other players, but allow staff to open the questholder status gump from questholders being carried by players (thanks to snicker7 for the suggestion).
- modified the way that the DAMAGE and POISON keywords work when used as value keywords.
Now, if they are used to modify a spawn object, then their effects will be applied to the spawn object, and if a range argument is used, then things within that range from the spawn object will be affected. (thanks to aph for the suggestion)
For example this spawn entry would apply damage to all players within 5 tiles of the mob named "Blather"
SETONMOB,Blather/DAMAGE,50,20,20,20,20,20,5,playeronly
Their behavior when used as standalone keywords was not changed.
- added protection against creating infinitely looping sequential spawn definitions. Spawn entries can now only be executed once per spawner tick.
- added the option to make addons created with the MULTIADDON keyword partially visible with the new PartialVisibility property (thanks to Lara for the idea). By setting this property to a percentage between 1-100, it will make that fraction of the addon components visible. An example of this is given in becomevisible.xml.
- changed the default smartspawning test to allow any unhidden staff, regardless of accesslevel to activate smartspawned spawners. This means that by default, all players and staff will activate smartspawned spawners. If you change the default level to Player by changing the setting of the SmartSpawnAccessLevel variable at line 100 of in xmlspawner2.cs to something like
CODE |
// specifies the level at which smartspawning will be triggered. Players with AccessLevel above this will not trigger smartspawning unless unhidden. public static AccessLevel SmartSpawnAccessLevel = AccessLevel.Player;
|
then only players and unhidden staff will activate them, but hidden staff will not (thanks to Erica for the suggestion).
- added support for Nerun's new .map format in [xmlimportmap. The [xmlimportmap command will automatically detect new and old formats and import accordingly. You can even import old and new formats at the same time.
New Features
- added support for a new xmlspawner.cfg file in the Data folder of the main RunUO installation. This configuration file can be used to specify certain default values without having to modify the settings in xmlspawner scripts themselves. This can simplify upgrading to new revisions since custom settings can now be specified outside of upgraded scripts and so will be maintained when those scripts are replaced.
If you do not wish to use this configuration feature, you do not have to add an xmlspawner.cfg file. In that case, the standard system defaults will be used just as they have in the past. This new feature is completely optional.
Below is an example of a configuration file illustrating the current support for some of the common xmlspawner and xmldialog settings.
Data/xmlspawner.cfg
QUOTE |
# This is a sample xmlspawner configuration file # comments can be added anywhere in the file using the # at the beginning of the line # sections are specified with [section] # individual setting assignments have the form 'name=value'. Spaces can be placed around the '=' # empty lines are ignored and can be placed anywhere
[XmlSpawner]
XmlSpawnDir=Spawns DiskAccessLevel=Administrator SmartSpawnAccessLevel=Administrator defMinDelay=5 defMaxDelay=10 defHomeRange=5 defSpawnRange=5 defRelativeHome=true
[XmlDialog]
XmlQuestNPCDir=XmlQuestNPC defProximityRange=3 defResetTime=60 defSpeechPace=10
|
Other systems can also make use of the configuration file by simply specifying their configuration settings in a custom named section. These custom sections will have no effect on any other settings in other sections.
For other systems to make use of the configuration file, the following call would be added to their Initialization method which would load in the settings from the named section during initialization. Individual settings would be processed using the specified custom method.
CODE |
XmlSpawner.LoadSettings(new XmlSpawner.AssignSettingsHandler(AssignSettings), "XmlDialog");
|
where "XmlDialog" would be replaced with a string identifying the section name in the configuration file used to hold the settings for the system.
"AssignSettings" is a custom public static method that would be scripted to process each setting. An example is shown below from the XmlDialog system.
CODE |
public static void AssignSettings(string argname, string value) { switch (argname) { case "XmlQuestNPCDir": DefsDir = value; break; case "defResetTime": defResetTime = TimeSpan.FromSeconds(XmlSpawner.ConvertToInt(value)); break; case "defProximityRange": defProximityRange = XmlSpawner.ConvertToInt(value); break; case "defSpeechPace": defSpeechPace = XmlSpawner.ConvertToInt(value); break; } }
|
- added the new MEFFECT keyword that allows moving effects to be specified. The syntax is
MEFFECT,itemid[,speed][,x,y,z][,x2,y2,z2]
When x,y,z is specified the moving effect will start at the location and move toward the target object. This syntax must be used as a modifier of a spawned object. If x,y,z is omitted, then the starting location will be the location of the spawner.
For example, to have an fireball move from the spawner location to a triggering player,
SETONTRIGMOB/MEFFECT,14036,3
To have it move from a specified location such as (1500,1100,10) to the triggering player
SETONTRIGMOB/MEFFECT,14036,3,1500,1100,10
Note that the z coordinate should be above ground level to avoid the appearance of ground clipping.
When x2,y2,z2 is also specified the moving effect will start at x,y,z and end at x2,y2,z2 allowing the effect to move between two arbirary locations in the world. This syntax can be used as a standalone keyword. For example the following entry would create a fireball travelling between the two locations.
MEFFECT,14036,3,1500,1100,10,1520,1120,10
- added the 'GETONNEARBY,range,name[,type][,searchcontainers],property' keyword that can be used to get or test properties on nearby items or mobiles. This can be used in property assignments or property tests. If more than one of the specified object is found, it will only return the value from one.
For example, to test to see if someone has placed the longsword named "Grizzleblag" on the ground near the spawner you could use a condition test like
GETONNEARBY,1,Grizzleblag,longsword,visible=true
Or you could get the size of a pile of gold in a nearby container with
SENDMSG/{GETONNEARBY,1,,gold,true,amount} gold pieces are in the container
- added the new standalone keyword 'SETONPETS,range' that allows you to set properties on nearby pets belonging to the triggering mob where the range is the distance from the triggering mob. You would use it like
SETONPETS,range/prop/value/prop/value...
- added the new 'GETACCOUNTTAG,tagname' keyword that allows access to account tags on the triggering player (thanks to CEO for the suggestion). This can be used in value assignments or property tests. For example, if you wanted to test for an account tag before handing out a quest, you could use a Condition test like
GETACCOUNTTAG,quest1="done"
where 'quest1' would be the account tag name, and "done" would be the value of the tag, or
SENDMSG/I see that you already have {GETACCOUNTTAG,numRewardsChosen} veteran rewards.
where 'numRewardsChosen' is the account tag used to keep track of vet rewards.
- added the new 'SETACCOUNTTAG,tagname/value' keyword that allows you to create or change the value of account tags on the triggering player. For example, to create an account tag named 'quest1' with the value 'done' use a spawn entry like
SETACCOUNTTAG,quest1/done
- enabled attachment support for "using" objects that allows you to add custom double-click functionality to any object, even statics and mobiles.
If you dont want to use this feature you can disable it by going into PacketHandlerOverrides.cs and commenting out the line in red as shown below
QUOTE |
// this replaces the default packet handler for Use requests. Items and Mobiles will still // behave exactly the same way, it simply adds a hook in to call the OnUse method for attachments // they might have. //Timer.DelayCall( TimeSpan.Zero, new TimerCallback( UseReqOverride ) );
|
With this feature enabled the following overridable methods are available to all attachments
CODE |
public virtual void OnUse(Mobile from) { }
|
which will be called whenever the object that the attachment is attached to is used (e.g. double clicked). The 'from' argument is the person doing the using.
CODE |
public virtual void OnUser(object target) { }
|
When you add an attachment to a player, this method will be called whenever the player "uses" things. The 'target' argument is the thing being used.
Note that the attachment system OnUse and OnUser methods dont replace the default RunUO OnUse method, they are called in addition to any OnUse support that a target object might have, so if an object has support for OnUse in its script, it will still be called.
If you want attachments to ignore the default RunUO OnUse call, you can override the following method in your attachments and have it return true:
CODE |
public virtual bool BlockDefaultOnUse(Mobile from, object target) { return false; }
|
- added the new XmlUse attachment that allows you to control the use of any object. By adding this attachment to any object you can specify the conditions required to use the object as well as add new use functions to the object that will be executed on double clicks.
Properties:Condition A test string that is the same as any xmlspawner condition test. It will be tested whenever the object with the attachment is used (double clicked). If it returns true, then the object can be used. This can be used to control the built-in use functions of an object or the custom use functions that you add on the fly.
MaxUsesAn integer value that restricts the maximum number of uses allowed. (default = unlimited)
RefractoryAn integer that restricts the minimum time in seconds between uses. (default = 0)
MaxRangeAn integer that restricts the maximum distance in tiles allowed from the target object (default = 3)
RequireLOSA bool that determines whether line-of-sight between the user and the object is required (default = false)
SuccessActionAssign this string to specify custom actions (in addition to the default OnUse functionality) that will be taken when the conditions for use of the object are met. The action string can be any spawnable entry string and supports multiple actions separated by semicolons.
FailureActionThis action will be executed when the conditions for use of the object are NOT met.
MaxUsesAction This action will be executed when someone tries to use the object after the max uses has been exceeded.
RefractoryAction This action will be executed when someone tries to use the object before the refractory period is over.
BlockDefaultUse Setting this property to true will allow you to completely disable the default scripted RunUO method called when the object is used. This can be used to replace existing default use functions with your custom use actions.
Constructors: public XmlUse()
public XmlUse(int maxuses)
public XmlUse(int maxuses, double refractory)
Examples:For example, to make any object usable only once, just issue this command and target the object
[addatt xmluse 1Note that you can always just remove the attachment and the object will go back to its default behavior. The attachment makes no changes to the object.
To spawn a metal box that can only be opened 3 times with a minimum delay of 10 seconds between openings and delivers a message if someone tries to use it more than the maximum number of times use a spawn entry like
metalbox/ATTACH/<xmluse,3,10/maxusesaction/@SENDMSG/Max uses exceeded.>To spawn a stone static that pops open a gump when double clicked
static,3796/ATTACH/<xmluse/successaction/@GUMP,Wicked woods,0/Enter here and despair!>you could also add this manually to any existing static by simply adding the attachment with
[addatt xmluse and then opening up the props on the attachment with
[getattand assigning the
SuccessAction property the value of "GUMP,Wicked woods,0/Enter here and despair!"

To spawn a door that can only be opened by players named "Bob"
metaldoor,1/ATTACH/<xmluse/condition/@GETONTRIGMOB,name="Bob">or by players that havent yet completed an objective of a quest
metaldoor,1/ATTACH/<xmluse/condition/@GETONCARRIED,Bunglers quest,questholder,completed1=false>To prevent a player from using any metal doors for 2 minutes, create a triggered spawner that will add an xmluse attachment to the player lasting 2 minutes with the following entry
SETONTRIGMOB/ATTACH/<xmluse/expiration/00:02/condition/@GETONTHIS,TYPE!#MetalDoor>Note that GETONTRIGMOB will always refer to the player doing the using, and GETONTHIS will always refer to the object being used.
- added an example of the new XmlUse attachment in customuse.xml. Just do an "[xmlloadhere customuse.xml" and respawn it.
Examples:1. Creates a metalbox that can only be opened by someone with positive karma, and after opening it sends a message, opens a gump, and changes the players karma to evil. If someone with negative karma tries to open it, they are refused and a gump pops up.
2. Creates a door that can only be opened by someone with enough strength (>70). If a player is too weak, they will be blocked and a gump will be displayed.
3. Spawns a horse that can only be mounted by someone with high enough chivalry (>90). If a player lacking the skill attempts to use it, they will be blocked and a message will be displayed.
4. Creates a brazier that will spawn a daemon when double clicked if the player has enough fame (>1000).
5. Spawns a stone that will deliver a bag of regs when double-clicked with a waiting time between uses of 10 seconds.
6. Creates a magic portal that teleports the user to a site in Ilshenar when double clicked.
Note that examples 4,5, and 6 are done using simple statics that have no default use scripted.
- added the ability to adjust the spawner timer priority for individual spawners so that you can have things like sequentialspawn-controlled animation running at up to the maximum timer priority.One limitation of the current sequential spawning is that the minimum spawner clock tick is 1 second, even if you set min/maxdelay to zero. That is because the spawner timer priority is fixed at 1 second. To change this priority for individual spawners, set the BasePriority property on the spawner to one of these values (or their int equivalents)
public enum TimerPriority
{
EveryTick,
TenMS,
TwentyFiveMS,
FiftyMS,
TwoFiftyMS,
OneSecond,
FiveSeconds,
OneMinute
}
That will define the spawner timer interval when min/maxdelay is set to zero.
To prevent accidentally leaving spawners with modified timer priorities, the BasePriority is reset back to the default of one second on server restarts. I havent decided whether to allow this to be serialized and restored on restarts.
- included an example of the use of modified timer priority in boulder.xml which creates an animated boulder moving across the screen triggered by nearby players, and if it detects a collision with the triggering player then it kills them (thanks to Xerrox for the idea).
You can play around with changing the basepriority setting in the spawner entry to see how it changes the animation speed.
- added the new #NOTILES,startid[,endid] spawn control keyword. This is similar to the #TILES keyword, but it allows you to specify the land/static tiles that the spawns for an entry will NOT be placed on. Only passable tiles that are not on the #NOTILES list will be used for spawn placement.
The example below has 2 spawn entries.
The first entry uses the #NOTILES keyword to specify that the orcs should NOT be spawned on grass tiles with ids of 3. Note that the lava tiles are not passable and so the orcs are placed on dirt, which is the only passable, non-grass tile around.
The second entry uses the #TILES keyword to place the lavalizards on the lava tiles.
- added an optional 'equippedonly' argument to the existing SETONCARRIED keyword that would allows access things like a players bankbox. The new syntax is
SETONCARRIED,itemname[,itemtype][,equippedonly]/prop/value/prop2/value...where specifying 'true' or 'equippedonly' for the equipped only arg will only look at items that are directly equipped on the mobile, and that would include bankboxes.
So to add something to a players bankbox you would do
SETONCARRIED,,bankbox,equippedonly/ADD/gold,500- added the new KILL keyword that can be used to kill mobiles. For example, the spawn entry
SETONTRIGMOB/KILLwould kill the triggering mob, or
SETONNEARBY,5,,rat/KILLwould kill all of the rats within 5 tiles
-added the new standalone keyword "SPAWN[,spawnername],subgroup" which can be used to force spawning of a particular subgroup on a particular spawner. If the spawnername arg is omitted, then the current spawner will be used.
- added a TYPE property keyword that returns the object class type. For example "GETONTRIGMOB,TYPE" would return the type of the triggering mob.
- added the new #WET and #TILES,startid[,endid] spawn control keywords. These allow you to restrict the land/static tiles that the spawns for an entry will be placed on. This works for both normal and regional spawning.
Only tiles that have been frozen into the map will be checked. It will not check for static items or multis that have simply been placed in the world.
Use of either of these keywords will automatically ignore surface restrictions during spawn placement (like using * in front of the entry).
You can determine the id of a tile by simply doing a [props on it and looking at the TileID for land targets, and ItemID for static targets. You to specify a single tile or a range of tiles to be included.
The example below has 5 spawn entries.
The first uses the #WET keyword to specify that the waterelemental spawns should only be placed on tiles that have the Wet tiledata flag set (water tiles).
The second entry uses the #TILES keyword to specify that the orcs should only be spawned on dirt tiles with ids between 113-120.
The third entry has trolls that are only spawned on a variety of grass tiles.
The dolphins spawn only on water tiles with an id of 6044.
The fifth entry spawns eagles on tree tiles with id 3296.
- added the '[WhatIsIt' command that will report the type and name of the target. This can be used by players or staff to provide information needed to set up quest objectives or any other situation where knowing the type and name of an object is needed. (thanks to Lara for the suggestion).