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!

[RUO X] World of Warcraft Level System Utility/SDK Implimentation Guide

Vorspire

Knight
[RUO X] World of Warcraft Level System Utility/SDK Implimentation Guide


Before you continue to read this post, make sure you have read and installed this script:
>> World of Warcraft Level System Utility/SDK


This guide is written based on the assumption of the reader having a common undestanding of C# termanology, key words and member placement, as well as the RunUO 2.0 API and serializing/deserializing methods.

The scale used for deciding the WoW-Style XP Zone is;


Trammel: Azeroth
Felucca: Azeroth
Ilshenar: Outland
Malas: Northrend
Tokuno: Northrend
Internal: Northrend


This guide will provide the following information:
  • Editing PlayerMobile
  • Editing BaseCreature
    [*]Editing BaseWeapon and BaseArmor (Level Requirements)
    [*]Creating a Cheque for Experience
    [*]Creating a Command to View Level Status
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////


All edits are to be made to: PlayerMobile.cs

Assembly Reference:


<PlayerMobile>: CREATE
Rich (BB code):
using System.Collections;
using System.Collections.Generic;

using Server.WoW;


Property Declarations:


<PlayerMobile>.m_Level: CREATE
<PlayerMobile>.m_LevelCap: CREATE
<PlayerMobile>.m_Experience: CREATE
<PlayerMobile>.m_Rested: CREATE
<PlayerMobile>.m_RestedCap: CREATE
<PlayerMobile>.m_LastOnline: CREATE
Rich (BB code):
private int
    m_Level = 1,
    m_LevelCap = 80,
    m_Experience = 0,
    m_Rested = 0,
    m_RestedCap = 8;

private DateTime
    m_LastOnline = DateTime.Now;


Command Properties:


<PlayerMobile>.LastOnline: CREATE
Rich (BB code):
[CommandProperty(AccessLevel.GameMaster)]
public DateTime LastOnline
{
	get
	{
		return m_LastOnline;
	}
	set
	{
		m_LastOnline = value;
	}
}

<PlayerMobile>.Rested: CREATE
Rich (BB code):
[CommandProperty(AccessLevel.GameMaster)]
public int Rested
{
	get
	{
		if( m_Rested > m_RestedCap )
			m_Rested = m_RestedCap;
		else if( m_Rested < 0 )
			m_Rested = 0;

		return m_Rested;
	}
	set
	{
		if (value == m_Rested)
			return;
		else
		{
			if (value > m_RestedCap)
				m_Rested = m_RestedCap;
			else
			{
				m_Rested = value;

				if (m_Rested > 0 && m_Rested < m_RestedCap)
					SendMessage(0x55, String.Format("You feel rested. Experience gained from killing monsters is increased by {0}% for {1} hours.", LevelUtility.RestedXPFactor * 100, m_Rested));
				else if (m_Rested >= m_RestedCap)
					SendMessage(0x55, String.Format("You are fully rested. Experience gained from killing monsters is increased by {0}% for {1} Hours.", LevelUtility.RestedXPFactor * 100, m_Rested));
				else if (m_Rested == 0)
					SendMessage(0x55, String.Format("You feel normal. Experience gained from killing monsters is now normal."));
			}
		}
	}
}

<PlayerMobile>.RestedCap: CREATE
Rich (BB code):
[CommandProperty(AccessLevel.Administrator)]
public int RestedCap
{
    get
    {
	if (m_RestedCap < 0)
		m_RestedCap = 0;

	return m_RestedCap;
    }
    set
    {
        m_RestedCap = value;
    }
}

<PlayerMobile>.Level: CREATE
Rich (BB code):
[CommandProperty( AccessLevel.Administrator )]
public int Level
{
    get
    {
        if (m_Level < 1)
            m_Level = 1;

        return m_Level;
    }
    set
    {
        if (value == m_Level)
            return;
        else if (value > m_Level)
        {
            int diff = value - m_Level;

            LevelUp( diff );
        }
        else if (value < m_Level)
        {
            int diff = m_Level - value;

            LevelDown( diff );
        }
    }
}

<PlayerMobile>.Experience: CREATE
Rich (BB code):
[CommandProperty(AccessLevel.Administrator)]
public int Experience
{
    get
    {
	if (m_Experience < 0)
		m_Experience = 0;

	return m_Experience;
    }
    set
    {
        if (value == m_Experience)
            return;
        else
        {
            SetExperience( value );
        }
    }
}

<PlayerMobile>.ExperienceReq: CREATE
Rich (BB code):
[CommandProperty(AccessLevel.Administrator)]
public int ExperienceReq
{
    get
    {
        ZoneXPBase xpBase = GetXPZone( true );

        return LevelUtility.ComputeExperienceReq( m_Level, xpBase );
    }
}


Methods:


<PlayerMobile>.GetXPZone( bool byLevel ): CREATE
Rich (BB code):
public ZoneXPBase GetXPZone( bool byLevel )
{
	if( byLevel )
	{
		if( m_Level <= 59 )
			return ZoneXPBase.Azeroth;
		else if( m_Level <= 69 )
			return ZoneXPBase.Outland;
		else
			return ZoneXPBase.Northrend;
	}
	else
	{
		if( Map == Map.Felucca || Map == Map.Trammel )
			return ZoneXPBase.Azeroth;
		else if( Map == Map.Ilshenar )
			return ZoneXPBase.Outland;
		else
			return ZoneXPBase.Northrend;
	}
}

<PlayerMobile>.SetExperience( int value ): CREATE
Rich (BB code):
public void SetExperience( int value )
{
	int difference = value - m_Experience;

	if (m_Experience != value)
		m_Experience = value;

	if ((Math.Abs(difference) > 0))
	{
		SendMessage((difference > 0 ? 57 : 37), "You {0} {1} XP", (difference > 0 ? "gained" : "lost"), Math.Abs(difference));

		CheckLevelGain( );
	}
}

<PlayerMobile>.CheckLevelGain( ): CREATE
Rich (BB code):
public void CheckLevelGain( )
{
	int count = 0;

	ZoneXPBase xpBase = GetXPZone( true );

	while (m_Experience >= ComputeExperienceReq(m_Level, m_Level + (count + 1), xpBase))
	{
		count++;
	}

	if (count > 0)
	{
		LevelUp(count);
	}
}

<PlayerMobile>.LevelUp( int count ): CREATE
Rich (BB code):
public void LevelUp( int count )
{
	if (m_Level + count > m_LevelCap)
		count = m_LevelCap - m_Level;

	m_Experience = 0;
	m_Level += count;
}

<PlayerMobile>.LevelDown( int count ): CREATE
Rich (BB code):
public void LevelDown( int count )
{
	if (m_Level - count < 1)
		count = m_Level - 1;

	m_Experience = 0;
	m_Level -= count;
}

<PlayerMobile>.AwardExperience( int count ): CREATE
Rich (BB code):
public void AwardExperience( BaseCreature killed, int bonus, int split )
{
	if (split < 1)
		split = 1;

	double baseXP = 0.0;

	if (killed != null)
	{
		if (killed.ControlMaster != null || killed.SummonMaster != null || killed.IsBonded || killed.Summoned)
			return;

		ZoneXPBase xpBase = GetXPZone( false );

		baseXP = LevelUtility.XPFromNPC( m_Level, killed.Level, xpBase );

		if (killed.IsElite)
			baseXP *= LevelUtility.EliteXPFactor;

		if (m_Rested > 0)
		{
			TimeSpan span = DateTime.Now.Subtract(m_LastOnline);
			int hours = (int)Math.Floor(span.TotalHours);

			if (hours > 0)
				m_Rested = m_Rested - hours;

			baseXP *= LevelUtility.RestedXPFactor;
		}
	}

	int final = (int)Math.Floor((double)((baseXP + bonus) / split));

	Experience += final;
}

<PlayerMobile>.OnLogout( LogoutEventArgs e ): EDIT
Rich (BB code):
m_LastOnline = DateTime.Now;

<PlayerMobile>.Serialize( GenericWriter writer ): EDIT
Rich (BB code):
writer.Write( (int) m_Level );
writer.Write( (int) m_LevelCap );
writer.Write( (int) m_Experience );
writer.Write( (int) m_Rested );
writer.Write( (int) m_RestedCap );
writer.Write( (DateTime) m_LastOnline );

<PlayerMobile>.Deserialize( GenericReader reader ): EDIT
Rich (BB code):
m_Level = reader.ReadInt( );
m_LevelCap = reader.ReadInt( );
m_Experience = reader.ReadInt( );
m_Rested = reader.ReadInt( );
m_RestedCap = reader.ReadInt( );
m_LastOnline = reader.ReadDateTime( );


/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////


All edits are to be made to: BaseCreature.cs

Assembly Reference:


<BaseCreature>: CREATE
Rich (BB code):
using System.Collections;
using System.Collections.Generic;

using Server.WoW;
using Server.Engines.PartySystem;


Property Declarations:


<BaseCreature>.m_Level: CREATE
Rich (BB code):
private int
    m_Level = 1;

<BaseCreature>.m_IsElite: CREATE
Rich (BB code):
private bool
    m_IsElite = false;


Command Properties:


<BaseCreature>.Level: CREATE
Rich (BB code):
[CommandProperty(AccessLevel.Administrator)]
public int Level
{
    get
    {
	if (m_Level < 1)
		m_Level = 1;

	return m_Level;
    }
    set
    {
        m_Level = value;
    }
}

<BaseCreature>.IsElite: CREATE
Rich (BB code):
[CommandProperty(AccessLevel.Administrator)]
public bool IsElite
{
    get
    {
	return m_IsElite;
    }
    set
    {
        SetElite( value );
    }
}


Methods:


<BaseCreature>.SetElite( bool value ): CREATE
Rich (BB code):
public virtual void SetElite( bool value )
{
   m_IsElite = value;
}

<BaseCreature>.GetBonusExperience( ): CREATE
Rich (BB code):
public virtual int GetBonusExperience( )
{
    return 0;
}

<BaseCreature>.OnDamage( int amount, Mobile from, bool willKill ): EDIT
Rich (BB code):
if (willKill)
{
	Dictionary<PlayerMobile, int> toAward = new Dictionary<PlayerMobile, int>();
	ArrayList entries = DamageEntries;
	List<Party> cycled = new List<Party>();

	foreach (DamageEntry de in entries)
	{
		if (de.Damager == null && de.Damager.Deleted)
			continue;

		Mobile damager = de.Damager;

		if (damager == null || damager.Deleted)
			continue;

		if (damager is PlayerMobile)
		{
			Party p = Party.Get(damager);

			if (p == null)
			{
				toAward.Add((PlayerMobile)damager, 1);
			}
			else if (!cycled.Contains(p))
			{
				ArrayList members = p.Members;

				for (int foo = 0; foo < members.Count; foo++)
				{
					PlayerMobile member = members[foo] as PlayerMobile;

					if (member == null || member.Deleted)
						continue;

					if (member.InRange(Location, 25))
						toAward.Add(member, members.Count);
				}

				cycled.Add(p);
			}
		}
		else if (damager is BaseCreature)
		{
			BaseCreature creature = damager as BaseCreature;
			PlayerMobile master = null;

			if (creature.Controled)
			{
				if (creature.ControlMaster != null && creature.ControlMaster is PlayerMobile)
					master = (PlayerMobile)creature.ControlMaster;
			}
			else if (creature.Summoned)
			{
				if (creature.SummonMaster != null && creature.SummonMaster is PlayerMobile)
					master = (PlayerMobile)creature.SummonMaster;
			}

			if (master == null || master.Deleted)
				continue;

			Party p = Party.Get(master);

			if (p == null)
			{
				toAward.Add(master, 1);
			}
			else if (!cycled.Contains(p))
			{
				ArrayList members = p.Members;

				for (int foo = 0; foo < members.Count; foo++)
				{
					PlayerMobile member = members[foo] as PlayerMobile;

					if (member == null || member.Deleted)
							continue;

					if (member.InRange(Location, 25))
						toAward.Add(member, members.Count);
				}

				cycled.Add(p);
			}
		}
	}

	foreach (KeyValuePair<PlayerMobile, int> valid in toAward)
	{
		if (valid.Key == null || valid.Key.Deleted)
			continue;

		valid.Key.AwardExperience(this, GetBonusExperience(), valid.Value);
	}
}

<BaseCreature>.Serialize( GenericWriter writer ): EDIT
Rich (BB code):
writer.Write( (int) m_Level );
writer.Write( (bool) m_IsElite );

<BaseCreature>.Deserialize( GenericReader reader ): EDIT
Rich (BB code):
m_Level = reader.ReadInt( );
SetElite( reader.ReadBool() );


/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////


All edits are to be made to: BaseArmor.cs, BaseWeapon.cs

Assembly Reference:


<BaseArmor/BaseWeapon>: CREATE
Rich (BB code):
using System.Collections;
using System.Collections.Generic;

using Server.WoW;


Property Declarations:


<BaseArmor/BaseWeapon>.m_LevelReq: CREATE
Rich (BB code):
private int
    m_LevelReq = 1;


Command Properties:


<BaseArmor/BaseWeapon>.LevelReq: CREATE
Rich (BB code):
[CommandProperty(AccessLevel.GameMaster)]
public int LevelReq
{
	get
	{
		if( m_LevelReq < 0 )
			m_LevelReq = 0;

		return m_LevelReq;
	}
	set
	{
		m_LevelReq = value;
	}
}


Methods:


<BaseArmor/BaseWeapon>.CheckLevel( Mobile from ): CREATE
Rich (BB code):
public bool CheckLevel(Mobile from)
{
	if( from == null || from.Deleted || !( from is PlayerMobile ) )
		return true;

	PlayerMobile equipee = from as PlayerMobile;

	if (m_LevelReq <= 0)
		return true;

	if (equipee.Level < m_LevelReq)
	{
		equipee.SendMessage(0x22, "You do not meet the level requirements for this item.");
		return false;
	}

	return true;
}

<BaseArmor/BaseWeapon>.CanEquip( Mobile from ): EDIT
Rich (BB code):

//<ADD THIS>

else if( !CheckLevel( from ) )
{
	return false;
}

//<BEFORE THIS>


else
{
	return base.CanEquip( from );
}

<BaseArmor/BaseWeapon>.Serialize( GenericWriter writer ): EDIT
Rich (BB code):
writer.Write( (int) m_LevelReq );

<BaseArmor/BaseWeapon>.Deserialize( GenericReader reader ): EDIT
Rich (BB code):
m_LevelReq = reader.ReadInt( );


/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////


Create a new file: ExperienceCheque.cs

Complete Script Code:


Rich (BB code):
using System;

using Server;
using Server.Mobiles;
using Server.WoW;

namespace Server.Items
{
	public class ExperienceCheque : Item
	{
		public int m_XPAmount;

		[CommandProperty( AccessLevel.GameMaster )]
		public int XPAmount
		{
			get
			{
				return m_XPAmount;
			}
			set
			{
				m_XPAmount = value;
				InvalidateProperties( );
			}
		}

		[Constructable]
		public ExperienceCheque( )
			: base( 0x14F0 )
		{
			Name = "a Blank Experience Cheque";
			m_XPAmount = 0;
		}

		[Constructable]
		public ExperienceCheque( int xpamount )
			: base( 0x14F0 )
		{
			Name = "a Cheque for " + xpamount.ToString("#,#") + " Experience";

            		m_XPAmount = xpamount;
		}

		public override void AddNameProperty( ObjectPropertyList list )
		{
			list.Add( ( m_XPAmount == 0 ) ? "a Blank Experience Cheque" : String.Format( "a Cheque for {0} Experience", m_XPAmount.ToString("#,#") ) );
		}

		public override void OnSingleClick( Mobile from )
		{
			LabelTo( from, ( m_XPAmount == 0 ) ? "a Blank Experience Cheque" : String.Format( "a Cheque for {0} XP", m_XPAmount.ToString("#,#") ) );
		}

		public override void OnDoubleClick( Mobile from )
		{
			PlayerMobile pm = from as PlayerMobile;

			if( pm != null && !pm.Deleted && pm.Alive )
			{
				if( IsChildOf( from.Backpack ) )
				{
					pm.Experience += m_XPAmount;
					Delete( );
				}
				else
				{
					from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
				}
			}
		}

		public ExperienceCheque( Serial serial )
			: base( serial )
		{
		}

		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );

			writer.Write( ( int )0 ); // version

			writer.Write( ( int )m_XPAmount );
		}

		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );

			int version = reader.ReadInt( );

			switch( version )
			{
				case 0:
					{
						m_XPAmount = reader.ReadInt( );
						break;
					}
			}
		}
	}
}


/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////


Create a new file: LevelStatusCMD.cs

Complete Script Code:


Rich (BB code):
using System;

using Server.Commands;
using Server.Mobiles;

namespace Server.WoW
{
	public class LevelStatusCMD
	{
		public static void Initialize()
		{
			CommandSystem.Register( "LevelStatus", AccessLevel.Player, new CommandEventHandler( LevelStatus_OnCommand ) );
		}

		[Usage( "LevelStatus" )]
		[Description( "Displays your current level status." )]
		private static void LevelStatus_OnCommand( CommandEventArgs e)
		{
			PlayerMobile pm = e.Mobile as PlayerMobile;

			if(pm != null)
			{
				pm.SendMessage("You are currently on level {0} and have {1} experience points! You need {2} experience points to advance to the next level.", pm.Level, pm.Experience, pm.ExperienceReq );
			}
		}
	}
}

/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////

Done!


OK, so hopefuly you've finished all of the edits, it wasn't too hard was it? :)

Now you should have a fully working level system!
Although the Level System we have just created is very basic, it should be easy enough to add in your own tweaks.

The part of the level system that handles the experience gained when killing a BaseCreature:
  • Is based on all damagers found in the BaseCreature's DamageEntries list.
  • Takes into account that the player may be a member of a party, if so, it will cycle through all of the members of the party and check if they are in range of the kill (25 tiles I think I set it to) and then distribute the experience evenly to each member. If a party has been "cycled", it will not be "cycled" again, so it will not grant more experience than it should.
  • If a damager is a BaseCreature, the system will look for the ControlMaster or SummonMaster as the main damager.
I really hope this helps everyone who posted earlier asking about how to impliment this system :)
I can not guarantee that the code in the guide is fully working, as a lot of last-minute edits were made in the forum post editor.
 

Holstis

Wanderer
I've located a few code errors like you said you typed this up quick so here we go

<PlayerMobile>.RestedCap: CREATE

[CommandProperty(AccessLevel.Administrator)]
publicl int RestedCap

<PlayerMobile>.Experience: CREATE

[CommandProperty(AccessLevel.Administrator)]
publicl int Experience

<PlayerMobile>.ExperienceReq: CREATE

[CommandProperty(AccessLevel.Administrator)]
publicl int ExperienceReq

<BaseCreature>.Level: CREATE

[CommandProperty(AccessLevel.Administrator)]
publicl int Level

im working the bugs out of the cheque. but other than that this is a great submission to the forums.
 

Vorspire

Knight
Thanks for pointing those out hehe, I was up till 6.30 AM writing this guide!

I have revised and corrected the typos.

Can you let me know what the bugs with the ExperienceCheque are, so I can update that too? :)

I saw this one: "using Server.WoWl;" - I'm really unsure on how this extra character has been added randomly to certain things :S
 

Holstis

Wanderer
hmmm... its been a while

Code:
Scripts: Compiling C# scripts...failed (1 errors, 0 warnings)
Errors:
 + Custom/ExperienceCheque.cs.cs:
    CS1520: Line 36: Class, struct, or interface method must have a return type
    CS1002: Line 36: ; expected
    CS1519: Line 37: Invalid token ':' in class, struct, or interface member declaration
    CS1519: Line 39: Invalid token '=' in class, struct, or interface member declaration
    CS1519: Line 39: Invalid token '(' in class, struct, or interface member declaration
    CS1519: Line 41: Invalid token '=' in class, struct, or interface member declaration
    CS1519: Line 41: Invalid token ';' in class, struct, or interface member declaration
    CS1518: Line 44: Expected class, delegate, enum, interface, or struct
    CS1518: Line 49: Expected class, delegate, enum, interface, or struct
    CS1518: Line 54: Expected class, delegate, enum, interface, or struct
    CS1518: Line 72: Expected class, delegate, enum, interface, or struct
    CS1518: Line 77: Expected class, delegate, enum, interface, or struct
    CS1518: Line 86: Expected class, delegate, enum, interface, or struct
    CS1022: Line 102: Type or namespace definition, or end-of-file expected
Scripts: One or more scripts failed to compile or no script files were found.
 - Press return to exit, or R to try again.

Sorry ive been looking at this for about two hours im a little rusty just started again currently deployed in iraq decided to try coding again. This is results of your base Experience Cheque.
 

Vorspire

Knight
I think I found the problem :) I forgot to use string formatting like this:

Code:
		public override void AddNameProperty( ObjectPropertyList list )
		{
			list.Add( ( m_XPAmount == 0 ) ? "a Blank Experience Cheque" : String.Format( "a Cheque for {0} Experience", m_XPAmount.ToString("#,#") ) );
		}

		public override void OnSingleClick( Mobile from )
		{
			LabelTo( from, ( m_XPAmount == 0 ) ? "a Blank Experience Cheque" : String.Format( "a Cheque for {0} XP", m_XPAmount.ToString("#,#") ) );
		}

I have updated the original script in the guide :)
 

Vorspire

Knight
LOL, my tired eyes...

This was the problem:
Code:
		[Constructable]
		public XPCheck( int xpamount )
			: base( 0x14F0 )
		{
			Name = "a Check For " + xpamount.ToString("#,#") + " Experience";

            		m_XPAmount = xpamount;
		}

The constructor name was wrong! How the heck could I miss that?
The script was loosly based on my own server's "XPCheck" - But I updated it to incorporate proper english.
A "check" is not a "cheque" :p

Main post updated, hopefuly no more problems hehe.
 

Holstis

Wanderer
<PlayerMobile>.AwardExperience( int count ): CREATE

if (killed.Controled || killed.IsBonded || killed.Summoned)
return;

<BaseCreature>.OnDamage( int amount, Mobile from, bool willKill ): EDIT

BaseCreature creature = damager as BaseCreature;
PlayerMobile master = null;

if (creature.Controled)
{

this time forgot an L in the code
 

Holstis

Wanderer
hmmm

I'm getting a error from the player mobile edit that reads

CS0117: Line 489: 'Server.Mobiles.BaseCreature' does not contain a definition for 'IsElite'
 

Holstis

Wanderer
really quick

due to my lack of coding in the past few years i am not much help so i apologize in advance for making this more of a hassle than a blessing.
 

Vorspire

Knight
Holstis;799518 said:
<PlayerMobile>.AwardExperience( int count ): CREATE

if (killed.Controled || killed.IsBonded || killed.Summoned)
return;

<BaseCreature>.OnDamage( int amount, Mobile from, bool willKill ): EDIT

BaseCreature creature = damager as BaseCreature;
PlayerMobile master = null;

if (creature.Controled)
{

this time forgot an L in the code

Ahh, is that another runuo 1.0 typo that was fixed in runuo 2.0?

My own shard is actually based on 1.0 Final, stripped down and rebuilt with the fundimentals of WoW, but mostly everything is still intact, the difference is mainly that it is 1.0 Final with .NET 3.5 developing support :D

So, that may also be the reason for a couple of typos here and there :S

Since this guide was aimed at RunUO 2.0, I will make the change :)

Updated line:
Code:
if (killed.ControlMaster != null || killed.SummonMaster != null || killed.IsBonded || killed.Summoned)

and as for the missing "IsElite" property, I completely forgot to add that into the guide lol, but I have now updated it with the property and concurrent methods.

You are not being a hassle at all, it's good to have constructive critisism and to be able to accept it with honor and to understand and simply, possibly accept that it may be for the better.
As my mentor always says "Critisism should not be the cause of anger."
 

hellalex

Sorceror
I did my best to try to install your system, but this is what I get.
Any guidance on how to edit the files correctly would be greatly appreciated :)

Code:
Errors:
[COLOR="DarkRed"] + Custom Scripts/BaseArmor.cs:[/COLOR]
    CS0592: Line 234: Attribute 'CommandProperty' is not valid on this declarati
on type. It is valid on 'property, indexer' declarations only.
    CS0246: Line 237: The type or namespace name 'PlayerMobile' could not be fou
nd (are you missing a using directive or an assembly reference?)
    CS0246: Line 240: The type or namespace name 'PlayerMobile' could not be fou
nd (are you missing a using directive or an assembly reference?)
    CS0246: Line 240: The type or namespace name 'PlayerMobile' could not be fou
nd (are you missing a using directive or an assembly reference?)
[COLOR="DarkRed"] + Custom Scripts/BaseCreature.cs:[/COLOR]
    CS0029: Line 1217: Cannot implicitly convert type 'System.Collections.Generi
c.List<Server.DamageEntry>' to 'System.Collections.ArrayList'
    CS0117: Line 1232: 'object' does not contain a definition for 'Get'
    CS0117: Line 1261: 'Server.Mobiles.BaseCreature' does not contain a definiti
on for 'Controled'
    CS0117: Line 1275: 'object' does not contain a definition for 'Get'
[COLOR="DarkRed"] + Custom Scripts/BaseWeapon.cs:[/COLOR]
    CS0592: Line 314: Attribute 'CommandProperty' is not valid on this declarati
on type. It is valid on 'property, indexer' declarations only.
[COLOR="DarkRed"] + Custom Scripts/PlayerMobile.cs:[/COLOR]
    CS0103: Line 154: The name 'm_Rested' does not exist in the current context
    CS0103: Line 154: The name 'm_RestedCap' does not exist in the current conte
xt
    CS0103: Line 155: The name 'm_Rested' does not exist in the current context
    CS0103: Line 155: The name 'm_RestedCap' does not exist in the current conte
xt
    CS0103: Line 156: The name 'm_Rested' does not exist in the current context
    CS0103: Line 157: The name 'm_Rested' does not exist in the current context
    CS0103: Line 159: The name 'm_Rested' does not exist in the current context
    CS0103: Line 163: The name 'm_Rested' does not exist in the current context
    CS0103: Line 167: The name 'm_RestedCap' does not exist in the current conte
xt
    CS0103: Line 168: The name 'm_Rested' does not exist in the current context
    CS0103: Line 168: The name 'm_RestedCap' does not exist in the current conte
xt
    CS0103: Line 171: The name 'm_Rested' does not exist in the current context
    CS0103: Line 173: The name 'm_Rested' does not exist in the current context
    CS0103: Line 173: The name 'm_Rested' does not exist in the current context
    CS0103: Line 173: The name 'm_RestedCap' does not exist in the current conte
xt
    CS0103: Line 174: The name 'm_Rested' does not exist in the current context
    CS0103: Line 175: The name 'm_Rested' does not exist in the current context
    CS0103: Line 175: The name 'm_RestedCap' does not exist in the current conte
xt
    CS0103: Line 176: The name 'm_Rested' does not exist in the current context
    CS0103: Line 177: The name 'm_Rested' does not exist in the current context
    CS0103: Line 189: The name 'm_RestedCap' does not exist in the current conte
xt
    CS0103: Line 190: The name 'm_RestedCap' does not exist in the current conte
xt
    CS0103: Line 192: The name 'm_RestedCap' does not exist in the current conte
xt
    CS0103: Line 196: The name 'm_RestedCap' does not exist in the current conte
xt
    CS0103: Line 204: The name 'm_Level' does not exist in the current context
    CS0103: Line 205: The name 'm_Level' does not exist in the current context
    CS0103: Line 207: The name 'm_Level' does not exist in the current context
    CS0103: Line 211: The name 'm_Level' does not exist in the current context
    CS0103: Line 213: The name 'm_Level' does not exist in the current context
    CS0103: Line 215: The name 'm_Level' does not exist in the current context
    CS0103: Line 219: The name 'm_Level' does not exist in the current context
    CS0103: Line 221: The name 'm_Level' does not exist in the current context
    CS0103: Line 233: The name 'm_Experience' does not exist in the current cont
ext
    CS0103: Line 234: The name 'm_Experience' does not exist in the current cont
ext
    CS0103: Line 236: The name 'm_Experience' does not exist in the current cont
ext
    CS0103: Line 240: The name 'm_Experience' does not exist in the current cont
ext
    CS0103: Line 257: The name 'm_Level' does not exist in the current context
    CS0103: Line 461: The name 'm_Level' does not exist in the current context
    CS0103: Line 463: The name 'm_Level' does not exist in the current context
    CS0103: Line 567: The name 'm_Experience' does not exist in the current cont
ext
    CS0103: Line 569: The name 'm_Experience' does not exist in the current cont
ext
    CS0103: Line 570: The name 'm_Experience' does not exist in the current cont
ext
    CS0103: Line 586: The name 'm_Experience' does not exist in the current cont
ext
    CS0103: Line 586: The name 'ComputeExperienceReq' does not exist in the curr
ent context
    CS0103: Line 586: The name 'm_Level' does not exist in the current context
    CS0103: Line 586: The name 'm_Level' does not exist in the current context
    CS0103: Line 598: The name 'm_Level' does not exist in the current context
    CS0103: Line 598: The name 'm_LevelCap' does not exist in the current contex
t
    CS0103: Line 599: The name 'm_LevelCap' does not exist in the current contex
t
    CS0103: Line 599: The name 'm_Level' does not exist in the current context
    CS0103: Line 601: The name 'm_Experience' does not exist in the current cont
ext
    CS0103: Line 602: The name 'm_Level' does not exist in the current context
    CS0103: Line 606: The name 'm_Level' does not exist in the current context
    CS0103: Line 607: The name 'm_Level' does not exist in the current context
    CS0103: Line 609: The name 'm_Experience' does not exist in the current cont
ext
    CS0103: Line 610: The name 'm_Level' does not exist in the current context
    CS0103: Line 626: The name 'm_Level' does not exist in the current context
    CS0103: Line 631: The name 'm_Rested' does not exist in the current context
    CS0103: Line 637: The name 'm_Rested' does not exist in the current context
    CS0103: Line 637: The name 'm_Rested' does not exist in the current context
    CS0120: Line 1053: An object reference is required for the nonstatic field,
method, or property 'Server.Mobiles.PlayerMobile.m_LastOnline'
    CS0103: Line 2806: The name 'm_Level' does not exist in the current context
    CS0103: Line 2807: The name 'm_LevelCap' does not exist in the current conte
xt
    CS0103: Line 2808: The name 'm_Experience' does not exist in the current con
text
    CS0103: Line 2809: The name 'm_Rested' does not exist in the current context

    CS0103: Line 2810: The name 'm_RestedCap' does not exist in the current cont
ext
    CS0103: Line 2869: The name 'm_Level' does not exist in the current context
    CS0103: Line 2870: The name 'm_LevelCap' does not exist in the current conte
xt
    CS0103: Line 2871: The name 'm_Experience' does not exist in the current con
text
    CS0103: Line 2872: The name 'm_Rested' does not exist in the current context

    CS0103: Line 2873: The name 'm_RestedCap' does not exist in the current cont
ext
Scripts: One or more scripts failed to compile or no script files were found.
 - Press return to exit, or R to try again.
 

hellalex

Sorceror
Forgot to attach the files, couldn't wrap them in Code -> made my browser crash =)
 

Attachments

  • BaseArmor.cs
    48.5 KB · Views: 28
  • BaseCreature.cs
    120.5 KB · Views: 29
  • PlayerMobile.cs
    104.7 KB · Views: 36
  • BaseWeapon.cs
    101.6 KB · Views: 27
I have finally gotten this 100% successfully working for me now, but my next thing to do is to limit the players' public moongate options based on their level (Level 1-58 is Trammel and Felucca only, 58-68 will add Ilshenar to the list, 68+ will add Malas and Tokuno to the list). I did take a look at PublicMoongate.cs and found:

Code:
public MoongateGump( Mobile mobile, Item moongate ) : base( 100, 100 )
        {
            m_Mobile = mobile;
            m_Moongate = moongate;

            PMList[] checkLists;

            if ( mobile.Player )
            {
                if ( Factions.Sigil.ExistsOn( mobile ) )
                {
                    checkLists = PMList.SigilLists;
                }
                else if ( mobile.Kills >= 5 )
                {
                    checkLists = PMList.RedLists;
                }
                else   //Add in the tests for PlayerMobile Level here?
                {
                    ClientFlags flags = mobile.NetState == null ? ClientFlags.None : mobile.NetState.Flags;           
                    bool young = mobile is PlayerMobile ? ((PlayerMobile)mobile).Young : false;
                    
                    if ( Core.SE && (flags & ClientFlags.Tokuno) != 0 )
                        checkLists = young ? PMList.SEListsYoung : PMList.SELists;
                    else if (Core.AOS && (flags & ClientFlags.Malas) != 0)
                        checkLists = young ? PMList.AOSListsYoung : PMList.AOSLists;
                    else if ((flags & ClientFlags.Ilshenar) != 0)
                        checkLists = young ? PMList.LBRListsYoung : PMList.LBRLists;
                    else
                        checkLists = young ? PMList.UORListsYoung : PMList.UORLists;
                }
            }
            else
            {
                checkLists = PMList.SELists;
            }

            m_Lists = new PMList[checkLists.Length];

            for ( int i = 0; i < m_Lists.Length; ++i )
                m_Lists[i] = checkLists[i];

            for ( int i = 0; i < m_Lists.Length; ++i )
            {
                if ( m_Lists[i].Map == mobile.Map )
                {
                    PMList temp = m_Lists[i];

                    m_Lists[i] = m_Lists[0];
                    m_Lists[0] = temp;

                    break;
                }
            }

            AddPage( 0 );

            AddBackground( 0, 0, 380, 280, 5054 );

            AddButton( 10, 210, 4005, 4007, 1, GumpButtonType.Reply, 0 );
            AddHtmlLocalized( 45, 210, 140, 25, 1011036, false, false ); // OKAY

            AddButton( 10, 235, 4005, 4007, 0, GumpButtonType.Reply, 0 );
            AddHtmlLocalized( 45, 235, 140, 25, 1011012, false, false ); // CANCEL

            AddHtmlLocalized( 5, 5, 200, 20, 1012011, false, false ); // Pick your destination:

            for ( int i = 0; i < checkLists.Length; ++i )
            {
                AddButton( 10, 35 + (i * 25), 2117, 2118, 0, GumpButtonType.Page, Array.IndexOf( m_Lists, checkLists[i] ) + 1 );
                AddHtmlLocalized( 30, 35 + (i * 25), 150, 20, checkLists[i].Number, false, false );
            }

            for ( int i = 0; i < m_Lists.Length; ++i )
                RenderPage( i, Array.IndexOf( checkLists, m_Lists[i] ) );
        }

It would seem to me that this would be the place to add in the tests for PlayerMobile level, but I don't believe it to be this simple. Can anyone provide some help on this? I can't seem to find the solution I'm looking for on the forums, so hopefully someone takes the time to read this and respond.
 
I have also been looking today for how to add a skillball to a pack whenever a player levels up with this system, but it seems that I am not at a level of understanding yet where I can add this without some advice. I did a search for this question and found a post about someone else doing it with a different leveling system, and it wasn't helpful in figuring out how to implement it with this system. Again, I'd greatly appreciate some help with this issue and the one I posted above this one.
 

Iraq-

Sorceror
You'd want to do that in either a) CheckLevelGain() or b) LevelUp( int ), both are in PlayerMobile.cs according to the OP

Example:
Code:
public void LevelUp( int count )
{
    if (m_Level + count > m_LevelCap)
        count = m_LevelCap - m_Level;
 
    m_Experience = 0;
    m_Level += count;
 
    for( int i = 0; i < count; i++ )
    {
          this.AddToBackpack( new Skillball() ); // give the player a new skillball for each level gained.
    }
}

or here (your choice)
Code:
public void CheckLevelGain( )
{
    int count = 0;
 
    ZoneXPBase xpBase = GetXPZone( true );
 
    while (m_Experience >= ComputeExperienceReq(m_Level, m_Level + (count + 1), xpBase))
    {
        count++;
    }
 
    if (count > 0)
    {
        LevelUp(count);
 
        for( int i = 0; i < count; i++ )
        {
              this.AddToBackpack( new Skillball() ); // add a new skillball to the players pack for each level gained.
        }
    }
}

also, for your 1st question regarding moongates, yes - the place to put that check would be in the gump's constructor, but the way they have it setup right now has multiple client version checks, young player status checks, etc. IF I WERE YOU... I would remove those checks and set up a basic moongate, and then build the moongate gump based on level, not based on the PMList enum value...
 
Thank you for your help; adding the item works perfectly. As for the moongate reworking, your idea doesn't sound like a bad one, I just don't want to ruin it lol!
 
I was actually thinking of using the PMLists that were already provided there, something along the lines of:
//begin pseudocode
if(playerMobile.Level < 58)
{
checklists = PMList.UORLists;
}
else if(playerMobile.Level > 57 && playerMobile.Level < 68)
{
checklists = PMList.LBRLists;
}
else
{
checklists = PMList.SELists;
}
//end pseudocode

Obviously that is very loosely written, but you get the logic behind it. It seems there is already some condition testing in place, I just don't want to break the current functionality. There are some unfamiliar things in the code there that I have not used like the ?. I also thought the : was for inheritance, but I don't quite get it's usage in the syntax for the code I listed a couple posts up from PublicMoongate.cs. I'm doing so many modifications to things that exist, I'm just borderline overwhelmed.
 

Vorspire

Knight
[syntax]string name = (pm != null) ? pm.Name : "Unknown";[/syntax]
[syntax]string name = String.Empty;
if(pm != null) { name = pm.Name; } else { name = "Unknown"; }[/syntax]

It's just a short-hand way of doing if/else statemets, it can be pretty complex too, for example when writing code for a property that has a min/max desired value:

[syntax]public int Level {
get { return m_Level = (m_Level < 0) ? 0 : (m_Level > 100) ? 100 : m_Level; }
set { m_Level = (value < 0) ? 0 : (value > 100) ? 100 : value; }
}[/syntax]
 
Top