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!

Adding Custom Flags to Players

ygor

Wanderer
Adding Custom Flags to Players

Intro
Sometimes you want to add a custom flag to the players, so you can control something, for example if they did or not a quest and if they will be able to do it again or not.
Of course you don´t want to delete players and restart the shard etc.

Description

Go to \Scripts\Mobiles and open PlayerMobile.cs

Now, look for private int m_Profession;

just below it, place your flag/variable, as example:private bool m_test;

Now, to keep this organized, lets add just below this declaration
Code:
//test flag for quest of the tutorial
             [CommandProperty( AccessLevel.GameMaster )]
		public bool test
		{
			get{ return m_test; }
			set{ m_test = value; }
		}

Now we must search for switch ( version ). This step is very important, and forgeting this will cause some doom
Code:
             switch ( version )
		{
		 case [COLOR="Red"]19[/COLOR]:
		            {
			m_test = reader.ReadBool();
			goto case [COLOR="Blue"]18[/COLOR];
			}

		case [COLOR="blue"]18[/COLOR]:
			{
				m_SolenFriendship = (SolenFriendship)...
Now, look for
Code:
writer.Write( (int) [COLOR="blue"]18[/COLOR] ); // version
and change 18 for the newer version, 19

And finally, add below this last line,
Code:
writer.Write( m_test );

Presto!

Conclusion

Adding custom flags can be a powerfull tool when designing a quest, and as this tutorial shows, its easy to implement, and can be easily accessed from other classes.
Also note, the method above can use others variables too, with few changes.

This tutorial was based in FSGov script by Ronin.
 

ygor

Wanderer
Lets make things more elegant!

Intro
Although the method above is functional, it can begin to take some space and make code confusing!
I got a reply from A_Li_N, and this part of the tutorial I will base on it!

Description

You are doing it in a way that is not a true 'flag' value, and therefore, you would have to add another bool each time you added a quest and serialize it, etc. This can cause lots of problems down the line.

Indeed, to make things compact, lets use booleans!
Booleans have a good feature, as in example: (Atention! Binary!)
Quest 1 -> 1=b00000001
Quest 2 -> 2=b00000010
Quest 3 -> 4=b00000100
Quest 4 -> 8=b00001000
Notice that you can have a unique number as the control of quests. For example, 7=4+2+1(b00111) ; 5=4+1(b00101); 12=8+4(b01100), etc!

To convert a binary to hex, without the use of a calculator(the windows one does the trick)
b010101010011 -> b 0101 0101 0011
0000=0
0001=1
0010=2
0011=3
0100=4
0101=5
0110=6
0111=7
1000=8
1001=9
1010=A
1011=B
1100=C
1101=D
1110=E
1111=F
b010101010011 -> b 0101 0101 0011 -> h 5 5 3 -> 0x553 alright?!
if you still completely lost, try this

So, let´s code! by A_Li_N
Code:
             [Flags]
	public enum CustomFlag
	{
		None      = 0x00000000,  
		Quest1   = 0x00000001,  //hex for binary 000001
		Quest2   = 0x00000002,  //hex for binary 000010
		Quest3   = 0x00000004,  //hex for binary 000100
		Quest4   = 0x00000008,  //hex for binary 001000
		Quest5   = 0x00000010,  //hex for binary 010000 
		Quest6   = 0x00000020   //hex for binary 100000
	}
...
	private CustomFlag m_CustomFlags;
...
	public CustomFlag CustomFlags
	{
		get{ return m_CustomFlags; }
		set{ m_CustomFlags = value; }
	}
...
	public bool GetFlag( CustomFlag flag )
	{
		return ( (m_CustomFlags & flag) != 0 );
	}

	public void SetFlag( CustomFlag flag, bool value )
	{
		if( value )
			m_CustomFlags |= flag;
		else
			m_CustomFlags &= ~flag;
	}
...
	Deserialize(...)
	{
		...
		m_CustomFlags = (CustomFlag)reader.ReadInt();
		...
	}
...
	Serialize(...)
	{
		...
		writer.Write( (int)m_CustomFlags );
		...
	}

You can then use these flags like the PlayerFlags to keep track of up to 64 quests in 1 variable. (1 serialization) You would get the flag by doing 'PlayerMobile.GetFlag( CustomFlag.Quest# )' and set them with 'PlayerMobile.SetFlag( CustomFlag.Quest#, true/false )'
You need to put the (de)serialization in the right place like you have with your bool.

With the CustomFlag enum at the top, you double the value up to 8, them move to the left and start again at 1, like I have shown.
Ex: h0001 h0002 h0004 h0008 h0010 h0020 h0040 h0080 h0100 h0200 h0400 h0800 h1000 (Can you see why?)

Alternatively, you could add custom values to the PlayerFlag enum at the top. Doing this would get rid of the need to add another serialized value. Flags can contain a total of 64 'values', including the 'None or empty'.

Conclusion
Its more compact, its more complex! The first method is fast and simple, but can eat some res from your server if the number increases.
This part of tutorial cover a more professional approach, hope you enjoy!

A special thanks to A_Li_N for the support!
 
Top