|
||
|
|||||||
| Script Support Get support for modifying RunUO Scripts, or writing your own! |
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 (permalink) |
|
Moderate
Join Date: Nov 2002
Location: USA
Posts: 6,598
|
As with my other tutorials, the ones you will find here are written for newer scripters. I will attempt to explain the chosen topics in enough (but not too much) detail for a good basic understanding. Please DO NOT post support questions in this thread as they will simply be removed.
I highly recommend that you have some knowledge of C# before beginning any RunUO script, and I recommend the thread “Scripting for Dummies: Creating an Item” if you have not yet written your first successful RunUO script. This series of lessons assumes you understand the key C# concepts such as Classes and Methods, as well as a familiarity with RunUO. In this lesson we will cover the basics of a Timer by building one step by step. Since it will be easier to explain without any extraneous code, this timer will be in a class by itself. Often you will see a timer embedded in another script which we will get too later or added to the end of another script. There is no real difference between a stand-alone script with a timer class and a timer class added to the end of another script. The second simply makes keeping the script and the timer it uses easier to keep together. Our timer will serve a somewhat useful purpose for those building quest npc’s or such. It will delete a given Mobile after a certain amount of time and optionally cause the Mobile to say something first. Not only will we explore timers, but we will delve into Overloading—a way to have more than one entry point into a given method or procedure. Let’s get started. First off, as with any good RunUO script we need to reference the System and Server namespaces. It is hard to write a script that does not use something from those two. Code:
using System; using Server; Code:
namespace Server.Mobiles
{
Now we will declare the class itself, it will be public so we can use it from elsewhere, and it will be derived from the base class “Timer.” Code:
public class MobileDeleteTimer : Timer
{
Code:
using System;
using Server;
namespace Server.Mobiles
{
public class MobileDeleteTimer : Timer
{
Code:
private Mobile mob; Next we need the constructor for our timer. This is called when the timer is created—when it is called with the “new” keyword. If we look in the Docs, we will see there are three Timer constructors (ctor) we can call our base class with, the one we will use is Timer( TimeSpan delay ) which you see takes one TimeSpan which is the delay before the timer “ticks.” For now I am going to hard code it to 10 seconds. We will make that adjustable later. Code:
public MobileDeleteTimer( Mobile m ) : base( TimeSpan.FromSeconds( 10 ) )
{
Code:
mob = m;
Priority = TimerPriority.OneSecond;
Our complete constructor is Code:
public MobileDeleteTimer( Mobile m ) : base( TimeSpan.FromSeconds( 10 ) )
{
mob = m;
Priority = TimerPriority.OneSecond;
}
Code:
protected override void OnTick()
{
Code:
if( mob == null || mob.Deleted )
{
this.Stop();
return;
}
Code:
mob.Delete(); Code:
using System;
using Server;
namespace Server.Mobiles
{
public class MobileDeleteTimer : Timer
{
private Mobile mob;
public MobileDeleteTimer( Mobile m ) : base( TimeSpan.FromSeconds( 10 ) )
{
mob = m;
Priority = TimerPriority.OneSecond;
}
protected override void OnTick()
{
if( mob == null || mob.Deleted )
{
Stop();
return;
}
mob.Delete();
}
}
}
Code:
Timer m_timer = new MobileDeleteTimer( this );
m_timer.Start();
__________________
David Forum Moderator The RunUO.com Forum Moderator Team Forum Rules and Guidelines RunUO Forum Search Engine Download RunUO 2.0 RC2 |
|
|
|
|
#2 (permalink) |
|
Moderate
Join Date: Nov 2002
Location: USA
Posts: 6,598
|
Overloading the constructor
Now that we have a working timer, we will add some features to it in an effort to make it more useful. The first thing we will do is add a way to adjust the delay… But, suppose we also like the 10 second delay—that will be good for most cases; we just want to be able to change it if we want to. It would be nice if we could create the timer most of the time just the way it is… Code:
Timer m_timer = new MobileDeleteTimer( this ); Code:
Timer m_timer = new MobileDeleteTimer( this, TimeSpan.FromSeconds( 30 ) As you recall our current constructor is Code:
public MobileDeleteTimer( Mobile m ) : base( TimeSpan.FromSeconds( 10 ) )
{
mob = m;
Priority = TimerPriority.OneSecond;
}
Code:
public MobileDeleteTimer( Mobile m, TimeSpan delay ) : base( delay )
{
mob = m;
Priority = TimerPriority.OneSecond;
}
Code:
public MobileDeleteTimer( Mobile m ) : this( m, TimeSpan.FromSeconds( 10 ) )
{
}
Here is the complete script with our first overloaded constructor. Code:
using System;
using Server;
namespace Server.Mobiles
{
public class MobileDeleteTimer : Timer
{
private Mobile mob;
public MobileDeleteTimer( Mobile m ) : this( m, TimeSpan.FromSeconds( 10 ) )
{
}
public MobileDeleteTimer( Mobile m, TimeSpan delay ) : base( delay )
{
mob = m;
Priority = TimerPriority.OneSecond;
}
protected override void OnTick()
{
if( mob == null || mob.Deleted )
{
Stop();
return;
}
mob.Delete();
}
}
}
Code:
Timer m_timer = new MobileDeleteTimer( this ); Code:
Timer m_timer = new MobileDeleteTimer( this, TimeSpan.FromSeconds( 30 )
__________________
David Forum Moderator The RunUO.com Forum Moderator Team Forum Rules and Guidelines RunUO Forum Search Engine Download RunUO 2.0 RC2 |
|
|
|
|
#3 (permalink) |
|
Moderate
Join Date: Nov 2002
Location: USA
Posts: 6,598
|
Another Option
Overloading wasn’t so bad. Lets jump right into the next modification (which will require a couple more overloads.) This time we are going to give the timer the ability to have the Mobile say something before it disappears. We need to change the primary constructor to accept a string as a parameter and then after a sanity check on the Mobile in question, and if the text is not null (if there is actually something to say,) have the Mobile speak the string. The updated constructor will appear as so… Code:
public MobileDeleteTimer( Mobile m, String toSay, TimeSpan delay ) : base( delay )
{
mob = m;
Priority = TimerPriority.OneSecond;
if( mob != null && toSay != null )
mob.Say( toSay );
}
However, now the overloaded constructor is calling a primary constructor that no longer exists. It must be modified as well. Since we still want a constructor that only requires a Mobile as a parameter, all we need to do is pass a null to our primary constructor where it is expecting a string. That should be enough to make it happy. Code:
public MobileDeleteTimer( Mobile m ) : this( m, null, TimeSpan.FromSeconds( 10 ) )
{
}
Code:
public MobileDeleteTimer( Mobile m, String toSay ) : this( m, toSay, TimeSpan.FromSeconds( 10 ) )
{
}
Code:
Timer m_timer = new MobileDeleteTimer( this, “Thank you my lord, I will be going now.” );
m_timer.Start();
Code:
using System;
using Server;
namespace Server.Mobiles
{
public class MobileDeleteTimer : Timer
{
private Mobile mob;
public MobileDeleteTimer( Mobile m ) : this( m, null, TimeSpan.FromSeconds( 10 ) )
{
}
public MobileDeleteTimer( Mobile m, String toSay ) : this( m, toSay, TimeSpan.FromSeconds( 10 ) )
{
}
public MobileDeleteTimer( Mobile m, String toSay, TimeSpan delay ) : base( delay )
{
mob = m;
Priority = TimerPriority.OneSecond;
if( toSay != null )
mob.Say( toSay );
}
protected override void OnTick()
{
if( mob == null || mob.Deleted )
{
Stop();
return;
}
mob.Delete();
}
}
}
We have now built a basic timer that has several options and serves a useful purpose. However timers still have a few more tricks up their sleeves.
__________________
David Forum Moderator The RunUO.com Forum Moderator Team Forum Rules and Guidelines RunUO Forum Search Engine Download RunUO 2.0 RC2 |
|
|
|
|
#4 (permalink) |
|
Moderate
Join Date: Nov 2002
Location: USA
Posts: 6,598
|
Review
A simple one-shot timer.
__________________
David Forum Moderator The RunUO.com Forum Moderator Team Forum Rules and Guidelines RunUO Forum Search Engine Download RunUO 2.0 RC2 |
|
|
|
|
#5 (permalink) |
|
Moderate
Join Date: Nov 2002
Location: USA
Posts: 6,598
|
Now lets dig a little deeper into timers. Looking at the RunUO docs, we see the Timer class has a handful of methods and properties. However only a few are normally used by scripters, those are:
Timer Constructors
A repeating timer is not much different than the single shot timer detailed above. Here is the complete class for a repeating timer. It will cause a given Mobile to emote some text on a regular interval until the timer is stopped. Code:
using System;
using Server;
namespace Server.Mobiles
{
public class MobileEmoteTimer : Timer
{
private Mobile mob;
private string something;
public MobileEmoteTimer( Mobile m, string emote, TimeSpan delay ) : base( delay, delay )
{
mob = m;
something = emote;
Priority = TimerPriority.TwoFiftyMS; // timer is checked every quarter second
}
protected override void OnTick()
{
if( mob == null || mob.Deleted )
{
Stop();
return;
}
mob.Emote( "*" + something + "*" );
}
}
}
Code:
public MobileEmoteTimer( Mobile m, string emote, TimeSpan delay ) : base( delay, delay ) In the OnTick() method we check for the existence of our Mobile, if it has been deleted we stop the timer to avoid a shard crashing null reference exception. Otherwise the Mobile emotes our text. Note there is no other provision in this code to stop the timer; that should be handled from the same script that calls the timer.
__________________
David Forum Moderator The RunUO.com Forum Moderator Team Forum Rules and Guidelines RunUO Forum Search Engine Download RunUO 2.0 RC2 |
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|