Go Back   RunUO - Ultima Online Emulation > RunUO > Script Support

Script Support Get support for modifying RunUO Scripts, or writing your own!

Reply
 
Thread Tools Display Modes
Old 07-03-2007, 03:03 PM   #1 (permalink)
Forum Expert
 
Lokai's Avatar
 
Join Date: Aug 2003
Location: Bergen, NY (Rochester)
Age: 41
Posts: 1,414
Send a message via ICQ to Lokai Send a message via MSN to Lokai Send a message via Yahoo to Lokai
Default C# Scripting: Objects, Classes, Constructors, and Inheritance

Objects, Classes, Constructors, and Inheritance

Objects:

An object is the base class of all classes.

Think of it this way: every Item, Mobile, Integer, String, Packet, Socket, etc. is an object. As such, each of these 'Inherits' certain things which define how they can be dealt with in code, how they interact with eachother, and how we get information into or out of them, from their ultimate Parent type -- object.

What does an object look like?

An object is defined by its characteristics, just like food, or government, or a person is defined by their characteristics. What defines every object are the properties it keeps, the methods we use to access those properties, and the methods that define what the object can do, think, say, write, or read. For example: PlayerMobile is a class derived from the Mobile class, which is derived from the object class. So, PlayerMobile is an object, which inherits some things from object, more things from Mobile, and finally has even more characteristics not found in either object or Mobile, which define who or what it is.

Class:

The class is the definition of a new type of object.

A class is always derived from a Parent class of some type, and can sometimes have Child classes which are derived from it. We will call a Parent class a "Superclass", and a Child class a "subclass". For example, as stated earlier, every class derives from the ultimate superclass - object, and Item, Mobile, etc. are considered subclasses. PlayerMobile is a subclass of Mobile, BaseContainer is a subclass of Item, and Backpack is a subclass of BaseContainer. Every subclass "inherits" all of the properties, attributes, methods, or characteristics, of its Parent or Parents (its superclasses.) These characteristics can be overriden in the subclass, but if not otherwise specified, they will behave like their superclass counterparts.

Property:

Properties are the bits and pieces that describe the basic parts of a class. Properties have a datatype, a variable name, and a value. They can also have an accessibility defined. If not specified, the accessibility is Private. It can also be Public, or Protected. Properties are defined, and usually initialized in the beginning of the definition of a class, and serve to create a "description" of the class. For example:

Code:
 
private int Size = 4;
int Color = 302;
string Name = "TestClass";
Method:

A method is a means of interacting with the class.

Methods also have accessibility, datatype (called "return type") and name. In addition, they can have zero or more parameters passed to them which help control what happens when the method is "called" from the outside. "Calling" a method simply means using the name of the method, and giving it any parameters it is expecting to receive. For example, this method is called "GetName" and it accepts no parameters, and it returns a datatype 'String' back to the program that called it:

Code:
public string GetName()
{
 return Name;
}
Here is what this method might look like inside a class:

Code:
 
public class TestClass
{
 private string Name = "TestClass";
 public string GetName()
 {
  return Name;
 }
}
And here is what the code of a program might look like that calls this method:

Code:
 
string MyString;
MyString = TestClass.GetName();
Console.WriteLine(MyString);
That code should output the word "TestClass" to the Console.
If no return type is specified, the word 'void' must be used in its place. This indicates that the method will not return any values to the program calling it, but will instead simply perform whatever operations it needs to perform on its own.

Constructors:

A constructor is the method of initializing an instance of a class.

A constructor is called when the 'new' keyword is used or when a System Reflection is used to instantiate an object.

The constructor resembles a method, but has no return type, and the name of the method is always the same as the class itself. Every constructor of every class other than the 'object' class either explicitly or implicitly calls a base class, or another constructor from the same class.

There are two forms of constructor initializer - one which calls a base class constructor and one which calls another constructor from this class, using the this (...) syntax. There must always be a "chain" of constructors which runs all the way up the class hierarchy. Every class in the hierarchy will have a constructor invoked, although some of those constructors may not explicitly appear in the code. The parameters (if any) within the brackets of base(...) or this(...) are passed as the parameters to the invoked constructors. They can be the parameters given in the constructor declaration, but don't have to be. Here's an example:

Code:
 
public class MyTestClass
{
    public MyTestClass (int x) : base() // Invokes the parameterless constructor in object ( the " : base()" can be omitted.)
    {
        Console.WriteLine ("In the base class constructor taking an int, which is " + x);
    }
}
public class MyDerivedTestClass : MyTestClass
{
    public MyDerivedTestClass () : this (10) // Invokes the MyDerivedTestClass constructor taking an int
    {
        Console.WriteLine ("Received no parameters, and passed 10 to this class.");
    }
    public MyDerivedTestClass (int y) : base (y * 5) // Invokes the MyTestClass constructor, gets an int, and passes an int
    {
        Console.WriteLine ("Received {0}, and passed {1} to the base class.", y, y * 5);
    }
              
    public MyDerivedTestClass (string x) : base (50) // Invokes the MyTestClass constructor, gets a string, and passes an int
    {
        Console.WriteLine ("Received a string, and passed 50 to the base class.");
    }
}
With the above code, a bit of code saying new MyDerivedTestClass(); would invoke the MyDerivedTestClass parameterless constructor, which would in turn invoke the MyDerivedTestClass constructor which takes an int parameter (with 10 as that parameter value), which would in turn invoke the MyTestClass constructor which takes an int parameter (with 10 * 5 as that parameter value).

Not all constructors in the hierarchy need to be invoked, as demonstrated above - the constructor taking a string parameter is not invoked at all when you do new MyDerivedTestClass() - but as stated earlier, there must be at least one constructor invoked in each class in the hierarchy.
Lokai is offline   Reply With Quote
Old 07-09-2007, 06:54 PM   #2 (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

For a very good post you get +Sticky

**thanks to aventae for bringing this thread to my attention**
__________________
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 08-19-2007, 10:45 PM   #3 (permalink)
Newbie
 
Join Date: Mar 2005
Age: 22
Posts: 54
Exclamation

Quote:
Originally Posted by Lokai View Post
Objects, Classes, Constructors, and Inheritance

Objects:

Property:

Properties are the bits and pieces that describe the basic parts of a class. Properties have a datatype, a variable name, and a value. They can also have an accessibility defined. If not specified, the accessibility is Private. It can also be Public, or Protected. Properties are defined, and usually initialized in the beginning of the definition of a class, and serve to create a "description" of the class. For example:

Code:
 
private int Size = 4;
int Color = 302;
string Name = "TestClass";
You are probably talking about Fields of the class.
Properties are actually big different from the fields 8)
Naytron is offline   Reply With Quote
Old 01-23-2008, 07:07 AM   #4 (permalink)
Forum Expert
 
Join Date: Jan 2008
Posts: 286
Send a message via AIM to Kitchen_ Send a message via MSN to Kitchen_
Default

Quote:
Originally Posted by Lokai View Post
Property:

Properties are the bits and pieces that describe the basic parts of a class. Properties have a datatype, a variable name, and a value. They can also have an accessibility defined. If not specified, the accessibility is Private. It can also be Public, or Protected. Properties are defined, and usually initialized in the beginning of the definition of a class, and serve to create a "description" of the class. For example:

Code:
 
private int Size = 4;
int Color = 302;
string Name = "TestClass";
Fields: Fields (C# Programming Guide)

Properties: Properties (C# Programming Guide)

Kitchen_ is offline   Reply With Quote
Old 04-28-2008, 11:08 AM   #5 (permalink)
Forum Expert
 
Lokai's Avatar
 
Join Date: Aug 2003
Location: Bergen, NY (Rochester)
Age: 41
Posts: 1,414
Send a message via ICQ to Lokai Send a message via MSN to Lokai Send a message via Yahoo to Lokai
Default C# Scripting: Breaking down an example script

C# Scripting: breaking down some of the basics using a simple script as an example

You may have trouble reading the script here, so it is also attached below.

PHP Code:
/* ~using~
 * 
 * This section says which namespaces we want to include (or 'use') when scripting this item.
    when we add something here, it allows us to shorten the convention we use to refer to 
    things elsewhere in the script. For example, we use the class 'ArmorMaterialType' in
    this script. But, that class is not defined in this script, so how does the program know
    what it is? It assumes that we mean Server.Items.ArmorMaterialType, since we are using
    Server.Items, we can shorten that to just the last part. See the 'namespace' description
    below for more about namespaces.
 */
using System;
using Server.Items;

/* ~namespace~
 * 
 * The 'namespace' line tells the program where we want to 'store' the item, or how it is
    categorized. If you are making an Item, chances are you will place it in here. If you 
    are making a new type of Mobile, like a monster or vendor, you would probably place it
    in the Server.Mobiles namespace. Think of it like a container where they are all stored.
 */
namespace Server.Items
{
    
/* ~attribute~
     * 
     * Attributes are a complicated subject. The 'FlipableAttribute' is needed so that we can have
        both a South-facing and an East-facing item. The hex numbers here (0x13be, 0x13c3) are 
        the ItemIDs that the item will use for South or East-facing. You will often have this
        attribute for Armor, Weapons, Furniture, etc.
     */
    
[FlipableAttribute(0x13be0x13c3)]
    public class 
MyChainLegs BaseArmor /* This is the class identifier. Here we give the name of
                                            our new class, and we also indicate what class our item
                                            is 'derived' from. We derive from another type so that
                                            our item can 'inherit' characteristics from that type.
                                            Basically, our item is a 'BaseArmor' with some modifications
                                            or 'overrides' as we call them.
                                          */
    
{
        
/* ~override~
         * 
         * These are the overrides. All of these are defined in BaseArmor, which is the base class for
            our item. We can override anything that is defined as either override or virtual in the
            previous class. Because these have only 'get' statements, we know that these are what are
            known as 'read-only' values. We can get the value, but we may NOT 'set' the value.
         */
        
public override int BasePhysicalResistance get { return 4; } }
        public 
override int BaseFireResistance get { return 4; } }
        public 
override int BaseColdResistance get { return 4; } }
        public 
override int BasePoisonResistance get { return 1; } }
        public 
override int BaseEnergyResistance get { return 2; } }

        public 
override int InitMinHits get { return 45; } }
        public 
override int InitMaxHits get { return 60; } }

        public 
override int AosStrReq get { return 60; } }
        public 
override int OldStrReq get { return 20; } }

        public 
override int OldDexBonus get { return -3; } }

        public 
override int ArmorBase get { return 28; } }

        public 
override ArmorMaterialType MaterialType get { return ArmorMaterialType.Chainmail; } }

        
/* ~Constructable~ 
         * 
         * This is another attribute. This particular attribute lets the compiler know
            that this item can be constructed. To simplify, we can use the [add command
            in-game, and create the item. */
        
[Constructable]
        public 
MyChainLegs() /* This is the primary constructor for this class.*/
            
base(0x13BE/* Here we specify what we are passing to the base class. Since this is
                                a type of 'BaseArmor', the BaseArmor constructor requires that we
                                include an integer value specifying the default ItemID of the item.
                                We 'pass' the ItemID 0x13BE, which is the ID for Chain Legs.*/
        
{
            
/* ~initializing the constructor~
             * 
             * Inside the constructor, we can 'initialize' values which are not read-only. In this
                case, we chose to set the weight of the item to '7'. This value would override any
                value defined in the base class, similar to the 'override' values above.*/
            
Weight 7.0;
        }

        
/* ~overloading~
         * 
         * When you have 2 or more constructors, we call it 'overloading'. The most important rule to
            overloading is that each constructor must have a different set of values passed to it
            or you will get a compiler error. This is because it would have no way of knowing which
            constructor was being called if both of them looked the same. So, in this constructor, we
            are passing a 'Serial' type, whereas in the base constructor above, we pass nothing.
         */
        
public MyChainLegs(Serial serial)
            : 
base(serial)
        {
        }

        
/* ~Serialize~
         * 
         * Whenever the Server does a save, all items are automatically Serialized, meaning their
            values are saved to a binary storage file called a GenericWriter. We do this, so that
            when the Server is loaded, every item can be properly loaded in the state it was in
            the last time it was saved.
         */
        
public override void Serialize(GenericWriter writer)
        {
            
/*NOTE: It is critical when building the Serialize/Deserialize methods, you keep the
                Serialized items in the same order in both methods. Think of this like placing items
                in a row on a bookshelf. The first item you place when you Serialize needs to be the 
                first item you will be picking up when you Deserialize.
             */
            
base.Serialize(writer); /*Here we call the Serialize method of the base class. Note, that
                                        we pass the same GenericWriter so that it can continue to use
                                        it to save whatever variables are stored in the base class.
                                     */
            
writer.Write((int)0); /* ~explicit cast~
                                   * 
                                   * An explicit cast is when we use parentheses '()' around a datatype
                                        to indicate that we want the program to treat whatever comes
                                        after the parentheses as that datatype. If the value is normally
                                        viewed as another type, the program will convert it to the type
                                        that we specified.
                                   */
        
}

        
/* ~Deserialize~
         * 
         * Whenever the Server starts up, every item can be properly loaded in the state it was in
            the last time it was saved, if everything significant about the item was properly
            Serialized in the previous step.
         */
        
public override void Deserialize(GenericReader reader)
        {
            
base.Deserialize(reader);
            
int version reader.ReadInt();
        }
    }

Attached Files
File Type: cs LearningScript.cs (7.4 KB, 20 views)
Lokai is offline   Reply With Quote
Old 05-18-2008, 02:10 AM   #6 (permalink)
Newbie
 
Join Date: Oct 2004
Age: 24
Posts: 49
Send a message via MSN to Deegs Send a message via Yahoo to Deegs
Talking

You have no idea how much this post is helping me at the moment. I am keeping that chainlegs script open while looking at other scripts to actually start to understand them better.


I do have a question regarding attributes i.e.

[FlipableAttribute(0x13be, 0x13c3)]
[Constructable]

Where exactly are those contained, and how do you know when you can use what attributes? Sort of like, how the overrides in that script, are derived from BaseArmor. Not sure if im making alot of sense.

Anyway, great post, I hope you will add some more, I for one am learning quite a bit from it.

+rep
__________________
- Deegs aka Citriz - Project Citriz
Deegs is offline   Reply With Quote
Old 05-18-2008, 09:30 AM   #7 (permalink)
Forum Expert
 
Lokai's Avatar
 
Join Date: Aug 2003
Location: Bergen, NY (Rochester)
Age: 41
Posts: 1,414
Send a message via ICQ to Lokai Send a message via MSN to Lokai Send a message via Yahoo to Lokai
Default

Quote:
Originally Posted by Deegs View Post
You have no idea how much this post is helping me at the moment. I am keeping that chainlegs script open while looking at other scripts to actually start to understand them better.


I do have a question regarding attributes i.e.

[FlipableAttribute(0x13be, 0x13c3)]
[Constructable]

Where exactly are those contained, and how do you know when you can use what attributes? Sort of like, how the overrides in that script, are derived from BaseArmor. Not sure if im making alot of sense.

Anyway, great post, I hope you will add some more, I for one am learning quite a bit from it.

+rep
For something like FlippableAttribute, you need InsideUO, or another tool that lets you see the images used. Basically, if the image of the item is facing one way, and there is another image facing another way, then FlippableAttribute lets you use the [flip command in game to change the facing of the item. This is especially important for furniture items, signs, and multis.

I STRONGLY recommend downloading Microsoft Visual C# Express Edition 2008. It's free, and can be found here:

Downloads

With it, you can right-click on a class name, its base class or any object, and navigate to the constructor or definition of that object. This will help you greatly with trying to figure out where a particular class is derived, what it's methods are, etc.
Lokai is offline   Reply With Quote
Old 05-18-2008, 10:30 AM   #8 (permalink)
Forum Expert
 
Vorspire's Avatar
 
Join Date: Jan 2005
Location: Newcastle, United Kingdom
Age: 21
Posts: 2,294
Send a message via ICQ to Vorspire Send a message via MSN to Vorspire Send a message via Skype™ to Vorspire
Default

Quote:
Originally Posted by Lokai View Post
...A class is always derived from a Parent class of some type...
A class is always an "object" but never "Always" derived from another class.

You can create your own "SuperClasses" that have no specific parents.

Examples:
Code:
//A Derived "SubClass" using inheritance
public class SubClass : SuperClass
{
    //This is known as a "Ctor" or "Constructor", since we inherit "SuperClass", we must call it's "Ctor" using "base()"
    public SuperClass() : base(args) //"args" would be variables you pass to or set for, the base "Ctor", if any are required.
    {
          //Set the "SuperClass" variables here
    }
}
Code:
//A custom "SuperClass", drop the inheritance
public class SuperClass
{
    //"Constructor", since we do not inherit anything, we do not need to define "base()"
    public SuperClass()
    {
          //Set Class Variables, which you need to define
    }
}
Code:
//A custom "SuperClass", drop the inheritance, use custom variables
public class SuperClass
{
    //Define your new variables
    private int m_Int;
    private double m_Double;
    private bool m_Bool;
    private string m_String;

    //"Constructor", since we do not inherit anything, we do not need to define "base()"
    public SuperClass()
    {
          //Set Class Variables, which you need to define as above
          m_Int = 1234;
          m_Double = 123.4;
          m_Bool = true; //Or false
          m_String = "Hello World";
    }
}
__________________

RPK.VORSPIRE.COM - The WoW-UO Cross-Over Shard

Last edited by Vorspire; 05-18-2008 at 10:32 AM.
Vorspire is offline   Reply With Quote
Old 05-18-2008, 10:53 AM   #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

I know that this thread isn't supposed to be in this scope, but I also know that Vorspire want to learn so I decided to correct minor errors:

Quote:
Originally Posted by Vorspire View Post
A class is always an "object" but never "Always" derived from another class.
Every object is made from a class, but there are several classes that doesn't make objects (static classes can't be used to make objects).
Take for example the Utility.cs class from the core.
The class itself isn't static but all the methods inside it are static so making an object from that class won't serve any purpose.

Quote:
Originally Posted by Vorspire View Post
You can create your own "SuperClasses" that have no specific parents.
All the classes are derived (behind the scenes) from a single parent: the "object" class itself.
That why before .NET 2.0 (which introduced generics) we could have a list of "objects" and insert any kind of object from any class we want into them.
The list simply expected an object from type "object" (the class) and because every single class is derived from the "object" class then they all match the criteria (even int, double, bool...).
__________________
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 05-18-2008, 03:54 PM   #10 (permalink)
Forum Expert
 
Vorspire's Avatar
 
Join Date: Jan 2005
Location: Newcastle, United Kingdom
Age: 21
Posts: 2,294
Send a message via ICQ to Vorspire Send a message via MSN to Vorspire Send a message via Skype™ to Vorspire
Default

Hence the definition of Object Orientated Programming (OOP)
__________________

RPK.VORSPIRE.COM - The WoW-UO Cross-Over Shard
Vorspire is offline   Reply With Quote
Reply

Bookmarks


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

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off



Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0 RC5