Go Back   RunUO - Ultima Online Emulation > RunUO > Custom Script Releases

Custom Script Releases This forum is where you can release your custom scripts for other users to use.

Please note: By releasing your scripts here you are submitting them to the public and as such agree to publish them under the GPL licensing terms. The RunUO Team has made its software GPL for you to use and enjoy you should do the same for anything based off of RunUO.

Reply
 
Thread Tools Display Modes
Old 06-14-2007, 04:38 PM   #26 (permalink)
andrewd
Guest
 
Posts: n/a
Default ok great that worked

i do have one other question
when i add the book it has 51 books already in it and u can remove the books when u add the runes to it. now after removeing the book there are still 51 books so this could be abused to get more rune books.
my question is what could i do to make it so u cant remove the books from the master book?
  Reply With Quote
Old 06-14-2007, 05:26 PM   #27 (permalink)
Forum Expert
 
Lokai's Avatar
 
Join Date: Aug 2003
Location: Bergen, NY (Rochester)
Age: 42
Posts: 1,493
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 andrewd View Post
i do have one other question
when i add the book it has 51 books already in it and u can remove the books when u add the runes to it. now after removeing the book there are still 51 books so this could be abused to get more rune books.
my question is what could i do to make it so u cant remove the books from the master book?
Comment out these lines (around 99 & 100) in InternalRunebookGump.cs:

Code:
// Remove Button (for dropping Runebook)
            AddItem(350, 30, 0x22C5, 0x461);
            AddButton(380, 36, 2181, 2181, 96, GumpButtonType.Reply, 0);
Lokai is offline   Reply With Quote
Old 06-14-2007, 09:39 PM   #28 (permalink)
Master of the Internet
 
Lord_Greywolf's Avatar
 
Join Date: Dec 2005
Posts: 12,206
Send a message via Yahoo to Lord_Greywolf
Default

or do what i posted above when removing the books - require the blank scrolls and skill that is normally needed to make the book

then when they remove it they are actualy just making a new one and putting the runes into it

(if you also want to require the recal & gate scrolls, and do not know how to make it that way, then let me know and i will post a multiple rwquirement one -- to me just the blanks ones are good enough -- can also raise required skill to 120 also)
__________________
http://www.AoAUO.com

:) ..... Come for the Customs, Play for the Fun. Return to see your new Friends ..... :)
Lord_Greywolf is online now   Reply With Quote
Old 06-14-2007, 09:56 PM   #29 (permalink)
Forum Novice
 
Hotshot's Avatar
 
Join Date: Jan 2006
Posts: 221
Default

i'm saying, when i add all my runebooks to the master and then i tried to go through the moongate library, it deleted all the destinations. Ahh.. just realized ggrr.. i feel like a dumb azz, lol ok ok.. sorry abou8t the world Omi/tele. etc... ggrr... I meant the Moongate Library, I was doing two things at once when i posted that.... and just looked at top of Omni script, sorry again. Its the Moongate Library from CEO that it didn't compile with on my shard. any ideas ? just keeps crashing... well did until i restored/backup
__________________
You Can Make a Good Living working for someone else, you can make a fortune working for yourself.
Hotshot is offline   Reply With Quote
Old 06-14-2007, 10:08 PM   #30 (permalink)
andrewd
Guest
 
Posts: n/a
Default awsome i just added what u said

grey do u mind posting the multiple items the gate scroll and the recall scroll thxs
  Reply With Quote
Old 06-14-2007, 10:08 PM   #31 (permalink)
Forum Expert
 
Lokai's Avatar
 
Join Date: Aug 2003
Location: Bergen, NY (Rochester)
Age: 42
Posts: 1,493
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 Lord_Greywolf View Post
or do what i posted above when removing the books - require the blank scrolls and skill that is normally needed to make the book

then when they remove it they are actualy just making a new one and putting the runes into it

(if you also want to require the recal & gate scrolls, and do not know how to make it that way, then let me know and i will post a multiple rwquirement one -- to me just the blanks ones are good enough -- can also raise required skill to 120 also)
Nice edits above, just saw those now.
Lokai is offline   Reply With Quote
Old 06-15-2007, 02:08 AM   #32 (permalink)
Master of the Internet
 
Lord_Greywolf's Avatar
 
Join Date: Dec 2005
Posts: 12,206
Send a message via Yahoo to Lord_Greywolf
Default

no problem at all - use this block of code instead:

Code:
			if (buttonID == 96) // edited version for requiring scrolls added by greywolf
			{
				if ( from.Skills.Inscribe.Base < 100 )
				{
					from.SendMessage("You do not have the skill required to extract the book");
				}
				else if ( from.Backpack.ConsumeTotal( typeof( BlankScroll ), 10 ) &&
						from.Backpack.ConsumeTotal( typeof( RecallScroll ), 1 ) &&
						from.Backpack.ConsumeTotal( typeof( GateTravelScroll ), 1 ) )
				{
					from.CloseGump(typeof(InternalRunebookGump));
					from.SendGump(new OKTargetGump("Remove Runebook?", 16777215,
						"Are you sure you want to remove this Runebook?",
						16777215, 300, 300, new GenericOKCallback(RemoveRunebook_Callback), m_MasterBook, m_Book, m_BookNum));
				}
				else
				{
					from.SendMessage("You do not have the materials needed to creat the rune book");
				}
			}
__________________
http://www.AoAUO.com

:) ..... Come for the Customs, Play for the Fun. Return to see your new Friends ..... :)
Lord_Greywolf is online now   Reply With Quote
Old 06-15-2007, 02:19 PM   #33 (permalink)
andrewd
Guest
 
Posts: n/a
Default I Found A Slight Problem

Quote:
Originally Posted by Lord_Greywolf View Post
no problem at all - use this block of code instead:

Code:
			if (buttonID == 96) // edited version for requiring scrolls added by greywolf
			{
				if ( from.Skills.Inscribe.Base < 100 )
				{
					from.SendMessage("You do not have the skill required to extract the book");
				}
				else if ( from.Backpack.ConsumeTotal( typeof( BlankScroll ), 10 ) &&
						from.Backpack.ConsumeTotal( typeof( RecallScroll ), 1 ) &&
						from.Backpack.ConsumeTotal( typeof( GateTravelScroll ), 1 ) )
				{
					from.CloseGump(typeof(InternalRunebookGump));
					from.SendGump(new OKTargetGump("Remove Runebook?", 16777215,
						"Are you sure you want to remove this Runebook?",
						16777215, 300, 300, new GenericOKCallback(RemoveRunebook_Callback), m_MasterBook, m_Book, m_BookNum));
				}
				else
				{
					from.SendMessage("You do not have the materials needed to creat the rune book");
				}
			}


if u dont have a rune in the book it wont extract from the master book but it will still take your blank scrolls
  Reply With Quote
Old 06-15-2007, 04:22 PM   #34 (permalink)
Forum Expert
 
Lokai's Avatar
 
Join Date: Aug 2003
Location: Bergen, NY (Rochester)
Age: 42
Posts: 1,493
Send a message via ICQ to Lokai Send a message via MSN to Lokai Send a message via Yahoo to Lokai
Default

Andrewd and Lord_GreyWolf:

You might want to use this version instead. This is more like a crafters version of the extraction routine. Using this will prevent the scrolls from being consumed if you do not have a GateScroll, for example. It also checks skill with a chance to gain, etc. I think you will like this.

NOTICE: This is in a different spot in the script than you were using.

Code:
        public static void RemoveRunebook_Callback(Mobile from, bool okay, MasterRunebook master, InternalRunebook book, int id)
        {
            if (okay)
            {
                Container pack = from.Backpack;
                if (pack == null || pack.Deleted)
                {
                    from.SendMessage("Unable to find a backpack in which to place a new Runebook.");
                    return;
                }
                int count = book.Entries.Count;
                if (count > 0)
                {
                    if (!from.Backpack.ConsumeTotal(new Type[] { typeof(BlankScroll), typeof(RecallScroll), typeof(GateTravelScroll) },
                        new int[] { 10, 1, 1 }))
                    {
                        from.SendMessage("You do not have the materials needed to create the runebook.");
                        return;
                    }
                    if (from.CheckSkill(SkillName.Inscribe, 100, 120))
                    {
                        from.SendMessage("You failed to extract the book. Some materials were lost.");
                        return;
                    }
                    
                    Runebook runebook = new Runebook(book.MaxCharges);
                    for (int x = 0; x < count; x++)
                    {
                        RunebookEntry rbe = new RunebookEntry(
                            ((RunebookEntry)book.Entries[0]).Location, ((RunebookEntry)book.Entries[0]).Map,
                            ((RunebookEntry)book.Entries[0]).Description, ((RunebookEntry)book.Entries[0]).House);
                        runebook.Entries.Add(rbe);
                        book.Entries.RemoveAt(0);
                    }
                    runebook.Name = book.Name;
                    book.Name = string.Format("Book #{0}", ((int)(id + 1)).ToString());
                    pack.DropItem(runebook);
                    from.SendMessage("Runebook extracted. Some materials were used.");
                }
                else
                {
                    from.SendMessage("You cannot remove an empty Runebook.");
                }
                from.CloseGump(typeof(InternalRunebookGump));
                from.SendGump(new InternalRunebookGump(from, book, master, id));
            }
            else
            {
                from.CloseGump(typeof(InternalRunebookGump));
                from.SendGump(new InternalRunebookGump(from, book, master, id));
            }
        }
Lokai is offline   Reply With Quote
Old 06-15-2007, 05:28 PM   #35 (permalink)
andrewd
Guest
 
Posts: n/a
Default aw great ill try when i get home

i have one other issue going on i have a ton if internalrunebook.item in my internal map is this suposed to happen becaus eif so it wont take long that item count will be way up there in a day i already have 2k internalrunebook in my internal map and im the only one using it so far.
  Reply With Quote
Old 06-15-2007, 05:56 PM   #36 (permalink)
Forum Expert
 
Lokai's Avatar
 
Join Date: Aug 2003
Location: Bergen, NY (Rochester)
Age: 42
Posts: 1,493
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 andrewd View Post
i have one other issue going on i have a ton if internalrunebook.item in my internal map is this suposed to happen becaus eif so it wont take long that item count will be way up there in a day i already have 2k internalrunebook in my internal map and im the only one using it so far.
I have to create 51 new Internal Runebooks each time I Deserialize or I would get null reference exceptions. Perhaps the Server does not actually remove them when it Serializes. Try changing your Serialization method like this in MasterRunebook.cs: (new line in red.)

Code:
        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);
            writer.Write((int)0); //version
            for (int x = 0; x < 51; x++) writer.Write((Item)m_Books[x]);
            for (int x = 0; x < 51; x++) m_Books[x].Delete();
        }
        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();
            m_Books = new InternalRunebook[51];
            for (int x = 0; x < 51; x++) m_Books[x] = (InternalRunebook)reader.ReadItem();
        }
Lokai is offline   Reply With Quote
Old 06-15-2007, 06:17 PM   #37 (permalink)
Forum Expert
 
Lokai's Avatar
 
Join Date: Aug 2003
Location: Bergen, NY (Rochester)
Age: 42
Posts: 1,493
Send a message via ICQ to Lokai Send a message via MSN to Lokai Send a message via Yahoo to Lokai
Default

I just realized that the 'ConsumeTotal' method is returning an 'int' so I cannot use the '!' operator with it. Use this code snipet instead:

Code:
if (from.Backpack.ConsumeTotal(newType[] { typeof(BlankScroll), typeof(RecallScroll), typeof(GateTravelScroll) },
newint[] { 10, 1, 1 }) >= 0)
Lokai is offline   Reply With Quote
Old 06-15-2007, 07:35 PM   #38 (permalink)
Tru
Forum Expert
 
Tru's Avatar
 
Join Date: Jan 2003
Location: California
Age: 41
Posts: 3,259
Default

Quote:
Originally Posted by Lokai View Post
I just realized that the 'ConsumeTotal' method is returning an 'int' so I cannot use the '!' operator with it. Use this code snipet instead:

Code:
if (from.Backpack.ConsumeTotal(newType[] { typeof(BlankScroll), typeof(RecallScroll), typeof(GateTravelScroll) },
newint[] { 10, 1, 1 }) >= 0)

Come up with this error:

Code:
Errors:
 + Custom/Stand Alone/Level Rewards/MasterRuneBook/InternalRunebookGump.cs:
    CS0443: Line 592: Syntax error, value expected
    CS1026: Line 592: ) expected
    CS1002: Line 592: ; expected
    CS1525: Line 592: Invalid expression term ','
    CS1002: Line 592: ; expected
    CS1002: Line 592: ; expected
    CS1525: Line 592: Invalid expression term ','
    CS1002: Line 592: ; expected
    CS1002: Line 592: ; expected
    CS1525: Line 592: Invalid expression term ','
    CS1002: Line 592: ; expected
    CS1001: Line 593: Identifier expected
    CS1002: Line 593: ; expected
    CS1525: Line 593: Invalid expression term ','
    CS1002: Line 593: ; expected
    CS1002: Line 593: ; expected
    CS1525: Line 593: Invalid expression term ','
    CS1002: Line 593: ; expected
    CS1002: Line 593: ; expected
    CS1525: Line 593: Invalid expression term ')'
    CS1002: Line 593: ; expected
    CS1525: Line 593: Invalid expression term ')'
    CS1002: Line 593: ; expected

Last edited by Tru; 06-15-2007 at 07:37 PM.
Tru is offline   Reply With Quote
Old 06-15-2007, 07:45 PM   #39 (permalink)
Forum Expert
 
Lokai's Avatar
 
Join Date: Aug 2003
Location: Bergen, NY (Rochester)
Age: 42
Posts: 1,493
Send a message via ICQ to Lokai Send a message via MSN to Lokai Send a message via Yahoo to Lokai
Default

@Tru

Please post your entire script, so I can see it in context.

Thanks.
Lokai is offline   Reply With Quote
Old 06-15-2007, 08:35 PM   #40 (permalink)
Tru
Forum Expert
 
Tru's Avatar
 
Join Date: Jan 2003
Location: California
Age: 41
Posts: 3,259
Default

Quote:
Originally Posted by Lokai View Post
@Tru

Please post your entire script, so I can see it in context.

Thanks.
How About just the RemoveRunebookCallback

Code:
public static void RemoveRunebook_Callback(Mobile from, bool okay, MasterRunebook master, InternalRunebook book, int id)
        {
            if (okay)
            {
                Container pack = from.Backpack;
                if (pack == null || pack.Deleted)
                {
                    from.SendMessage("Unable to find a backpack in which to place a new Runebook.");
                    return;
                }
                int count = book.Entries.Count;
                if (count > 0)
                {
                    //if (!from.Backpack.ConsumeTotal(new Type[] { typeof(BlankScroll), typeof(RecallScroll), typeof(GateTravelScroll) },
                        //new int[] { 10, 1, 1 }))
                      if (from.Backpack.ConsumeTotal(newType[] { typeof(BlankScroll), typeof(RecallScroll), typeof(GateTravelScroll) },
                          newint[] { 10, 1, 1 }) >= 0)

                    {
                        from.SendMessage("You do not have the materials needed to create the runebook.");
                        return;
                    }
                    if (from.CheckSkill(SkillName.Inscribe, 100, 120))
                    {
                        from.SendMessage("You failed to extract the book. Some materials were lost.");
                        return;
                    }

                    Runebook runebook = new Runebook(book.MaxCharges);
                    for (int x = 0; x < count; x++)
                    {
                        RunebookEntry rbe = new RunebookEntry(
                            ((RunebookEntry)book.Entries[0]).Location, ((RunebookEntry)book.Entries[0]).Map,
                            ((RunebookEntry)book.Entries[0]).Description, ((RunebookEntry)book.Entries[0]).House);
                        runebook.Entries.Add(rbe);
                        book.Entries.RemoveAt(0);
                    }
                    runebook.Name = book.Name;
                    book.Name = string.Format("Book #{0}", ((int)(id + 1)).ToString());
                    pack.DropItem(runebook);
                    from.SendMessage("Runebook extracted. Some materials were used.");
                }
                else
                {
                    from.SendMessage("You cannot remove an empty Runebook.");
                }
                from.CloseGump(typeof(InternalRunebookGump));
                from.SendGump(new InternalRunebookGump(from, book, master, id));
            }
            else
            {
                from.CloseGump(typeof(InternalRunebookGump));
                from.SendGump(new InternalRunebookGump(from, book, master, id));
            }
        }
If you need the rest I can post it. The original 2 lines are edited out.
Tru is offline   Reply With Quote
Old 06-15-2007, 09:54 PM   #41 (permalink)
Forum Expert
 
Lokai's Avatar
 
Join Date: Aug 2003
Location: Bergen, NY (Rochester)
Age: 42
Posts: 1,493
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 Tru View Post
How About just the RemoveRunebookCallback

Code:
public static void RemoveRunebook_Callback(Mobile from, bool okay, MasterRunebook master, InternalRunebook book, int id)
        {
            if (okay)
            {
                Container pack = from.Backpack;
                if (pack == null || pack.Deleted)
                {
                    from.SendMessage("Unable to find a backpack in which to place a new Runebook.");
                    return;
                }
                int count = book.Entries.Count;
                if (count > 0)
                {
                    //if (!from.Backpack.ConsumeTotal(new Type[] { typeof(BlankScroll), typeof(RecallScroll), typeof(GateTravelScroll) },
                        //new int[] { 10, 1, 1 }))
                      if (from.Backpack.ConsumeTotal(newType[] { typeof(BlankScroll), typeof(RecallScroll), typeof(GateTravelScroll) },
                          newint[] { 10, 1, 1 }) >= 0)
 
                    {
                        from.SendMessage("You do not have the materials needed to create the runebook.");
                        return;
                    }
                    if (from.CheckSkill(SkillName.Inscribe, 100, 120))
                    {
                        from.SendMessage("You failed to extract the book. Some materials were lost.");
                        return;
                    }
 
                    Runebook runebook = new Runebook(book.MaxCharges);
                    for (int x = 0; x < count; x++)
                    {
                        RunebookEntry rbe = new RunebookEntry(
                            ((RunebookEntry)book.Entries[0]).Location, ((RunebookEntry)book.Entries[0]).Map,
                            ((RunebookEntry)book.Entries[0]).Description, ((RunebookEntry)book.Entries[0]).House);
                        runebook.Entries.Add(rbe);
                        book.Entries.RemoveAt(0);
                    }
                    runebook.Name = book.Name;
                    book.Name = string.Format("Book #{0}", ((int)(id + 1)).ToString());
                    pack.DropItem(runebook);
                    from.SendMessage("Runebook extracted. Some materials were used.");
                }
                else
                {
                    from.SendMessage("You cannot remove an empty Runebook.");
                }
                from.CloseGump(typeof(InternalRunebookGump));
                from.SendGump(new InternalRunebookGump(from, book, master, id));
            }
            else
            {
                from.CloseGump(typeof(InternalRunebookGump));
                from.SendGump(new InternalRunebookGump(from, book, master, id));
            }
        }
If you need the rest I can post it. The original 2 lines are edited out.

I have the exact same line, and it compiles fine. I guess I need to see the rest. BTW, I am using RC1 in testing this.
Lokai is offline   Reply With Quote
Old 06-15-2007, 10:41 PM   #42 (permalink)
Tru
Forum Expert
 
Tru's Avatar
 
Join Date: Jan 2003
Location: California
Age: 41
Posts: 3,259
Default

Code:
using System;
using System.Collections;
using Server;
using Server.Items;
using Server.Network;
using Server.Spells;
using Server.Spells.Fourth;
using Server.Spells.Seventh;
using Server.Spells.Chivalry;
using Server.Targeting;
using Server.Prompts;

namespace Server.Gumps
{
    public class InternalRunebookGump : Gump
    {
        private InternalRunebook m_Book;
        public InternalRunebook Book { get { return m_Book; } }

        private int m_BookNum;
        public int BookNum { get { return m_BookNum; } }

        private MasterRunebook m_MasterBook;
        public MasterRunebook MasterBook { get { return m_MasterBook; } }

        public int GetMapHue(Map map)
        {
            if (map == Map.Trammel)
                return 10;
            else if (map == Map.Felucca)
                return 81;
            else if (map == Map.Ilshenar)
                return 1102;
            else if (map == Map.Malas)
                return 1102;
            else if (map == Map.Tokuno)
                return 1154;

            return 0;
        }

        public string GetName(string name)
        {
            if (name == null || (name = name.Trim()).Length <= 0)
                return "(nondescript)";

            return name;
        }

        private void AddBackground()
        {
            AddPage(0);

            // Background image
            AddImage(100, 10, 2200);

            // Two separators
            for (int i = 0; i < 2; ++i)
            {
                int xOffset = 125 + (i * 165);

                AddImage(xOffset, 50, 57);
                xOffset += 20;

                for (int j = 0; j < 6; ++j, xOffset += 15)
                    AddImage(xOffset, 50, 58);

                AddImage(xOffset - 5, 50, 59);
            }

            // First four page buttons
            for (int i = 0, xOffset = 130, gumpID = 2225; i < 4; ++i, xOffset += 35, ++gumpID)
                AddButton(xOffset, 187, gumpID, gumpID, 0, GumpButtonType.Page, 2 + i);

            // Next four page buttons
            for (int i = 0, xOffset = 300, gumpID = 2229; i < 4; ++i, xOffset += 35, ++gumpID)
                AddButton(xOffset, 187, gumpID, gumpID, 0, GumpButtonType.Page, 6 + i);

            // Charges
            AddHtmlLocalized(132, 32, 80, 18, 1011296, false, false); // Charges:
            AddHtml(185, 32, 50, 18, string.Format("{0}/{1}", m_Book.CurCharges.ToString(), m_Book.MaxCharges.ToString()), false, false);

            // Max charges
            //AddHtmlLocalized(300, 40, 100, 18, 1011297, false, false); // Max Charges:
            //AddHtml(400, 40, 30, 18, m_Book.MaxCharges.ToString(), false, false);
        }

        private void AddIndex()
        {
            // Index 
            AddPage(1);

            // Scroll Button (for adding Recall Scrolls)
            //AddButton(236, 39, 5402, 5402, 97, GumpButtonType.Reply, 0);
            AddButton(236, 34, 2510, 2510, 97, GumpButtonType.Reply, 0);
            AddItem(221, 32, 8012);

            // Remove Button (for dropping Runebook)
            //AddItem(350, 30, 0x22C5, 0x461);
            //AddButton(380, 36, 2181, 2181, 96, GumpButtonType.Reply, 0);

            // List of entries
            ArrayList entries = m_Book.Entries;

            for (int i = 0; i < 16; ++i)
            {
                string desc;
                int hue;

                if (i < entries.Count)
                {
                    desc = GetName(((RunebookEntry)entries[i]).Description);
                    hue = GetMapHue(((RunebookEntry)entries[i]).Map);
                }
                else
                {
                    desc = "Empty";
                    hue = 0;
                }

                // Use charge button
                AddButton(130 + ((i / 8) * 160), 65 + ((i % 8) * 15), 2103, 2104, 2 + (i * 6) + 0, GumpButtonType.Reply, 0);

                if (i == entries.Count)
                {
                    // (Button for adding Recall Rune for new Location)
                    AddButton(145 + ((i / 8) * 160), 62 + ((i % 8) * 15), 2510, 2510, 98, GumpButtonType.Reply, 0); //or 30087 or 4202
                    AddItem(129 + ((i / 8) * 160), 65 + ((i % 8) * 15), 7959);
                }
                else
                    // Description label
                    AddLabelCropped(145 + ((i / 8) * 160), 60 + ((i % 8) * 15), 115, 17, hue, desc);
            }

            // Turn page button
            //AddButton(393, 14, 2206, 2206, 0, GumpButtonType.Page, 2);
        }

        private void AddDetails(int index, int half)
        {
            // Use charge button
            AddButton(130 + (half * 160), 65, 2103, 2104, 2 + (index * 6) + 0, GumpButtonType.Reply, 0);

            string desc;
            int hue;

            if (index < m_Book.Entries.Count)
            {
                RunebookEntry e = (RunebookEntry)m_Book.Entries[index];

                desc = GetName(e.Description);
                hue = GetMapHue(e.Map);

                // Location labels
                int xLong = 0, yLat = 0;
                int xMins = 0, yMins = 0;
                bool xEast = false, ySouth = false;

                if (Sextant.Format(e.Location, e.Map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth))
                {
                    AddLabel(135 + (half * 160), 80, 0, String.Format("{0}° {1}'{2}", yLat, yMins, ySouth ? "S" : "N"));
                    AddLabel(135 + (half * 160), 95, 0, String.Format("{0}° {1}'{2}", xLong, xMins, xEast ? "E" : "W"));
                }

                // Drop rune button
                AddButton(135 + (half * 160), 115, 2437, 2438, 2 + (index * 6) + 1, GumpButtonType.Reply, 0);
                AddHtmlLocalized(150 + (half * 160), 115, 100, 18, 1011298, false, false); // Drop rune

                if (Core.AOS)
                {
                    AddButton(135 + (half * 160), 140, 2103, 2104, 2 + (index * 6) + 3, GumpButtonType.Reply, 0);
                    AddHtmlLocalized(150 + (half * 160), 136, 110, 20, 1062722, false, false); // Recall

                    AddButton(135 + (half * 160), 158, 2103, 2104, 2 + (index * 6) + 4, GumpButtonType.Reply, 0);
                    AddHtmlLocalized(150 + (half * 160), 154, 110, 20, 1062723, false, false); // Gate Travel

                    AddButton(135 + (half * 160), 176, 2103, 2104, 2 + (index * 6) + 5, GumpButtonType.Reply, 0);
                    AddHtmlLocalized(150 + (half * 160), 172, 110, 20, 1062724, false, false); // Sacred Journey
                }
                else
                {
                    // Recall button
                    AddButton(135 + (half * 160), 140, 2271, 2271, 2 + (index * 6) + 3, GumpButtonType.Reply, 0);

                    // Gate button
                    AddButton(205 + (half * 160), 140, 2291, 2291, 2 + (index * 6) + 4, GumpButtonType.Reply, 0);
                }
            }
            else
            {
                desc = "Empty";
                hue = 0;
            }

            // Description label
            AddLabelCropped(145 + (half * 160), 60, 115, 17, hue, desc);
        }

        public InternalRunebookGump(Mobile from, InternalRunebook book, MasterRunebook masterbook, int booknum)
            : base(150, 200)
        {
            m_Book = book;
            m_MasterBook = masterbook;
            m_BookNum = booknum;

            AddBackground();

            AddLabel(137, 12, 0, m_Book.Name);
            AddLabel(312, 32, 0, "Return");
            AddButton(288, 34, 2223, 2223, 99, GumpButtonType.Reply, 0);

            if (booknum > 0)
            {
                AddButton(283, 14, 9766, 9767, booknum + 99, GumpButtonType.Reply, 0);
                AddLabel(303, 12, 0, string.Format("{0}", ((int)(booknum)).ToString()));
            }
            if (booknum < 50)
            {
                AddButton(407, 14, 9762, 9763, booknum + 101, GumpButtonType.Reply, 0);
                AddLabel(387, 12, 0, string.Format("{0}", ((int)(booknum + 2)).ToString()));
            }

            AddIndex();

            for (int page = 0; page < 8; ++page)
            {
                AddPage(2 + page);

                //AddButton(125, 14, 2205, 2205, 0, GumpButtonType.Page, 1 + page);

                //if (page < 7)
                //    AddButton(393, 14, 2206, 2206, 0, GumpButtonType.Page, 3 + page);

                for (int half = 0; half < 2; ++half)
                    AddDetails((page * 2) + half, half);
            }
        }

        public static bool HasSpell(Mobile from, int spellID)
        {
            Spellbook book = Spellbook.Find(from, spellID);

            return (book != null && book.HasSpell(spellID));
        }

        public override void OnResponse(NetState state, RelayInfo info)
        {
            Mobile from = state.Mobile;

            if (m_MasterBook.Deleted || !from.InRange(m_MasterBook.GetWorldLocation(), 1) || !Multis.DesignContext.Check(from))
                return;

            int buttonID = info.ButtonID;

            if (buttonID == 96)
            {
                from.CloseGump(typeof(InternalRunebookGump));
                from.SendGump(new OKTargetGump("Remove Runebook?", 16777215,
                    "Are you sure you want to remove this Runebook?",
                    16777215, 300, 300, new GenericOKCallback(RemoveRunebook_Callback), m_MasterBook, m_Book, m_BookNum));
            }
            else
                if (buttonID == 97)
                {
                    from.CloseGump(typeof(InternalRunebookGump));
                    from.SendGump(new InternalRunebookGump(from, m_Book, m_MasterBook, m_BookNum));
                    from.SendMessage("Target a Recall Scroll to add charges.");
                    from.Target = new InternalTarget(m_Book, m_MasterBook, m_BookNum);
                }
                else
                    if (buttonID == 98)
                    {
                        from.CloseGump(typeof(InternalRunebookGump));
                        from.SendGump(new InternalRunebookGump(from, m_Book, m_MasterBook, m_BookNum));
                        from.SendMessage("Target a Recall Rune to add a destination.");
                        from.Target = new InternalRuneTarget(m_Book, m_MasterBook, m_BookNum);
                    }
                    else
                        if (buttonID == 99)
                        {
                            from.CloseGump(typeof(InternalRunebookGump));
                            from.SendGump(new MasterRunebookGump(from, m_MasterBook));
                        }
                        else

                            if (buttonID > 99)
                            {
                                from.CloseGump(typeof(InternalRunebookGump));
                                from.SendGump(new InternalRunebookGump(from, m_MasterBook.Books[buttonID - 100], m_MasterBook, buttonID - 100));
                            }
                            else
                            {
                                buttonID -= 2;

                                int index = buttonID / 6;
                                int type = buttonID % 6;

                                if (index >= 0 && index < m_Book.Entries.Count)
                                {
                                    RunebookEntry e = (RunebookEntry)m_Book.Entries[index];

                                    switch (type)
                                    {
                                        case 0: // Use charges
                                            {
                                                if (m_Book.CurCharges <= 0)
                                                {
                                                    from.CloseGump(typeof(InternalRunebookGump));
                                                    from.SendGump(new InternalRunebookGump(from, m_Book, m_MasterBook, m_BookNum));

                                                    from.SendLocalizedMessage(502412); // There are no charges left on that item.
                                                }
                                                else
                                                {
                                                    int xLong = 0, yLat = 0;
                                                    int xMins = 0, yMins = 0;
                                                    bool xEast = false, ySouth = false;

                                                    if (Sextant.Format(e.Location, e.Map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth))
                                                    {
                                                        string location = String.Format("{0}° {1}'{2}, {3}° {4}'{5}", yLat, yMins, ySouth ? "S" : "N", xLong, xMins, xEast ? "E" : "W");
                                                        from.SendMessage(location);
                                                    }

                                                    m_Book.OnTravel();

                                                    new RecallSpell(from, m_Book, e, m_Book).Cast();
                                                }

                                                break;
                                            }
                                        case 1: // Drop rune
                                            {
                                                if (m_Book.CheckAccess(from))
                                                {
                                                    m_Book.DropRune(from, e, index);

                                                    from.CloseGump(typeof(InternalRunebookGump));
                                                    from.SendGump(new InternalRunebookGump(from, m_Book, m_MasterBook, m_BookNum));
                                                }
                                                else
                                                {
                                                    from.SendLocalizedMessage(502413); // That cannot be done while the book is locked down.
                                                }

                                                break;
                                            }
                                        case 3: // Recall
                                            {
                                                if (HasSpell(from, 31))
                                                {
                                                    int xLong = 0, yLat = 0;
                                                    int xMins = 0, yMins = 0;
                                                    bool xEast = false, ySouth = false;

                                                    if (Sextant.Format(e.Location, e.Map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth))
                                                    {
                                                        string location = String.Format("{0}° {1}'{2}, {3}° {4}'{5}", yLat, yMins, ySouth ? "S" : "N", xLong, xMins, xEast ? "E" : "W");
                                                        from.SendMessage(location);
                                                    }

                                                    m_Book.OnTravel();
                                                    new RecallSpell(from, null, e, null).Cast();
                                                }
                                                else
                                                {
                                                    from.SendLocalizedMessage(500015); // You do not have that spell!
                                                }

                                                break;
                                            }
                                        case 4: // Gate
                                            {
                                                if (HasSpell(from, 51))
                                                {
                                                    int xLong = 0, yLat = 0;
                                                    int xMins = 0, yMins = 0;
                                                    bool xEast = false, ySouth = false;

                                                    if (Sextant.Format(e.Location, e.Map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth))
                                                    {
                                                        string location = String.Format("{0}° {1}'{2}, {3}° {4}'{5}", yLat, yMins, ySouth ? "S" : "N", xLong, xMins, xEast ? "E" : "W");
                                                        from.SendMessage(location);
                                                    }

                                                    m_Book.OnTravel();
                                                    new GateTravelSpell(from, null, e).Cast();
                                                }
                                                else
                                                {
                                                    from.SendLocalizedMessage(500015); // You do not have that spell!
                                                }

                                                break;
                                            }
                                        case 5: // Sacred Journey
                                            {
                                                if (Core.AOS)
                                                {
                                                    if (HasSpell(from, 209))
                                                    {
                                                        int xLong = 0, yLat = 0;
                                                        int xMins = 0, yMins = 0;
                                                        bool xEast = false, ySouth = false;

                                                        if (Sextant.Format(e.Location, e.Map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth))
                                                        {
                                                            string location = String.Format("{0}° {1}'{2}, {3}° {4}'{5}", yLat, yMins, ySouth ? "S" : "N", xLong, xMins, xEast ? "E" : "W");
                                                            from.SendMessage(location);
                                                        }

                                                        m_Book.OnTravel();
                                                        new SacredJourneySpell(from, null, e, null).Cast();
                                                    }
                                                    else
                                                    {
                                                        from.SendLocalizedMessage(500015); // You do not have that spell!
                                                    }
                                                }

                                                break;
                                            }
                                    }
                                }
                            }
        }

        private class InternalTarget : Target
        {
            private InternalRunebook m_RuneBook;
            private MasterRunebook m_Master;
            private int m_Booknum;

            public InternalTarget(InternalRunebook book, MasterRunebook master, int booknum)
                : base(3, false, TargetFlags.None)
            {
                m_RuneBook = book;
                m_Master = master;
                m_Booknum = booknum;
            }

            protected override void OnTarget(Mobile from, object targeted)
            {
                if (targeted is RecallScroll)
                {
                    Item scrolls = targeted as Item;
                    if (m_RuneBook.CurCharges < m_RuneBook.MaxCharges)
                    {
                        from.Send(new PlaySound(0x249, from.Location));

                        int amount = scrolls.Amount;

                        if (amount > (m_RuneBook.MaxCharges - m_RuneBook.CurCharges))
                        {
                            scrolls.Consume(m_RuneBook.MaxCharges - m_RuneBook.CurCharges);
                            m_RuneBook.CurCharges = m_RuneBook.MaxCharges;
                        }
                        else
                        {
                            m_RuneBook.CurCharges += amount;
                            scrolls.Delete();
                        }
                    }
                    else
                    {
                        from.SendLocalizedMessage(502410); // This book already has the maximum amount of charges.
                    }
                }
                else
                    from.SendMessage("That is not a Recall Scroll.");
                from.CloseGump(typeof(InternalRunebookGump));
                from.SendGump(new InternalRunebookGump(from, m_RuneBook, m_Master, m_Booknum));
            }
        }

        private class InternalRuneTarget : Target
        {
            private InternalRunebook m_RuneBook;
            private MasterRunebook m_Master;
            private int m_Booknum;

            public InternalRuneTarget(InternalRunebook book, MasterRunebook master, int booknum)
                : base(3, false, TargetFlags.None)
            {
                m_RuneBook = book;
                m_Master = master;
                m_Booknum = booknum;
            }

            protected override void OnTarget(Mobile from, object targeted)
            {
                if (targeted is RecallRune)
                {
                    if (m_RuneBook.Entries.Count < 16)
                    {
                        RecallRune rune = (RecallRune)targeted;

                        if (rune.Marked && rune.TargetMap != null)
                        {
                            m_RuneBook.Entries.Add(new RunebookEntry(rune.Target, rune.TargetMap, rune.Description, rune.House));

                            rune.Delete();

                            from.Send(new PlaySound(0x42, from.Location));

                            string desc = rune.Description;

                            if (desc == null || (desc = desc.Trim()).Length == 0)
                                desc = "(nondescript)";

                            from.SendMessage(desc);
                        }
                        else
                        {
                            from.SendLocalizedMessage(502409); // This rune does not have a marked location.
                        }
                    }
                    else
                    {
                        from.SendLocalizedMessage(502401); // This runebook is full.
                    }
                }
                else
                    if (targeted == from && from.AccessLevel >= AccessLevel.GameMaster)
                    {
                        from.SendGump(new OKTargetGump("No Recall Rune?", 16777215,
                            "Do you want to Target your location instead of a Recall Rune?",
                            16777215, 300, 300, new GenericOKCallback(TargetPoint3D_Callback), m_Master, m_RuneBook, m_Booknum));
                        return;
                    }
                from.SendMessage("That is not a Recall Rune.");
                from.CloseGump(typeof(InternalRunebookGump));
                from.SendGump(new InternalRunebookGump(from, m_RuneBook, m_Master, m_Booknum));
            }
        }

        public static void RemoveRunebook_Callback(Mobile from, bool okay, MasterRunebook master, InternalRunebook book, int id)
        {
            if (okay)
            {
                int count = book.Entries.Count;
                if (count > 0)
                {
                    Runebook runebook = new Runebook(book.MaxCharges);
                    for (int x = 0; x < count; x++)
                    {
                        RunebookEntry rbe = new RunebookEntry(
                            ((RunebookEntry)book.Entries[0]).Location, ((RunebookEntry)book.Entries[0]).Map,
                            ((RunebookEntry)book.Entries[0]).Description, ((RunebookEntry)book.Entries[0]).House);
                        runebook.Entries.Add(rbe);
                        book.Entries.RemoveAt(0);
                    }
                    runebook.Name = book.Name;
                    book.Name = string.Format("Book #{0}", ((int)(id + 1)).ToString());
                    Container pack = from.Backpack;
                    if (pack == null || pack.Deleted)
                        from.SendMessage("Unable to find backpack to place new Runebook.");
                    else
                    {
                        pack.DropItem(runebook);
                        from.SendMessage("Runebook extracted.");
                    }
                }
                else
                {
                    from.SendMessage("You cannot remove an empty Runebook.");
                }
                from.CloseGump(typeof(InternalRunebookGump));
                from.SendGump(new InternalRunebookGump(from, book, master, id));
            }
            else
            {
                from.CloseGump(typeof(InternalRunebookGump));
                from.SendGump(new InternalRunebookGump(from, book, master, id));
            }
        }
/*public static void RemoveRunebook_Callback(Mobile from, bool okay, MasterRunebook master, InternalRunebook book, int id)
        {
            if (okay)
            {
                Container pack = from.Backpack;
                if (pack == null || pack.Deleted)
                {
                    from.SendMessage("Unable to find a backpack in which to place a new Runebook.");
                    return;
                }
                int count = book.Entries.Count;
                if (count > 0)
                {
                    //if (!from.Backpack.ConsumeTotal(new Type[] { typeof(BlankScroll), typeof(RecallScroll), typeof(GateTravelScroll) },
                        //new int[] { 10, 1, 1 }))
                      if (from.Backpack.ConsumeTotal(newType[] { typeof(BlankScroll), typeof(RecallScroll), typeof(GateTravelScroll) },
                          newint[] { 10, 1, 1 }) >= 0)

                    {
                        from.SendMessage("You do not have the materials needed to create the runebook.");
                        return;
                    }
                    if (from.CheckSkill(SkillName.Inscribe, 100, 120))
                    {
                        from.SendMessage("You failed to extract the book. Some materials were lost.");
                        return;
                    }

                    Runebook runebook = new Runebook(book.MaxCharges);
                    for (int x = 0; x < count; x++)
                    {
                        RunebookEntry rbe = new RunebookEntry(
                            ((RunebookEntry)book.Entries[0]).Location, ((RunebookEntry)book.Entries[0]).Map,
                            ((RunebookEntry)book.Entries[0]).Description, ((RunebookEntry)book.Entries[0]).House);
                        runebook.Entries.Add(rbe);
                        book.Entries.RemoveAt(0);
                    }
                    runebook.Name = book.Name;
                    book.Name = string.Format("Book #{0}", ((int)(id + 1)).ToString());
                    pack.DropItem(runebook);
                    from.SendMessage("Runebook extracted. Some materials were used.");
                }
                else
                {
                    from.SendMessage("You cannot remove an empty Runebook.");
                }
                from.CloseGump(typeof(InternalRunebookGump));
                from.SendGump(new InternalRunebookGump(from, book, master, id));
            }
            else
            {
                from.CloseGump(typeof(InternalRunebookGump));
                from.SendGump(new InternalRunebookGump(from, book, master, id));
            }
        }*/
        
        public static void TargetPoint3D_Callback(Mobile from, bool okay, MasterRunebook master, InternalRunebook book, int id)
        {
            if (okay)
            {
                if (book.Entries.Count < 16)
                {
                    book.Entries.Add(new RunebookEntry(from.Location, from.Map, "", null));
                    from.SendMessage("Enter the description for this location.");
                    from.Prompt = new DescriptionPrompt(master, book, id);
                }
                else
                {
                    from.SendLocalizedMessage(502401); // This runebook is full.
                    from.CloseGump(typeof(InternalRunebookGump));
                    from.SendGump(new InternalRunebookGump(from, book, master, id));
                }
            }
            else
            {
                from.CloseGump(typeof(InternalRunebookGump));
                from.SendGump(new InternalRunebookGump(from, book, master, id));
            }
        }

        private class DescriptionPrompt : Prompt
        {
            MasterRunebook m_Master;
            InternalRunebook m_Book;
            int m_Id;

            public DescriptionPrompt(MasterRunebook master, InternalRunebook book, int id)
            {
                m_Master = master;
                m_Book = book;
                m_Id = id;
            }

            public override void OnResponse(Mobile from, string text)
            {
                int index = m_Book.Entries.Count - 1;
                m_Book.Entries.RemoveAt(index);
                m_Book.Entries.Add(new RunebookEntry(from.Location, from.Map, text, null));
                from.SendMessage(text);
                from.CloseGump(typeof(InternalRunebookGump));
                from.SendGump(new InternalRunebookGump(from, m_Book, m_Master, m_Id));
            }
        }
    }
}
I'm using a newer SVN (not sure of the number actually).
Tru is offline   Reply With Quote
Old 06-15-2007, 10:54 PM   #43 (permalink)
Forum Expert
 
Lokai's Avatar
 
Join Date: Aug 2003
Location: Bergen, NY (Rochester)
Age: 42
Posts: 1,493
Send a message via ICQ to Lokai Send a message via MSN to Lokai Send a message via Yahoo to Lokai
Default

OK, I am confused. You have the section where the error is commented out, but the line number is in the middle of the comments??

If you uncommented it, you would have 2 sections with the same name. Something is not right here. This cannot be the same code you got that first error with. Line 592 and 593 are in the commented section.
Lokai is offline   Reply With Quote
Old 06-15-2007, 11:24 PM   #44 (permalink)
Tru
Forum Expert
 
Tru's Avatar
 
Join Date: Jan 2003
Location: California
Age: 41
Posts: 3,259
Default

Quote:
Originally Posted by Lokai View Post
OK, I am confused. You have the section where the error is commented out, but the line number is in the middle of the comments??

If you uncommented it, you would have 2 sections with the same name. Something is not right here. This cannot be the same code you got that first error with. Line 592 and 593 are in the commented section.
The commented part is the code that doesnt work. The uncommented is what I'm currently using. I swapped when it wouldnt compile then you asked for the whole thing.
Tru is offline   Reply With Quote
Old 06-15-2007, 11:37 PM   #45 (permalink)
Forum Expert
 
Lokai's Avatar
 
Join Date: Aug 2003
Location: Bergen, NY (Rochester)
Age: 42
Posts: 1,493
Send a message via ICQ to Lokai Send a message via MSN to Lokai Send a message via Yahoo to Lokai
Default

Got it.

You have this:

newType[]

instead of this:

new Type[]

you were missing a space.
Lokai is offline   Reply With Quote
Old 06-16-2007, 12:06 AM   #46 (permalink)
Tru
Forum Expert
 
Tru's Avatar
 
Join Date: Jan 2003
Location: California
Age: 41
Posts: 3,259
Default

Quote:
Originally Posted by Lokai View Post
Got it.

You have this:

newType[]

instead of this:

new Type[]

you were missing a space.
Yep just noticed. Its your code actually, I just copied from your post.
No biggie though.
Thanks Again

BTW Samething with the next line as well:
Code:
newint[]

Last edited by Tru; 06-16-2007 at 12:08 AM.
Tru is offline   Reply With Quote
Old 06-16-2007, 02:13 AM   #47 (permalink)
Master of the Internet
 
Lord_Greywolf's Avatar
 
Join Date: Dec 2005
Posts: 12,206
Send a message via Yahoo to Lord_Greywolf
Default

by the way have you varified if adding this in:

for (int x = 0; x < 51; x++) m_Books[x].Delete();

does fix the problem of the extra internal rune books?

I took a look at mine using global interface and i have about 15 pages of them so far, and all i have have done is tested it a couple of times (adding and deleting) and the book was only around for a couple of restarts and is now gone even and they remain

so this is a big memory leak problem
__________________
http://www.AoAUO.com

:) ..... Come for the Customs, Play for the Fun. Return to see your new Friends ..... :)
Lord_Greywolf is online now   Reply With Quote
Old 06-16-2007, 02:27 AM   #48 (permalink)
andrewd
Guest
 
Posts: n/a
Exclamation yes i noticed the same thing

i also deleted the book and it was still internal. major problem
  Reply With Quote
Old 06-16-2007, 02:40 AM   #49 (permalink)
Master of the Internet
 
Lord_Greywolf's Avatar
 
Join Date: Dec 2005
Posts: 12,206
Send a message via Yahoo to Lord_Greywolf
Default

looks like it needs an "on delete" method to go in and delete the internal books associated with it

i can see where this can cause a big memory leak problem over time where you would end up with 1000's of them on the internal map

i was just thinking to my self while typing this, instead of making them virtual books
maybe making them actual books (maybe even stored in a bag) on the internal map - and just call them via simular calls like that in the linked books you wrote - i.e. the main gump opens their gump - even though they are on the internap map
this way they would be real, and not need to be serialized with the main book (they have their own routine), just their id numbers to store which ones that are associated with the main book
and with an on delete method that when the main one is deleted, it deletes them (or the bag that holds them)

i could see where that would work - be a big rewrite change
was just a thought
__________________
http://www.AoAUO.com

:) ..... Come for the Customs, Play for the Fun. Return to see your new Friends ..... :)
Lord_Greywolf is online now   Reply With Quote
Old 06-16-2007, 05:49 AM   #50 (permalink)
Forum Expert
 
Lokai's Avatar
 
Join Date: Aug 2003
Location: Bergen, NY (Rochester)
Age: 42
Posts: 1,493
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 Tru View Post
Yep just noticed. Its your code actually, I just copied from your post.
No biggie though.
Thanks Again

BTW Samething with the next line as well:
Code:
newint[]
Oh, that explains it. It wasn't my code, it was the forums stripping off extra spaces. WHY DOES IT DO THAT?

EDIT* strange, looking at the post I made above, it does not look like the space was stripped. It must be one of those mysterious "Internal Spaces" that just looks like it's there until you try to copy it.

OK, here is the OnDelete() method. We can see if this takes care if it:

Code:
        public override void OnDelete()
        {
            for (int x = 0; x < 51; x++) m_Books[x].Delete();
            base.OnDelete();
        }

Last edited by Lokai; 06-16-2007 at 05:52 AM.
Lokai 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 - 2010, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0 RC5