Go Back   RunUO - Ultima Online Emulation > Developer's Corner > Programming > C#

C# C# Discussion

Reply
 
Thread Tools Display Modes
Old 04-12-2008, 04:21 PM   #1 (permalink)
Forum Expert
 
Join Date: Dec 2003
Location: Sitting in a chair fulfilling my life's goal
Age: 22
Posts: 2,565
Send a message via AIM to Killamus Send a message via MSN to Killamus
Default Function overriding

Just a quick question, is something like this at all possible? I did a bit of searching, but turned up nothing:

Code:
public class class1
{
  public virtual void A()
  {
     Console.WriteLine("A");
  }
}

public static class classO
{
public override void class1.A()
  {
     Console.WriteLine("B");
  } 
}
So, something like having a regular class (Must be a regular class) and not inheriting it, but having another class override the function?
__________________
Procrastinators unite!
Tomorrow.
Saying that Java is nice because it works on all OS's is like saying that anal sex is nice because it works on all genders.
Killamus is offline   Reply With Quote
Old 04-12-2008, 04:53 PM   #2 (permalink)
Master of the Internet
 
Join Date: Mar 2006
Location: Germany
Age: 17
Posts: 14,152
Send a message via AIM to Suil Ban Send a message via MSN to Suil Ban
Default

Quote:
Originally Posted by Killamus View Post
Just a quick question, is something like this at all possible? I did a bit of searching, but turned up nothing:

Code:
public class class1
{
  public virtual void A()
  {
     Console.WriteLine("A");
  }
}

public static class classO
{
public override void class1.A()
  {
     Console.WriteLine("B");
  } 
}
So, something like having a regular class (Must be a regular class) and not inheriting it, but having another class override the function?
I'm not sure if it's possible, but I'm not sure I see a reason for doing this.
__________________
the runuo community has lost sight
Suil Ban is offline   Reply With Quote
Old 04-12-2008, 06:34 PM   #3 (permalink)
Forum Expert
 
Join Date: Dec 2003
Location: Sitting in a chair fulfilling my life's goal
Age: 22
Posts: 2,565
Send a message via AIM to Killamus Send a message via MSN to Killamus
Default

Code:
using System;
using Server.Mobiles;
using Server.Items:

namespace Server.Mobiles
{
public static class PlayerOverride
{
public override void PlayerMobile.OnResurrection()
{
//Overriden! No PM edits.
}
}
}
No more playermobile edits :]
__________________
Procrastinators unite!
Tomorrow.
Saying that Java is nice because it works on all OS's is like saying that anal sex is nice because it works on all genders.
Killamus is offline   Reply With Quote
Old 04-12-2008, 06:36 PM   #4 (permalink)
RunUO Forum Moderator
 
daat99's Avatar
 
Join Date: Dec 2004
Location: Israel
Age: 27
Posts: 8,163
Send a message via ICQ to daat99 Send a message via AIM to daat99
Default

Quote:
Originally Posted by Killamus View Post
Just a quick question, is something like this at all possible? I did a bit of searching, but turned up nothing:

Code:
public class class1
{
  public virtual void A()
  {
     Console.WriteLine("A");
  }
}

public static class classO
{
public override void class1.A()
  {
     Console.WriteLine("B");
  } 
}
So, something like having a regular class (Must be a regular class) and not inheriting it, but having another class override the function?
In order to "override" a method you must inherit the original class.
Personally I understand the motive of avoiding changes to distro classes but in my opinion, this is an example for when you should modify it.

If you want an easy way you can always do:
Code:
public class PlayerMobile
{
  public virtual type function(parameters)
  {
    if (MyStaticClass.MyStaticMethod(my_parameters)) return type;
    //distro code
  }
}
This way you need to add only one line to player mobile.
__________________
I always try to help
Sometimes, I don't know how....

My Web Page
Forum Rules
-------------------------------------------------------------
Extensive OWLTR System | Token System | World Teleporters
-------------------------------------------------------------

Last edited by daat99; 04-12-2008 at 06:41 PM.
daat99 is offline   Reply With Quote
Old 04-13-2008, 11:34 AM   #5 (permalink)
Forum Expert
 
Join Date: Oct 2003
Location: Calhoun, Ga
Age: 43
Posts: 985
Send a message via AIM to roadmaster
Default

If your not wanting to make edits to the Distro PlayerMobile you could use a custom derived playermobile.

this is an old one i used to use, this is just an example for you:

Code:
using System;
using System.Collections;
using Server;
using Server.Gumps;
using Server.Items;
using Server.Network;
using Server.Accounting; 
 
namespace Server.Mobiles
{
	public class MyPlayerMobile : PlayerMobile
	{
		private Item m_InternalMount;
		
		private bool m_OrcFriend = false;
    	private bool m_DrowFriend = false;
		
		private RaceType m_Race = RaceType.None;
		
		public int m_StrCap = 150;
		public int m_DexCap = 150;
		public int m_IntCap = 150;
		
    public enum RaceType
    {
      None, Human, Dwarf, Drow, Centaur, Elf, Orc, Deamon, Vampire, Undead 
    }
    
    public Item InternalMount
	{
		get{ return m_InternalMount; }
		set{ m_InternalMount = value; }
	}

    [CommandProperty( AccessLevel.GameMaster )]
    public bool OrcFriend
    {
      get{ return m_OrcFriend; }
      set{ m_OrcFriend = value; }
    }

    [CommandProperty( AccessLevel.GameMaster )]
    public bool DrowFriend
    {
      get{ return m_DrowFriend; }
      set{ m_DrowFriend = value; }
    }

   [CommandProperty( AccessLevel.GameMaster )]
    public RaceType Race
    {
      get{ return m_Race; }
      set{ m_Race = value; InvalidateProperties(); }
    }

		[CommandProperty( AccessLevel.GameMaster )] 
		public int StrCap // Maximum value of STR stat
		{
			get {return m_StrCap;}
			set {m_StrCap = value;}
		}

		[CommandProperty( AccessLevel.GameMaster )] 
		public int IntCap // Maximum value of INT stat
		{
			get {return m_IntCap;}
			set {m_IntCap = value;}
		}

		[CommandProperty( AccessLevel.GameMaster )] 
		public int DexCap // Maximum value of DEX stat
		{
			get {return m_DexCap;}
			set {m_DexCap = value;}
		}

    new public static void Initialize()
		{
			EventSink.Login += new LoginEventHandler( OnLogin );
		}

 		private static void OnLogin( LoginEventArgs e )
		{
			if ( e.Mobile is MyPlayerMobile )
			{
				MyPlayerMobile m = (MyPlayerMobile)e.Mobile;
				
				MyPlayerMobile.MaxPlayerResistance = 85;

				if(m.Race == RaceType.None)
				{
					m.CloseGump( typeof( RaceGump ) );
					m.SendGump( new RaceGump( m, RacePage.Info) );
				}
			}
		}

/*
		public override void AddNameProperties( ObjectPropertyList list )
		{
			if(this.Race != RaceType.None)
			list.Add( 1042971, "{0}", m_Race==RaceType.None ? " " : m_Race.ToString() );

			base.AddNameProperties( list );
		}
*/
		public override void OnDeath( Container c )
		{
			if ( m_InternalMount != null )
			{
				m_InternalMount.Delete();
				m_InternalMount = null;
			}
			base.OnDeath( c );
		}

		public override void OnAfterResurrect()
		{
			RestoreBody();
			base.OnAfterResurrect();
		}
		
		public void CreateInternalMount()
		{
			if ( m_InternalMount == null )
			{
				m_InternalMount = new Item( 0x3EAA );
				m_InternalMount.Layer = Layer.Mount;
				m_InternalMount.Movable = false;
				m_InternalMount.Visible = false;
				AddItem( m_InternalMount );
			}
		}

		
		public void RestoreBody()
		{
			if(this.Female)
				this.BodyValue = 401;// if error change back to BodyMod instead of BodyValue
			else
				this.BodyValue = 400;// if error change back to BodyMod instead of BodyValue
			
			RaceType race = this.Race;

			switch( race )
			{
				case RaceType.Centaur:
				{
					this.BodyMod = 101;
					CreateInternalMount();
					break;
				}
				//case RaceType.Ogre: this.BodyMod = 1; break;
				case RaceType.Orc: 
				{
					this.BodyMod = 7;
					CreateInternalMount();
					break;
				}
				case RaceType.Deamon: 
				{
					this.BodyMod = 43;
					CreateInternalMount();
					break;
				}
			}
		}
/*
		public override TimeSpan ComputeMovementSpeed( Direction dir )
		{
			if ( (dir & Direction.Mask) != (this.Direction & Direction.Mask) )
				return TimeSpan.Zero;

			bool running = ( (dir & Direction.Running) != 0 );

			bool onHorse = ( this.Mount != null );

			if ( onHorse )
			{
				if(this.Race == RaceType.Centaur)
					return ( running ? TimeSpan.FromSeconds( 0.1 ) : TimeSpan.FromSeconds( 0.2 ) );
				else if(this.Race == RaceType.Deamon)
					return ( running ? TimeSpan.FromSeconds( 0.1 ) : TimeSpan.FromSeconds( 0.2 ) );
				else if(this.Race == RaceType.Orc)
					return ( running ? TimeSpan.FromSeconds( 0.3 ) : TimeSpan.FromSeconds( 0.6 ) );
				else
					return ( running ? TimeSpan.FromSeconds( 0.2 ) : TimeSpan.FromSeconds( 0.2 ) );
			}
			else
				return ( running ? TimeSpan.FromSeconds( 0.9 ) : TimeSpan.FromSeconds( 1.4 ) ); //changed to assist centaur and orc speeds: turin
			//return ( running ? TimeSpan.FromSeconds( 0.15 ) : TimeSpan.FromSeconds( 0.3 ) );
		}
*/
		//the default constructor called at creation
		public MyPlayerMobile()
		{
			try
			{
				m_Race = this.Race;
			}
			catch(Exception e)
			{
				Console.WriteLine(e);
			}
		}
 
		//the serial constructor called at world load
		public MyPlayerMobile( Serial s ) : base( s )
		{
		}
            
		//called at every world save
		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
            
			writer.Write( (int) 3 ); 
			
			writer.Write( m_InternalMount );
 
      		writer.Write( (bool)m_OrcFriend );
			writer.Write( (bool)m_DrowFriend );
			
			writer.Write( (int)m_Race );
 
			writer.Write( (int) m_StrCap );
			writer.Write( (int) m_DexCap );
			writer.Write( (int) m_IntCap ); 
		}
 
		//called by serial constructor at world load
		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
 
			int version = reader.ReadInt();
 
			switch ( version )
			{
				case 3:
				{
					m_InternalMount = reader.ReadItem();
					goto case 2;
				}
				case 2:
				{
         			m_OrcFriend = (bool)reader.ReadBool();
          			m_DrowFriend = (bool)reader.ReadBool();
					goto case 1;
				}
				case 1:
				{
					m_Race = (RaceType)reader.ReadInt();
					goto case 0;
				}
				case 0: 
				{
					m_StrCap = reader.ReadInt();
					m_DexCap = reader.ReadInt();
					m_IntCap = reader.ReadInt();
					
					break;
				}
			}
			RestoreBody();
		}
/*
		public override void Resurrect()
		{
//			bool wasAlive = this.Alive;
// Races stuff
			RaceType Race = this.Race;
// EO Races stuff
			base.Resurrect();
		}
*/
	}
}
of course you'd still have to set it up in CharacterCreation.cs to use the Custom PlayerMobile instead of the Distro when creating a new character.

and of course whether or not you would want to use a Custom would depend on what your trying to do.
__________________
If you are not a Moderator, don't try to moderate.
roadmaster is offline   Reply With Quote
Old 04-13-2008, 04:24 PM   #6 (permalink)
RunUO Forum Moderator
 
daat99's Avatar
 
Join Date: Dec 2004
Location: Israel
Age: 27
Posts: 8,163
Send a message via ICQ to daat99 Send a message via AIM to daat99
Default

Quote:
Originally Posted by roadmaster View Post
If your not wanting to make edits to the Distro PlayerMobile you could use a custom derived playermobile.
Based on killamus track record, the reason he doesn't want to have any playermobile edits is because he want to release a script without them.

If that's the case then making a derived class will be a bit problematic.

Personally speaking, I never liked the idea of "derived class" just to avoid editing the original class, but that's just simple me

Thanks for your input though.
__________________
I always try to help
Sometimes, I don't know how....

My Web Page
Forum Rules
-------------------------------------------------------------
Extensive OWLTR System | Token System | World Teleporters
-------------------------------------------------------------
daat99 is offline   Reply With Quote
Old 04-13-2008, 05:53 PM   #7 (permalink)
Forum Expert
 
Greystar's Avatar
 
Join Date: Mar 2004
Location: NorthCentral IL, USA
Age: 34
Posts: 3,848
Default

Quote:
Originally Posted by daat99 View Post
Based on killamus track record, the reason he doesn't want to have any playermobile edits is because he want to release a script without them.

If that's the case then making a derived class will be a bit problematic.

Personally speaking, I never liked the idea of "derived class" just to avoid editing the original class, but that's just simple me

Thanks for your input though.
I'm not big on the derived thing either, however at one point I had made a "baseMobile" that inherited from Mobile then both PlayerMobile and BaseCreature inherited from it, that way I could add things to that, that affected both NPCs and PCs, however now that I'm doing core compiling on my own I just modify Mobile in the core and recompile.
__________________
Quote:
(\__/)
(='.'=)This is Bunny. Copy and paste bunny into your
(")_(")signature to help him gain world domination.
Killable Guards (GS Version)
Just a Simple Staff Tool
You can leave me messages.
Ernest Gary Gygax - Quote "I would like the world to remember me as the guy who really enjoyed playing games and sharing his knowledge and his fun pastimes with everybody else."
Greystar is offline   Reply With Quote
Old 04-13-2008, 09:20 PM   #8 (permalink)
Forum Expert
 
Join Date: Dec 2003
Location: Sitting in a chair fulfilling my life's goal
Age: 22
Posts: 2,565
Send a message via AIM to Killamus Send a message via MSN to Killamus
Default

Quote:
Originally Posted by daat99 View Post
Based on killamus track record, the reason he doesn't want to have any playermobile edits is because he want to release a script without them.
I have a track record? Now I'm scared
anyways, Thanks for the help. That's helped a lot, plus your posts in the whole static class thread.
Don't worry, you won't see this script released for a while, so be prepared to answer many more questions I can't find answers to in the MSDN library.
__________________
Procrastinators unite!
Tomorrow.
Saying that Java is nice because it works on all OS's is like saying that anal sex is nice because it works on all genders.
Killamus is offline   Reply With Quote
Old 04-14-2008, 04:22 PM   #9 (permalink)
RunUO Forum Moderator
 
daat99's Avatar
 
Join Date: Dec 2004
Location: Israel
Age: 27
Posts: 8,163
Send a message via ICQ to daat99 Send a message via AIM to daat99
Default

Quote:
Originally Posted by Killamus View Post
I have a track record? Now I'm scared
anyways, Thanks for the help. That's helped a lot, plus your posts in the whole static class thread.
Don't worry, you won't see this script released for a while, so be prepared to answer many more questions I can't find answers to in the MSDN library.
Looks like I was right, you do work on another script for a release

Good luck with it and if I'll have thoughts to share on your questions I'll let you know.
__________________
I always try to help
Sometimes, I don't know how....

My Web Page
Forum Rules
-------------------------------------------------------------
Extensive OWLTR System | Token System | World Teleporters
-------------------------------------------------------------
daat99 is offline   Reply With Quote
Old 04-14-2008, 05:39 PM   #10 (permalink)
Forum Expert
 
mordero's Avatar
 
Join Date: Nov 2003
Location: Illinois, USA
Age: 21
Posts: 2,909
Default

I havent tried this at all, so I dont know how hard it would be to implement, but you could always try this:

Type: System.Reflection.Emit.MethodRental

It uses reflection to replace a method in an object.
mordero is offline   Reply With Quote
Old 04-14-2008, 10:03 PM   #11 (permalink)
Forum Expert
 
Join Date: Dec 2003
Location: Sitting in a chair fulfilling my life's goal
Age: 22
Posts: 2,565
Send a message via AIM to Killamus Send a message via MSN to Killamus
Default

Quote:
Originally Posted by mordero View Post
I havent tried this at all, so I dont know how hard it would be to implement, but you could always try this:

Type: System.Reflection.Emit.MethodRental

It uses reflection to replace a method in an object.
*twitch* *twitch* *Brain explodes*

Ouch.
It looks simple enough, but I'm curious as to how I'd find the values for some of the requirements (Like the size of the method in bytes). Is there an int for that, or is it copy/paste into a text file?

Also, how exactly does one do a pointer in C#? I remember learning about it in C++, but I haven't seen it in C# yet.
__________________
Procrastinators unite!
Tomorrow.
Saying that Java is nice because it works on all OS's is like saying that anal sex is nice because it works on all genders.
Killamus is offline   Reply With Quote
Old 04-15-2008, 02:34 AM   #12 (permalink)
Master of the Internet
 
Join Date: Mar 2006
Location: Germany
Age: 17
Posts: 14,152
Send a message via AIM to Suil Ban Send a message via MSN to Suil Ban
Default

Quote:
Originally Posted by Killamus View Post
Also, how exactly does one do a pointer in C#? I remember learning about it in C++, but I haven't seen it in C# yet.
Code:
unsafe
{
	int* p;
}
__________________
the runuo community has lost sight
Suil Ban is offline   Reply With Quote
Old 04-15-2008, 01:49 PM   #13 (permalink)
Forum Expert
 
Join Date: Dec 2003
Location: Sitting in a chair fulfilling my life's goal
Age: 22
Posts: 2,565
Send a message via AIM to Killamus Send a message via MSN to Killamus
Default

So a pointer to a function would be something like
Code:
public virtual void* MethodName(params)
{
Methods();
return;
}
Also, why is it unsafe to do pointers in C#?
__________________
Procrastinators unite!
Tomorrow.
Saying that Java is nice because it works on all OS's is like saying that anal sex is nice because it works on all genders.
Killamus is offline   Reply With Quote
Old 04-15-2008, 03:00 PM   #14 (permalink)
Master of the Internet
 
Join Date: Mar 2006
Location: Germany
Age: 17
Posts: 14,152
Send a message via AIM to Suil Ban Send a message via MSN to Suil Ban
Default

One of .NET's goals is taking care of garbage collection and memory management for you. When pointers and other user memory manipulation come into play, the unsafe bit is no longer 'managed code'.
__________________
the runuo community has lost sight
Suil Ban is offline   Reply With Quote
Old 04-15-2008, 05:09 PM   #15 (permalink)
Forum Expert
 
Join Date: Dec 2003
Location: Sitting in a chair fulfilling my life's goal
Age: 22
Posts: 2,565
Send a message via AIM to Killamus Send a message via MSN to Killamus
Default

Ok. So, that is how you'd do a pointer method in C#? So, if I wanted to write a pointer to a playermobile function, I'd have to do something like this:

Code:
public virtual void* OnResurrection(PlayerMobile player)
{
player.OnResurrection();
}
and that would be a pointer to the PlayerMobile OnResurrection function? Or would something like this have to be in the PlayerMobile class?

Also: lol@Microsoft still trying to tell programmers what to do... At least this is easy enough to get past.
__________________
Procrastinators unite!
Tomorrow.
Saying that Java is nice because it works on all OS's is like saying that anal sex is nice because it works on all genders.
Killamus is offline   Reply With Quote
Old 04-15-2008, 07:16 PM   #16 (permalink)
Forum Expert
 
mordero's Avatar
 
Join Date: Nov 2003
Location: Illinois, USA
Age: 21
Posts: 2,909
Default

Umm the whole point isnt to tell programmers what to do, but make it easier for them. Its much easier for a programmer to ignore the whole memory thing and let it happen automatically.
mordero is offline   Reply With Quote
Old 04-16-2008, 12:24 AM   #17 (permalink)
Forum Expert
 
Join Date: Dec 2003
Location: Sitting in a chair fulfilling my life's goal
Age: 22
Posts: 2,565
Send a message via AIM to Killamus Send a message via MSN to Killamus
Default

Quote:
Originally Posted by mordero View Post
Umm the whole point isnt to tell programmers what to do, but make it easier for them. Its much easier for a programmer to ignore the whole memory thing and let it happen automatically.
I know, I just think it's funny.
I'm also rather greatful for it, as I suck at remembering what to delete and what not to delete.
Anyways, moot point.
But, while talking to my C++ instructor, it seems that everything in C# is a pointer, and managed that way. To me, there are very few differences between (ex) a regular integer in C# and a pointer integer in C++. Anyone care to explain?
__________________
Procrastinators unite!
Tomorrow.
Saying that Java is nice because it works on all OS's is like saying that anal sex is nice because it works on all genders.
Killamus is offline   Reply With Quote
Old 04-16-2008, 11:50 AM   #18 (permalink)
Master of the Internet
 
Join Date: Mar 2006
Location: Germany
Age: 17
Posts: 14,152
Send a message via AIM to Suil Ban Send a message via MSN to Suil Ban
Default

Memory all works the same on the basic level. C# just hides it from you.
__________________
the runuo community has lost sight
Suil Ban is offline   Reply With Quote
Old 04-16-2008, 03:04 PM   #19 (permalink)
ConnectUO Creator
 
Jeff's Avatar
 
Join Date: Jan 2004
Location: In your mom
Age: 27
Posts: 4,743
Default

A pointer to a method in C# is a bitch, but it ends up being a IntPtr in the end if you keep everything safe. YOu have to use tons of MarshalAs bullshit. TBH its not worth it.
__________________
Jeff Boulanger
ConnectUO - Core Developer

Want to help make ConnectUO better? Click here to submit your ideas/requests
Use your talent to compete against other community members in RunUO hosted coding competitions

If you know XNA (even if its just a little) or are a good artist(2d or 3d) and are interested in making games for a hobby send me a pm or drop by #xna in irc.runuo.com. I'm looking to put together a small game development team.


Please do not pm me for support. If you are having issues please post in the appropriate forum. Thanks for your continued support of both ConnectUO and RunUO
Jeff is offline   Reply With Quote
Old 04-16-2008, 03:41 PM   #20 (permalink)
RunUO Forum Moderator
 
daat99's Avatar
 
Join Date: Dec 2004
Location: Israel
Age: 27
Posts: 8,163
Send a message via ICQ to daat99 Send a message via AIM to daat99
Default

Quote:
Originally Posted by Jeff View Post
A pointer to a method in C# is a bitch, but it ends up being a IntPtr in the end if you keep everything safe. YOu have to use tons of MarshalAs bullshit. TBH its not worth it.
I totally agree

In any case c# integer is basically an object that knows basic integer math while c++ pointer to integer is only a memory address for a memory block that represent an integer number.
For the average user there's no difference between c# integer and c++ normal integer (due to the fact that most people doesn't use the integer class methods).

Keep in mind that every object in c# is basically a pointer to a memory block that contains that objects internal data.

Like people said before me, c# just hides all the pointer headache from the programmer while c++ let the programmer bang his head against the table (and maybe jump off the roof) in order to use pointers without nasty hard to detect memory leaks.
__________________
I always try to help
Sometimes, I don't know how....

My Web Page
Forum Rules
-------------------------------------------------------------
Extensive OWLTR System | Token System | World Teleporters
-------------------------------------------------------------
daat99 is offline   Reply With Quote
Reply

Bookmarks


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools