Before I begin, thank you to everyone who has been reading and supporting my tutorials. I truly hope that I can help expand your knowledge base for RunUO C#.
Time for some more "OnDoubleClick" action! In this mini-tutorial I will be creating an item that you can double click to change yourself into a Lich. As with every script we start with the using directives... I'm making an item so I am "using Server.Items;" - my script will effect a mobile so I'll also be "using Server.Mobiles;"
using System;
using Server.Network;
using Server.Items;
using Server.Mobiles;
I want to give my item the [constructable] tag and give it a name. Lets call it a "Lich Artifact" I'll also set it to be movable. For classes and namespaces make sure that you write the name as all one word as seen below.
using System;
using Server.Network;
using Server.Items;
using Server.Mobiles;
namespace Server.Items
{
public class LichsArtifact : Item
{
[Constructable]
public LichsArtifact() : base( 9636 )
{
Movable = true;
Name = "Lich Artifact";
}
You can see that the itemID i'll be using is 9636 as seem above "base( 9636 )" - Also note that my public class is all one word "LichsArtifact : Item"
Next I will demonstrate that serialization can be done at differen't points in the script. Its not always needed to do serialization last, though it is common practice.
using System;
using Server.Network;
using Server.Items;
using Server.Mobiles;
namespace Server.Items
{
public class LichsArtifact : Item
{
[Constructable]
public LichsArtifact() : base( 9636 )
{
Movable = true;
Name = "Lich Artifact";
}
public LichsArtifact( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
Now that I've added serialization I will give me script some instructions, I'll be using the OnDoubleClick method and I'll also add in a small if statement to run a check prior to use - making sure that when the item is double clicked it is not too far away from the player.
using System;
using Server.Network;
using Server.Items;
using Server.Mobiles;
namespace Server.Items
{
public class LichsArtifact : Item
{
[Constructable]
public LichsArtifact() : base( 9636 )
{
Movable = true;
Name = "Lich Artifact";
}
public LichsArtifact( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void OnDoubleClick( Mobile from )
{
if ( !from.InRange( GetWorldLocation(), 2 ) )
{
from.SendLocalizedMessage( 500446 ); // That item is too far away.
}
I've now instructed my script to send a localized message to the player if the item is 2 spaces away. "if ( !from.InRange( GetWorldLocation(), 2 ) )" and then "from.SendLocalizedMessage( 500446 );" - Remember that overrides always require some type of if statement to properly relay instructions. (or if defined already it can be used as a method -> example: "public override int InitMinHits" and "public override int InitMaxHits" as used on a piece of armor, clothing or a weapon.
Next I will add my else statements, one for if the player is a male and one for if the player is a female - this ensures that players who use this item can revert back to their original body value if used again.
using System;
using Server.Network;
using Server.Items;
using Server.Mobiles;
namespace Server.Items
{
public class LichsArtifact : Item
{
[Constructable]
public LichsArtifact() : base( 9636 )
{
Movable = true;
Name = "Lich Artifact";
}
public LichsArtifact( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void OnDoubleClick( Mobile from )
{
if ( !from.InRange( GetWorldLocation(), 2 ) )
{
from.SendLocalizedMessage( 500446 ); // That is too far away.
}
else
{
if ( from.BodyValue == 0x190 || from.BodyValue == 0x191 )
{
from.BodyValue = 24;
from.PlaySound( 1001 );
Effects.SendLocationParticles( EffectItem.Create( from.Location, from.Map, EffectItem.DefaultDuration ), 0x376A, 1, 29, 0x47D, 2, 9962, 0 );
Effects.SendLocationParticles( EffectItem.Create( new Point3D( from.X, from.Y, from.Z - 7 ), from.Map, EffectItem.DefaultDuration ), 0x37C4, 1, 29, 0x47D, 2, 9502, 0 );
}
Now that I've added my first "else" statement you can see that I've specified the bodyvalue of the player who may be using the item. remember, else if statements are one or the other. So if the player is not the bodyvalue i've specified (male/female) then it will move onto the other checks / statements. I have also added some particle effects for when the item is successfully used. I will do a tutorial on particle effects in the future, but for now lets just focus on the else if statements. I also plan to cover sounds in future tutorials "from.PlaySound( 1001 );"
Next I will add the rest of my statements and end the script.
using System;
using Server.Network;
using Server.Items;
using Server.Mobiles;
namespace Server.Items
{
public class LichsArtifact : Item
{
[Constructable]
public LichsArtifact() : base( 9636 )
{
Movable = true;
Name = "Lich Artifact";
}
public LichsArtifact( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void OnDoubleClick( Mobile from )
{
if ( !from.InRange( GetWorldLocation(), 2 ) )
{
from.SendLocalizedMessage( 500446 ); // That is too far away.
}
else
{
if ( from.BodyValue == 0x190 || from.BodyValue == 0x191 )
{
from.BodyValue = 24;
from.PlaySound( 1001 );
Effects.SendLocationParticles( EffectItem.Create( from.Location, from.Map, EffectItem.DefaultDuration ), 0x376A, 1, 29, 0x47D, 2, 9962, 0 );
Effects.SendLocationParticles( EffectItem.Create( new Point3D( from.X, from.Y, from.Z - 7 ), from.Map, EffectItem.DefaultDuration ), 0x37C4, 1, 29, 0x47D, 2, 9502, 0 );
}
else
{
if (from.Female == true )
{
from.BodyValue = 0x191;
from.PlaySound( 1001 );
Effects.SendLocationParticles( EffectItem.Create( from.Location, from.Map, EffectItem.DefaultDuration ), 0x376A, 1, 29, 0x47D, 2, 9962, 0 );
Effects.SendLocationParticles( EffectItem.Create( new Point3D( from.X, from.Y, from.Z - 7 ), from.Map, EffectItem.DefaultDuration ), 0x37C4, 1, 29, 0x47D, 2, 9502, 0 );
}
else
{
from.BodyValue = 0x190;
from.PlaySound( 1001 );
Effects.SendLocationParticles( EffectItem.Create( from.Location, from.Map, EffectItem.DefaultDuration ), 0x376A, 1, 29, 0x47D, 2, 9962, 0 );
Effects.SendLocationParticles( EffectItem.Create( new Point3D( from.X, from.Y, from.Z - 7 ), from.Map, EffectItem.DefaultDuration ), 0x37C4, 1, 29, 0x47D, 2, 9502, 0 );
}
}
}
}
}
}
I've added a closing bracket for each of my "snippets" of code (as I like to call them) and since I've serialized my script earlier in the tutorial I am all finished.
My script now peforms a check to see if the user is a male character or female and on use will transform them into the body value I specified as "from.Bodyvalue = 24;" then on its second use it will transform them back into their original body value - Depending on if they were male or female originally.
As I said, I plan to cover particle effects and sound in future tutorials but at least you can somewhat see how they are used.