RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Items and Mobiles: Variables, Properties and Serialization

Vorspire

Knight
Items and Mobiles: Variables, Properties and Serialization

Items and Mobiles: Variables, Properties and Serialization
Difficulty: 5/10 (Requires basic understanding of scope, key-words, data-types, variables and methods)​
This tutorial will teach you how to create new Variables and Properties for use with Mobiles and Items.​
We will be taking the steps needed to create the basics for a new Level System.​



--------------------------------------------------------




In Part 1, we will look at how to create a new Variable in the PlayerMobile class and turn it into a public Property, while also allowing it's value to be Serialized and Deserialized (Saved and Loaded).
This Variable/Property will be called "Level" and will hold the Player's current Level number, using the integer data-type.

In Part 2, we will look at how to create a new Variable in the BaseWeapon class and turn it into a public Property, while also allowing it's value to be Serialized and Deserialized (Saved and Loaded).
This Variable/Property will be called "LevelReq" and will hold the Weapon's Level Requirement number, using the integer data-type.



--------------------------------------------------------




1
Adding a new Property to the PlayerMobile class

Note: All code shown in the following examples must be inserted, in order, at the green line shown below;

Scripts/Mobiles/PlayerMobile.cs
Rich (BB code):
	public class PlayerMobile : Mobile
	{
		================

1.1: Private Variable

The Private Variable is used to store the value of the Player's current Level and will only be available to the PlayerMobile class, you can't access this Variable from any other class outside of the PlayerMobile class scope. (We will cover this later)

Since we want to store a number, we need to use the Integer data-type, it is defined as "int" and supports a maximum value of 2,147,483,647

The Private Variable we will create will be called "m_Level" and will have a default value of 1; This default value will be the Level number that you wish the Player to start with.
Rich (BB code):
private int m_Level = 1;

1.2: Public Variable

The Public Variable is used to control the access to the Private Variable "m_Level", there are two accessors: "get" and "set".

The Public Variable will be available to the PlayerMobile class and to other classes from outside of the PlayerMobile class scope.

The Public Variable we wll create wll be called "Level" and will use both "get" and "set" accessors to manipulate the value of the Private Variable "m_Level".
Rich (BB code):
private int m_Level = 1;

public int Level
{
	get { return m_Level; } //Get the value of m_Level
	set { m_Level = value; } //Set the value of m_Level
}

Note: The "value" variable doesn't seem to exist before we use it, this is because it is silently passed as an argument to the scope of the "set" accessor, much like an argument in a method.
Note: "value" always contains the value from the right-hand-side of an operation, for example;
Rich (BB code):
Level = 100;
Where the "value" will be 100.

1.3: Public Property

The Public Property is the Public Variable with an Attribute Tag attached to it, this tag allows our Public Property to become available on the [Props command list.

The Public Property accessors "get" and "set" can be limited to an AccessLevel when using the following Attribute Tag;
Rich (BB code):
private int m_Level = 1;

[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
public int Level
{
	get { return m_Level; } //Get the value of m_Level
	set { m_Level = value; } //Set the value of m_Level
}
Note: The "get" accessor is limited to AccessLevel.Counselor, this means that anyone with Counselor access and above can get (view) this Public Property's value.
Note: The "set" accessor is limited to AccessLevel.GameMaster, this means that anyone with GameMaster access and above can set this Public Property's value.

1.4: Serializing

Serializing is the process of writing variable data to RunUO's save files, since we are editing the PlayerMobile class, the save files will be located in Saves/Mobiles.

When we Serialize a variable value, we save the data so that RunUO can load it again when the server is (re-)started, this process is called Deserializing.

Note: I recommend that you have this tutorial on stand-by so that if you don't understand something here, you can reference it there;
http://www.runuo.com/forums/tutorials/302-serialization.html

All we need to do now is Serialize the "m_Level" Private Variable, but be warned that this is possibly the most difficult step in this tutorial and I will proceed with caution when explaining the details.

In the PlayerMobile class, you will need to find this method;
Rich (BB code):
		public override void Serialize( GenericWriter writer )
		{

Inside the Serialize method scope, find the first line that contains;
Rich (BB code):
writer.Write( (int) 25 ); // version
Note: The number 25 in the above sample may be different to your number.

The first thing you must do is increase the version number by 1. (25 becomes 26)

After you have increased the version number, you need to tell the "writer" that you want to save our "m_Level" Private Variable;
Rich (BB code):
writer.Write( (int) 26 ); // version

writer.Write( m_Level );

1.5: Deserializing

Deserializing is the process of reading variable data from RunUO's save files, since we are editing the PlayerMobile class, the save files will be located in Saves/Mobiles.

When we Deserialize a variable value, we load the data into RunUO and restore the value of the Private Variable "m_Level" when the server is (re-)started.

Note: I recommend that you have this tutorial on stand-by so that if you don't understand something here, you can reference it there;
http://www.runuo.com/forums/tutorials/302-serialization.html

All we need to do now is Deserialize the "m_Level" Private Variable, but be warned that this is possibly the most difficult step in this tutorial and I will proceed with caution when explaining the details.

In the PlayerMobile class, you will need to find this method;
Rich (BB code):
		public override void Deserialize( GenericReader reader )
		{

Inside the Deserialize method scope, find the first line that contains;
Rich (BB code):
int version = reader.ReadInt();

Now we need to ask the "reader" for the value we previously saved, this is the critical part, there should be a "switch" statement just below the above example, we will need to add an extra "case" to this "switch" because it will determine which values to load based on the "version" number.

So, find the code similar to the following example;
Rich (BB code):
int version = reader.ReadInt();

switch ( version )
{
	case 25:
	{
Note: "case" 25 is the previous version number that we increased in the Serialize method.

Since we increased our version number, we will also need to increase the amount of "cases" in the "switch" scope;
Rich (BB code):
int version = reader.ReadInt();

switch ( version )
{
	case 26:
	{
		m_Level = reader.ReadInt();

		goto case 25; //Fall through to case 25 to allow other variables to be loaded
	}
	case 25:
	{

1.6: Implementing the Public Variable

It's all about the usage.
Now we have a fully functional Level property attached to the PlayerMobile class, we just need a way to use it, unfortuantely, that is a completely different tutorial ;)
By now you should understand how to create you own custom properties for Mobiles of all kinds. This part of the tutorial can also be applied to BaseCreature too, if you wanted to give monsters a Level system.



--------------------------------------------------------




2
Adding a new Property to the BaseWeapon class

Note: All code shown in the following examples must be inserted, in order, at the green line shown below (unless otherwise stated);

Scripts/Items/Weapons/BaseWeapon.cs
Rich (BB code):
	public abstract class BaseWeapon : Item, IWeapon, IFactionItem, ICraftable, ISlayer, IDurability
	{
		================

2.1: Private Variable

The Private Variable is used to store the value of the Weapon's current Level Requirement and will only be available to the BaseWeapon class, you can't access this Variable from any other class outside of the BaseWeapon class scope. (We will cover this later)

Since we want to store a number, we need to use the Integer data-type, it is defined as "int" and supports a maximum value of 2,147,483,647

The Private Variable we will create will be called "m_LevelReq" and will have a default value of 0; This default value will be the Level Requirement number that you wish the Weapon to be created with.
Rich (BB code):
private int m_LevelReq = 0;

2.2: Public Variable

The Public Variable is used to control the access to the Private Variable "m_LevelReq", there are two accessors: "get" and "set".

The Public Variable will be available to the BaseWeapon class and to other classes from outside of the BaseWeapon class scope.

The Public Variable we wll create wll be called "LevelReq" and will use both "get" and "set" accessors to manipulate the value of the Private Variable "m_LevelReq".
Rich (BB code):
private int m_LevelReq = 0;

public int LevelReq
{
	get { return m_LevelReq; } //Get the value of m_LevelReq
	set { m_LevelReq = value; } //Set the value of m_LevelReq
}

Note: The "value" variable doesn't seem to exist before we use it, this is because it is silently passed as an argument to the scope of the "set" accessor, much like an argument in a method.
Note: "value" always contains the value from the right-hand-side of an operation, for example;
Rich (BB code):
LevelReq = 100;
Where the "value" will be 100.

2.3: Public Property

The Public Property is the Public Variable with an Attribute Tag attached to it, this tag allows our Public Property to become available on the [Props command list.

The Public Property accessors "get" and "set" can be limited to an AccessLevel when using the following Attribute Tag;
Rich (BB code):
private int m_LevelReq = 0;

[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
public int LevelReq
{
	get { return m_LevelReq; } //Get the value of m_LevelReq
	set { m_Level = valueReq; } //Set the value of m_LevelReq
}
Note: The "get" accessor is limited to AccessLevel.Counselor, this means that anyone with Counselor access and above can get (view) this Public Property's value.
Note: The "set" accessor is limited to AccessLevel.GameMaster, this means that anyone with GameMaster access and above can set this Public Property's value.

2.4: Serializing

Serializing is the process of writing variable data to RunUO's save files, since we are editing the BaseWeapon class, the save files will be located in Saves/Items.

When we Serialize a variable value, we save the data so that RunUO can load it again when the server is (re-)started, this process is called Deserializing.

Note: I recommend that you have this tutorial on stand-by so that if you don't understand something here, you can reference it there;
http://www.runuo.com/forums/tutorials/302-serialization.html

All we need to do now is Serialize the "m_LevelReq" Private Variable, but be warned that this is possibly the most difficult step in this tutorial and I will proceed with caution when explaining the details.

In the BaseWeapon class, you will need to find this method;
Rich (BB code):
		public override void Serialize( GenericWriter writer )
		{

Inside the Serialize method scope, find the first line that contains;
Rich (BB code):
writer.Write( (int) 8 ); // version
Note: The number 8 in the above sample may be different to your number.

The first thing you must do is increase the version number by 1. (8 becomes 9)

After you have increased the version number, you need to tell the "writer" that you want to save our "m_LevelReq" Private Variable;
Rich (BB code):
writer.Write( (int) 9 ); // version

writer.Write( m_LevelReq );

2.5: Deserializing

Deserializing is the process of reading variable data from RunUO's save files, since we are editing the BaseWeapon class, the save files will be located in Saves/Items.

When we Deserialize a variable value, we load the data into RunUO and restore the value of the Private Variable "m_LevelReq" when the server is (re-)started.

Note: I recommend that you have this tutorial on stand-by so that if you don't understand something here, you can reference it there;
http://www.runuo.com/forums/tutorials/302-serialization.html

All we need to do now is Deserialize the "m_LevelReq" Private Variable, but be warned that this is possibly the most difficult step in this tutorial and I will proceed with caution when explaining the details.

In the PlayerMobile class, you will need to find this method;
Rich (BB code):
		public override void Deserialize( GenericReader reader )
		{

Inside the Deserialize method scope, find the first line that contains;
Rich (BB code):
int version = reader.ReadInt();

Now we need to ask the "reader" for the value we previously saved, this is the critical part, there should be a "switch" statement just below the above example, we will need to add an extra "case" to this "switch" because it will determine which values to load based on the "version" number.

So, find the code similar to the following example;
Rich (BB code):
int version = reader.ReadInt();

switch ( version )
{
	case 8:
Note: "case" 8 is the previous version number that we increased in the Serialize method.

Since we increased our version number, we will also need to increase the amount of "cases" in the "switch" scope;
Rich (BB code):
int version = reader.ReadInt();

switch ( version )
{
	case 9:
	{
		m_LevelReq = reader.ReadInt();

		goto case 8; //Fall through to case 8 to allow other variables to be loaded
	}
	case 8:

2.6: Implementing the Public Variable

It's all about the usage.
Now we have a fully functional Level Requirement property attached to the BaseWeapon class, we just need a way to use it, unfortuantely, that is a completely different tutorial ;)
By now you should understand how to create you own custom properties for Items of all kinds. This part of the tutorial can also be applied to BaseArmor too, if you wanted to give armor a Level Requirement.



--------------------------------------------------------


I hope someone can make use of this :)
 
Top