How do I add additional pages to the staffatlas? (here is the code)
C#:
using System;
using Server.Network;
using Server.Gumps;
using Server.Prompts;
using Server.Mobiles;
using Server.Items;
using Server.Misc;
using Server.Spells;
using Server.Spells.Fourth;
using Server.Spells.Seventh;
using Server.Spells.Chivalry;

namespace Server.Items
{
    [FlipableAttribute(39958, 39959)]
    public class StaffAtlas : Runebook
    {
        public override int MaxEntries { get { return 48; } }
        //public override int LabelNumber { get { return 1156443; } } // a runic atlas

        public int Selected { get; set; }

        [Constructable]
        public StaffAtlas() : base(100, 39958)
        {
            Selected = -1;
        }

        public override void OnDoubleClick(Mobile from)
        {
            if (from is PlayerMobile && (from.InRange(GetWorldLocation(), 2) || from.AccessLevel >= AccessLevel.Counselor))
            {
                if (CheckAccess(from) || from.AccessLevel >= AccessLevel.Counselor)
                {
                    if (DateTime.UtcNow < NextUse)
                    {
                        from.SendLocalizedMessage(502406); // This book needs time to recharge.
                        return;
                    }

                    BaseGump.SendGump(new StaffAtlasGump((PlayerMobile)from, this));
                    Openers.Add(from);
                }
                else
                    from.SendLocalizedMessage(502436); // That is not accessible.
            }
        }

        public override bool OnDragDrop(Mobile from, Item dropped)
        {
            int entries = Entries.Count;
            bool d = base.OnDragDrop(from, dropped);

            if (from is PlayerMobile && d && Entries.Count > entries)
            {
                int newPage = Math.Max(0, (Entries.Count - 1) / 16);

                StaffAtlasGump g = from.FindGump(typeof(StaffAtlasGump)) as StaffAtlasGump;

                if (g != null && g.Atlas == this)
                {
                    g.Page = newPage;
                    g.Refresh();
                }
                else
                {
                    if (g != null)
                        from.CloseGump(typeof(StaffAtlasGump));

                    g = new StaffAtlasGump((PlayerMobile)from, this);
                    g.Page = newPage;
                    from.SendGump(g);
                }
            }

            return d;
        }

        public override int OnCraft(int quality, bool makersMark, Mobile from, Server.Engines.Craft.CraftSystem craftSystem, Type typeRes, ITool tool, Server.Engines.Craft.CraftItem craftItem, int resHue)
        {
            if (makersMark)
                Crafter = from;

            Quality = (BookQuality)(quality - 1);

            //MaxCharges = 100;

            return quality;
        }

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

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

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

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

            int version = reader.ReadInt();
            Selected = reader.ReadInt();

            //if (MaxCharges != 100)
            //    MaxCharges = 100;
        }
    }

    public class StaffAtlasGump : BaseGump
    {
        public static string ToCoordinates(Point3D location, Map map)
        {
            int xLong = 0, yLat = 0, xMins = 0, yMins = 0;
            bool xEast = false, ySouth = false;

            bool valid = Sextant.Format(location, map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth);

            return valid ? String.Format("{0}° {1}'{2}, {3}° {4}'{5}", yLat, yMins, ySouth ? "S" : "N", xLong, xMins, xEast ? "E" : "W") : "Nowhere";
        }

        public StaffAtlas Atlas { get; set; }
        public int Selected { get { return Atlas == null ? -1 : Atlas.Selected; } }
        public int Page { get; set; }

        public StaffAtlasGump(PlayerMobile pm, StaffAtlas atlas)
            : base(pm, 100, 100)
        {
            TypeID = 0x1F2;
            Atlas = atlas;
            Page = 0;
        }

        public static int GetMapHue(Map map)
        {
            if (map == Map.Trammel)
                return 0xA;
            else if (map == Map.Felucca)
                return 0x51;
            else if (map == Map.Malas)
                return 0x44E;
            else if (map == Map.Tokuno)
                return 0x482;
            else if (map == Map.TerMur)
                return 0x66D;

            return 0;
        }

        public override void AddGumpLayout()
        {
            AddImage(0, 0, 39923);

            AddHtmlLocalized(60, 9, 147, 22, 1011296, false, false); //Charges:
            AddHtml(110, 9, 97, 22, String.Format("{0} / {1}", Atlas.CurCharges, Atlas.MaxCharges), false, false);

            AddHtmlLocalized(264, 9, 144, 18, 1011299, false, false); // rename book
            AddButton(248, 14, 2103, 2103, 1, GumpButtonType.Reply, 0);

            int startIndex = Page * 16;
            int index = 0;

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

                if (i < Atlas.Entries.Count)
                {
                    desc = RunebookGump.GetName(Atlas.Entries[i].Description);
                    hue = Selected == i ? 0x14B : GetMapHue(Atlas.Entries[i].Map);
                }
                else
                {
                    desc = "Empty";
                    hue = 0;
                }

                // Select Button
                AddButton(46 + ((index / 8) * 205), 55 + ((index % 8) * 20), 2103, 2104, i + 100, GumpButtonType.Reply, 0);

                // Description label
                AddLabelCropped(62 + ((index / 8) * 205), 50 + ((index % 8) * 20), 144, 18, hue, desc);

                index++;
            }

            RunebookEntry entry = null;

            if (Selected >= 0 && Selected < Atlas.Entries.Count)
            {
                entry = Atlas.Entries[Selected];
            }
            
            string coords = entry != null ? ToCoordinates(entry.Location, entry.Map) : "Nowhere";

            AddHtml(25, 254, 182, 18, String.Format("<center>{0}</center>", coords), false, false);

            AddHtmlLocalized(62, 290, 144, 18, 1011300, false, false); // Set default                       
            AddButton(46, 295, 2103, 2103, 2, GumpButtonType.Reply, 0);

            AddHtmlLocalized(62, 310, 144, 18, 1011298, false, false); // Drop rune
            AddButton(46, 315, 2103, 2103, 3, GumpButtonType.Reply, 0);

            AddHtml(25, 348, 182, 18, String.Format("<center>{0}</center>", entry != null ? entry.Description : "Empty"), false, false);

            int hy = 284;
            int by = 289;

            AddHtmlLocalized(280, hy, 128, 18, 1077595, false, false); // Recall (Spell)
            AddButton(264, by, 2103, 2103, 4, GumpButtonType.Reply, 0);

            hy += 18;
            by += 18;
        /*
            if (Atlas.CurCharges != 0)
            {
                AddHtmlLocalized(280, hy, 128, 18, 1077594, false, false); // Recall (Charge)
                AddButton(264, by, 2103, 2103, 5, GumpButtonType.Reply, 0);

                hy += 18;
                by += 18;
            }
        */
            if (User.Skills[SkillName.Magery].Value >= 66.0)
            {
                AddHtmlLocalized(280, hy, 128, 18, 1015214, false, false); // Gate Travel
                AddButton(264, by, 2103, 2103, 6, GumpButtonType.Reply, 0);

                hy += 18;
                by += 18;
            }

            AddHtmlLocalized(280, hy, 128, 18, 1060502, false, false); // Sacred Journey
            AddButton(264, by, 2103, 2103, 7, GumpButtonType.Reply, 0);

            if (Page < 2)
            {
                AddButton(374, 3, 2206, 2206, 1150, GumpButtonType.Reply, 0);
            }

            if (Page > 0)
            {
                AddButton(23, 5, 2205, 2205, 1151, GumpButtonType.Reply, 0);
            }
        }

        public override void OnResponse(RelayInfo info)
        {
            if (info.ButtonID >= 100 && info.ButtonID < 1000)
            {
                SelectEntry(info.ButtonID - 100);
            }
            else
            {
                RunebookEntry entry = null;

                if (Selected >= 0 && Selected < Atlas.Entries.Count)
                {
                    entry = Atlas.Entries[Selected];
                }

                switch (info.ButtonID)
                {
                    case 0: Atlas.Openers.Remove(User); break;
                    case 1: RenameBook(); break;
                    case 2:
                        {
                            if (entry != null)
                            {
                                SetDefault();
                            }
                            else
                            {
                                Atlas.Openers.Remove(User);
                            }
                            break;
                        }                       
                    case 3:
                        {
                            if (entry != null)
                            {
                                DropRune(); break;
                            }
                            else
                            {
                                User.SendLocalizedMessage(502422); // There is no rune to be dropped.
                                Atlas.Openers.Remove(User);
                            }
                            break;
                        }
                    case 4:
                        {
                            if (entry != null)
                            {
                                RecallSpell();
                            }
                            else
                            {
                                User.SendLocalizedMessage(502423); // This place in the book is empty.
                                Atlas.Openers.Remove(User);
                            }
                            break;
                        }
                    case 5:
                        {
                            if (entry != null)
                            {
                                RecallCharge();
                            }
                            else
                            {
                                User.SendLocalizedMessage(502423); // This place in the book is empty.
                                Atlas.Openers.Remove(User);
                            }
                            break;
                        }
                    case 6:
                        {
                            if (entry != null)
                            {
                                GateTravel();
                            }
                            else
                            {
                                User.SendLocalizedMessage(502423); // This place in the book is empty.
                                Atlas.Openers.Remove(User);
                            }
                            break;
                        }
                    case 7:
                        {
                            if (entry != null)
                            {
                                SacredJourney();
                            }
                            else
                            {
                                User.SendLocalizedMessage(502423); // This place in the book is empty.
                                Atlas.Openers.Remove(User);
                            }
                            break;
                        }
                    case 1150:
                        Page++;
                        Refresh();
                        break;
                    case 1151:
                        Page--;
                        Refresh();
                        break;
                }
            }
        }

        public void RenameBook()
        {
            if (Atlas.CheckAccess(User) && Atlas.Movable != false || User.AccessLevel >= AccessLevel.GameMaster)
            {
                User.Prompt = new InternalPrompt(Atlas);
            }
            else
            {
                User.SendLocalizedMessage(502413); // That cannot be done while the book is locked down.
            }
        }

        private void SelectEntry(int id)
        {
            Atlas.Selected = id;
            Refresh();
        }

        private void SetDefault()
        {
            if (Atlas.CheckAccess(User) || User.AccessLevel >= AccessLevel.GameMaster)
            {
                Atlas.DefaultIndex = Selected;
                Refresh();
                User.SendLocalizedMessage(502417, "", 0x35); // New default location set.
            }
            else
            {
                Atlas.Openers.Remove(User);
                User.SendLocalizedMessage(502413, null, 0x35); // That cannot be done while the book is locked down.
            }
        }

        private void DropRune()
        {
            if (Atlas.CheckAccess(User) && Atlas.Movable != false || User.AccessLevel >= AccessLevel.GameMaster)
            {
                Atlas.DropRune(User, Atlas.Entries[Selected], Selected);
                Refresh();
            }
            else
            {
                Atlas.Openers.Remove(User);
                User.SendLocalizedMessage(502413, null, 0x35); // That cannot be done while the book is locked down.
            }
        }

        private void RecallSpell()
        {
            RunebookEntry e = Atlas.Entries[Selected];           

            if (RunebookGump.HasSpell(User, 31))
            {
                string coords = ToCoordinates(e.Location, e.Map);

                if (coords != "Nowhere")
                    User.SendMessage(ToCoordinates(e.Location, e.Map));

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

            Atlas.Openers.Remove(User);
        }

        private void RecallCharge()
        {
            RunebookEntry e = Atlas.Entries[Selected];

            if (Atlas.CurCharges <= 0)
            {
                Refresh();
                User.SendLocalizedMessage(502412); // There are no charges left on that item.
            }
            else
            {
                string coords = ToCoordinates(e.Location, e.Map);

                if (coords != "Nowhere")
                    User.SendMessage(ToCoordinates(e.Location, e.Map));

                Atlas.OnTravel();

                if (new RecallSpell(User, Atlas, e, Atlas).Cast())
                    Atlas.NextUse = DateTime.UtcNow;

                Atlas.Openers.Remove(User);
            }
        }

        private void GateTravel()
        {
            RunebookEntry e = Atlas.Entries[Selected];

            if (RunebookGump.HasSpell(User, 51))
            {
                string coords = ToCoordinates(e.Location, e.Map);

                if (coords != "Nowhere")
                    User.SendMessage(ToCoordinates(e.Location, e.Map));

                Atlas.OnTravel();

                if (new GateTravelSpell(User, null, e).Cast())
                    Atlas.NextUse = DateTime.UtcNow;
            }
            else
            {
                User.SendLocalizedMessage(500015); // You do not have that spell!
            }

            Atlas.Openers.Remove(User);
        }

        private void SacredJourney()
        {
            RunebookEntry e = Atlas.Entries[Selected];

            if (Core.AOS)
            {
                if (RunebookGump.HasSpell(User, 209))
                {
                    User.SendMessage(ToCoordinates(e.Location, e.Map));

                    Atlas.OnTravel();
                    new SacredJourneySpell(User, null, e, null).Cast();
                    Atlas.NextUse = DateTime.UtcNow;
                }
                else
                {
                    User.SendLocalizedMessage(500015); // You do not have that spell!
                }
            }

            Atlas.Openers.Remove(User);
        }

        private class InternalPrompt : Prompt
        {
            public override int MessageCliloc { get { return 502414; } } // Please enter a title for the runebook:
            public StaffAtlas Atlas { get; private set; }

            public InternalPrompt(StaffAtlas atlas)
            {
                Atlas = atlas;
            }

            public override void OnResponse(Mobile from, string text)
            {
                if (Atlas.Deleted || !from.InRange(Atlas.GetWorldLocation(), 3) || !(from is PlayerMobile))
                    return;

                if (Atlas.CheckAccess(from) || from.AccessLevel >= AccessLevel.GameMaster)
                {
                    Atlas.Description = Utility.FixHtml(text.Trim());
                    from.SendGump(new StaffAtlasGump((PlayerMobile)from, Atlas));
                    from.SendLocalizedMessage(1041531); // You have changed the title of the rune book.
                }
                else
                {
                    Atlas.Openers.Remove(from);
                    from.SendLocalizedMessage(502416); // That cannot be done while the book is locked down.
                }
            }

            public override void OnCancel(Mobile from)
            {
                from.SendLocalizedMessage(502415); // Request cancelled.

                if (from is PlayerMobile && !Atlas.Deleted && from.InRange(Atlas.GetWorldLocation(), (Core.ML ? 3 : 1)))
                {
                    from.SendGump(new StaffAtlasGump((PlayerMobile)from, Atlas));
                }
            }
        }
    }
}
Post automatically merged:

Wasn't there a Master Runebook somewhere inwhich we could add runebooks to it?
 
Last edited:
Wasn't there a Master Runebook somewhere inwhich we could add runebooks to it?

I made one of those way back on RunUO perhaps 10-15 years ago, so no clue if it would work on a current server. Anyway, I could probably rewrite it for the modern server, assuming I can find it again. (I have learned much better coding techniques since then.)

As to the Staff Runebook, I think it works like a standard runebook, so you just drop runes in it to keep adding. Not sure about the number of pages, nor what gives it the initial locations. That might be another script, because it does not appear to be in the code you posted.
 
Back