RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

[ Runuo 2.0 RC2] Custom Regions in a Box V4.0 [Updated]

aj9251

Sorceror
Would you mind running you're server in debug mode for me? I cant seem to replicate the crash.

Edit: Nvm got it. Working on it now..
 

aj9251

Sorceror
Fixed ALOT of script and hopefully most/all of the crashes. Please redownload on the first page. If you have any crashes/errors please post them with you're server in debug mode
 

Pure Insanity

Sorceror
Your fix for null crashes isn't really a fix...there are real ways of fixing it. Believe there was a valid fix posted for it on one of the other regions in a box threads.
 

aj9251

Sorceror
Your fix for null crashes isn't really a fix...there are real ways of fixing it. Believe there was a valid fix posted for it on one of the other regions in a box threads.
It works doesn't it??? I failed too see anyone else contribute anything towards fixing the errors. As for the posts on the other threads I was unable to find anything. Furthermore, if someone did find something I think it extremely selfish of them for not posting it on here and sharing their findings.. I guess thats what I get for spending the better part of my afternoon and most the evening debugging a 3 year old script.
 

Talow

Sorceror
Aj, I want to thank you for updating the script. And a fix is a fix, I mean really, just because it's not the way you would do it do not mean that the fix is any less valid. If you have a valid reason why the script isn't working that's one thing and should state that, IE did you have a crash with the fix? if so leave the report so he can look it over and adjust it to deal with the issue.
 

dazedmouse

Sorceror
Thank you very much for the fix. I had no crash with fix. Old script or not you should be proud that a lot of people still use your script.. And yes I agree Aj they should have posted a fix if they did get it working. Again Thank you for fixing this script...
 

nerun

Sorceror
This is the RegionControl.cs i use in my Distro, it works with RunUO 2.2, and fix z value, and RemoveAreaGump will be refreshed after added a new area:

Code:
/*
INCLUDED AT v4.0 FOR RC2:

@JeremyMCC
I've toyed around with the RegionControl.cs and have a fix that seems to work.
I've tested it pretty thoroughly and haven't had any crashes and the custom go location still
seems to work fine. Here's the fix, let me know how it works for everyone.
http://www.runuo.com/community/threads/runuo-2-0-rc1-custom-regions-in-a-box-v4-0.70170/page-6#post-543450

    @oii88
    Reported JeremyMCC changes did not works.
    http://www.runuo.com/community/threads/runuo-2-0-rc1-custom-regions-in-a-box-v4-0.70170/page-6#post-543461

@Datguy
Removed Custom Go Location
If you want no Crash/error, remove CustomGo in RegionControl.cs.
You'll not have the Region Go command for the custom regions you make but you'll not have crashes either.
http://www.runuo.com/community/threads/runuo-2-0-rc1-custom-regions-in-a-box-v4-0.70170/page-8#post-543495

INCLUDED AT v4.0 FOR NERUN'S DISTRO

@Lord Dio
Custom Regions in a Box 2.0 Final: Z value fix
http://www.runuo.com/community/threads/custom-regions-in-a-box-2-0-final-z-value-fix.102663/

@Nerun
Lines 873-877
RemoveAreaGump will be refreshed after added a new area
*/
using System;
using System.Collections.Generic;
using Server;
using Server.Mobiles;
using Server.Spells;
using Server.Items;
using Server.Regions;
using System.Collections;
using Server.SkillHandlers;
using Server.Gumps;

namespace Server.Items
{
    public enum RegionFlag : uint
    {
        None                =  0x00000000,
        AllowBenefitPlayer  =  0x00000001,
        AllowHarmPlayer    =  0x00000002,
        AllowHousing        =  0x00000004,
        AllowSpawn          =  0x00000008,

        CanBeDamaged        =  0x00000010,
        CanHeal            =  0x00000020,
        CanRessurect        =  0x00000040,
        CanUseStuckMenu    =  0x00000080,
        ItemDecay          =  0x00000100,

        ShowEnterMessage    =  0x00000200,
        ShowExitMessage    =  0x00000400,

        AllowBenefitNPC    =  0x00000800,
        AllowHarmNPC        =  0x00001000,

        CanMountEthereal    =  0x000002000,
        // ToDo: Change to "CanEnter"
        CanEnter            =  0x000004000,

        CanLootPlayerCorpse =  0x000008000,
        CanLootNPCCorpse    =  0x000010000,
        // ToDo: Change to "CanLootOwnCorpse"
        CanLootOwnCorpse    =  0x000020000,

        CanUsePotions      =  0x000040000,

        IsGuarded          =  0x000080000,

        // Obsolete, needed for old versions for DeSer.
        NoPlayerCorpses    =  0x000100000,
        NoItemDrop          =  0x000200000,
        //

        EmptyNPCCorpse      =  0x000400000,
        EmptyPlayerCorpse  =  0x000800000,
        DeleteNPCCorpse    =  0x001000000,
        DeletePlayerCorpse  =  0x002000000,
        ResNPCOnDeath      =  0x004000000,
        ResPlayerOnDeath    =  0x008000000,
        MoveNPCOnDeath      =  0x010000000,
        MovePlayerOnDeath  =  0x020000000,

        NoPlayerItemDrop    =  0x040000000,
        NoNPCItemDrop      =  0x080000000
    }

    public class RegionControl : Item
    {
        private static List<RegionControl> m_AllControls = new List<RegionControl>();

        public static List<RegionControl> AllControls
        {
            get { return m_AllControls; }
        }
 
        #region Region Flags

        private RegionFlag m_Flags;

        public RegionFlag Flags
        {
            get { return m_Flags; }
            set { m_Flags = value; }
        }

        public bool GetFlag(RegionFlag flag)
        {
            return ((m_Flags & flag) != 0);
        }

        public void SetFlag(RegionFlag flag, bool value)
        {
            if (value)
                m_Flags |= flag;
            else
            {
                m_Flags &= ~flag;
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool AllowBenefitPlayer
        {
            get { return GetFlag(RegionFlag.AllowBenefitPlayer); }
            set { SetFlag(RegionFlag.AllowBenefitPlayer, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool AllowHarmPlayer
        {
            get { return GetFlag(RegionFlag.AllowHarmPlayer); }
            set { SetFlag(RegionFlag.AllowHarmPlayer, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool AllowHousing
        {
            get { return GetFlag(RegionFlag.AllowHousing); }
            set { SetFlag(RegionFlag.AllowHousing, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool AllowSpawn
        {
            get { return GetFlag(RegionFlag.AllowSpawn); }
            set { SetFlag(RegionFlag.AllowSpawn, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool CanBeDamaged
        {
            get { return GetFlag(RegionFlag.CanBeDamaged); }
            set { SetFlag(RegionFlag.CanBeDamaged, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool CanMountEthereal
        {
            get { return GetFlag(RegionFlag.CanMountEthereal); }
            set { SetFlag(RegionFlag.CanMountEthereal, value); }
        }

        // ToDo: Change to "CanEnter"
        [CommandProperty(AccessLevel.GameMaster)]
        public bool CanEnter
        {
            get { return GetFlag(RegionFlag.CanEnter); }
            set { SetFlag(RegionFlag.CanEnter, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool CanHeal
        {
            get { return GetFlag(RegionFlag.CanHeal); }
            set { SetFlag(RegionFlag.CanHeal, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool CanRessurect
        {
            get { return GetFlag(RegionFlag.CanRessurect); }
            set { SetFlag(RegionFlag.CanRessurect, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool CanUseStuckMenu
        {
            get { return GetFlag(RegionFlag.CanUseStuckMenu); }
            set { SetFlag(RegionFlag.CanUseStuckMenu, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool ItemDecay
        {
            get { return GetFlag(RegionFlag.ItemDecay); }
            set { SetFlag(RegionFlag.ItemDecay, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool AllowBenefitNPC
        {
            get { return GetFlag(RegionFlag.AllowBenefitNPC); }
            set { SetFlag(RegionFlag.AllowBenefitNPC, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool AllowHarmNPC
        {
            get { return GetFlag(RegionFlag.AllowHarmNPC); }
            set { SetFlag(RegionFlag.AllowHarmNPC, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool ShowEnterMessage
        {
            get { return GetFlag(RegionFlag.ShowEnterMessage); }
            set { SetFlag(RegionFlag.ShowEnterMessage, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool ShowExitMessage
        {
            get { return GetFlag(RegionFlag.ShowExitMessage); }
            set { SetFlag(RegionFlag.ShowExitMessage, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool CanLootPlayerCorpse
        {
            get { return GetFlag(RegionFlag.CanLootPlayerCorpse); }
            set { SetFlag(RegionFlag.CanLootPlayerCorpse, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool CanLootNPCCorpse
        {
            get { return GetFlag(RegionFlag.CanLootNPCCorpse); }
            set { SetFlag(RegionFlag.CanLootNPCCorpse, value); }
        }

        // ToDo: Change to "CanLootOwnCorpse"
        [CommandProperty(AccessLevel.GameMaster)]
        public bool CanLootOwnCorpse
        {
            get { return GetFlag(RegionFlag.CanLootOwnCorpse); }
            set { SetFlag(RegionFlag.CanLootOwnCorpse, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool CanUsePotions
        {
            get { return GetFlag(RegionFlag.CanUsePotions); }
            set { SetFlag(RegionFlag.CanUsePotions, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool IsGuarded
        {
            get
            { return GetFlag(RegionFlag.IsGuarded); }
            set
            {
                SetFlag(RegionFlag.IsGuarded, value);
                if (m_Region != null)
                    m_Region.Disabled = !value;

                Timer.DelayCall(TimeSpan.FromSeconds(2.0), new TimerCallback(UpdateRegion));
            }
        }

        // OBSOLETE, needed for old Deser
        public bool NoPlayerCorpses
        {
            get { return GetFlag(RegionFlag.NoPlayerCorpses); }
            set { SetFlag(RegionFlag.NoPlayerCorpses, value); }
        }

        public bool NoItemDrop
        {
            get { return GetFlag(RegionFlag.NoItemDrop); }
            set { SetFlag(RegionFlag.NoItemDrop, value); }
        }
        // END OBSOLETE

        [CommandProperty(AccessLevel.GameMaster)]
        public bool EmptyNPCCorpse
        {
            get { return GetFlag(RegionFlag.EmptyNPCCorpse); }
            set { SetFlag(RegionFlag.EmptyNPCCorpse, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool EmptyPlayerCorpse
        {
            get { return GetFlag(RegionFlag.EmptyPlayerCorpse); }
            set { SetFlag(RegionFlag.EmptyPlayerCorpse, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool DeleteNPCCorpse
        {
            get { return GetFlag(RegionFlag.DeleteNPCCorpse); }
            set { SetFlag(RegionFlag.DeleteNPCCorpse, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool DeletePlayerCorpse
        {
            get { return GetFlag(RegionFlag.DeletePlayerCorpse); }
            set { SetFlag(RegionFlag.DeletePlayerCorpse, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool ResNPCOnDeath
        {
            get { return GetFlag(RegionFlag.ResNPCOnDeath); }
            set { SetFlag(RegionFlag.ResNPCOnDeath, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool ResPlayerOnDeath
        {
            get { return GetFlag(RegionFlag.ResPlayerOnDeath); }
            set { SetFlag(RegionFlag.ResPlayerOnDeath, value); }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool MoveNPCOnDeath
        {
            get { return GetFlag(RegionFlag.MoveNPCOnDeath); }
            set
            {
                if (MoveNPCToMap == null || MoveNPCToMap == Map.Internal || MoveNPCToLoc == Point3D.Zero)
                    SetFlag(RegionFlag.MoveNPCOnDeath, false);
                else
                    SetFlag(RegionFlag.MoveNPCOnDeath, value);
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool MovePlayerOnDeath
        {
            get { return GetFlag(RegionFlag.MovePlayerOnDeath); }
            set
            {
                if (MovePlayerToMap == null || MovePlayerToMap == Map.Internal || MovePlayerToLoc == Point3D.Zero)
                    SetFlag(RegionFlag.MovePlayerOnDeath, false);
                else
                    SetFlag(RegionFlag.MovePlayerOnDeath, value);
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool NoPlayerItemDrop
        {
            get { return GetFlag(RegionFlag.NoPlayerItemDrop); }
            set { SetFlag(RegionFlag.NoPlayerItemDrop, value); }
        }
 
        [CommandProperty(AccessLevel.GameMaster)]
        public bool NoNPCItemDrop
        {
            get { return GetFlag(RegionFlag.NoNPCItemDrop); }
            set { SetFlag(RegionFlag.NoNPCItemDrop, value); }
        }

        # endregion
 
        #region Region Restrictions

        private BitArray m_RestrictedSpells;
        private BitArray m_RestrictedSkills;

        public BitArray RestrictedSpells
        {
            get { return m_RestrictedSpells; }
        }

        public BitArray RestrictedSkills
        {
            get { return m_RestrictedSkills; }
        }

        # endregion
 
        # region Region Related Objects

        private CustomRegion m_Region;
        private Rectangle3D[] m_RegionArea;

        public CustomRegion Region
        {
            get { return m_Region; }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public Rectangle3D[] RegionArea
        {
            get { return m_RegionArea; }
            set { m_RegionArea = value; }
        }

        # endregion
 
        # region Control Properties

        private bool m_Active = true;

        [CommandProperty(AccessLevel.GameMaster)]
        public bool Active
        {
            get { return m_Active; }
            set
            {
                if (m_Active != value)
                {
                    m_Active = value;
                    UpdateRegion();
                }
            }

        }

        # endregion
 
        # region Region Properties

        private string m_RegionName;
        private int m_RegionPriority;
        private MusicName m_Music;
        private TimeSpan m_PlayerLogoutDelay;
        private int m_LightLevel;

        private Map m_MoveNPCToMap;
        private Point3D m_MoveNPCToLoc;
        private Map m_MovePlayerToMap;
        private Point3D m_MovePlayerToLoc;

        [CommandProperty(AccessLevel.GameMaster)]
        public string RegionName
        {
            get { return m_RegionName; }
            set
            {
                if (Map != null && !RegionNameTaken(value))
                    m_RegionName = value;
                else if (Map != null)
                    Console.WriteLine("RegionName not changed for {0}, {1} already has a Region with the name of {2}", this, Map, value);
                else if(Map == null)
                    Console.WriteLine("RegionName not changed for {0} to {1}, it's Map value was null", this, value);

                UpdateRegion();
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public int RegionPriority
        {
            get { return m_RegionPriority; }
            set
            {
                m_RegionPriority = value;
                UpdateRegion();
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public MusicName Music
        {
            get { return m_Music; }
            set
            {
                m_Music = value;
                UpdateRegion();
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public TimeSpan PlayerLogoutDelay
        {
            get{ return m_PlayerLogoutDelay; }
            set
            {
                m_PlayerLogoutDelay = value;
                UpdateRegion();
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public int LightLevel
        {
            get { return m_LightLevel; }
            set
            {
                m_LightLevel = value;
                UpdateRegion();
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public Map MoveNPCToMap
        {
            get { return m_MoveNPCToMap; }
            set
            {
                if (value != Map.Internal)
                    m_MoveNPCToMap = value;
                else
                    SetFlag(RegionFlag.MoveNPCOnDeath, false);
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public Point3D MoveNPCToLoc
        {
            get { return m_MoveNPCToLoc; }
            set
            {
                if (value != Point3D.Zero)
                    m_MoveNPCToLoc = value;
                else
                    SetFlag(RegionFlag.MoveNPCOnDeath, false);
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public Map MovePlayerToMap
        {
            get { return m_MovePlayerToMap; }
            set
            {
                if (value != Map.Internal)
                    m_MovePlayerToMap = value;
                else
                    SetFlag(RegionFlag.MovePlayerOnDeath, false);
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public Point3D MovePlayerToLoc
        {
            get { return m_MovePlayerToLoc; }
            set
            {
                if (value != Point3D.Zero)
                    m_MovePlayerToLoc = value;
                else
                    SetFlag(RegionFlag.MovePlayerOnDeath, false);
            }
        }

      // REMOVED
        /*
        private Point3D m_CustomGoLocation;

        [CommandProperty(AccessLevel.GameMaster)]
        public Point3D CustomGoLocation
        {
            get { return m_Region.GoLocation; }
            set
            {
                m_Region.GoLocation = value;
                m_CustomGoLocation = value;
                UpdateRegion();
            }
        }
        */

        # endregion
 
        [Constructable]
        public RegionControl() : base ( 5609 )
        {
            Visible = false;
            Movable = false;
            Name = "Region Controller";

            if (m_AllControls == null)
                m_AllControls = new List<RegionControl>();
            m_AllControls.Add(this);

            m_RegionName = FindNewName("Custom Region");
            m_RegionPriority = CustomRegion.DefaultPriority;

            m_RestrictedSpells = new BitArray(SpellRegistry.Types.Length);
            m_RestrictedSkills = new BitArray(SkillInfo.Table.Length);
        }

        [Constructable]
        public RegionControl(Rectangle2D rect): base(5609)
        {
            Visible = false;
            Movable = false;
            Name = "Region Controller";

            if (m_AllControls == null)
                m_AllControls = new List<RegionControl>();
            m_AllControls.Add(this);

            m_RegionName = FindNewName("Custom Region");
            m_RegionPriority = CustomRegion.DefaultPriority;

            m_RestrictedSpells = new BitArray(SpellRegistry.Types.Length);
            m_RestrictedSkills = new BitArray(SkillInfo.Table.Length);

            Rectangle3D newrect = Server.Region.ConvertTo3D(rect);
            DoChooseArea(null, this.Map, newrect.Start, newrect.End, this);

            UpdateRegion();
        }

        [Constructable]
        public RegionControl(Rectangle3D rect): base(5609)
        {
            Visible = false;
            Movable = false;
            Name = "Region Controller";

            if (m_AllControls == null)
                m_AllControls = new List<RegionControl>();
            m_AllControls.Add(this);

            m_RegionName = FindNewName("Custom Region");
            m_RegionPriority = CustomRegion.DefaultPriority;

            m_RestrictedSpells = new BitArray(SpellRegistry.Types.Length);
            m_RestrictedSkills = new BitArray(SkillInfo.Table.Length);

            DoChooseArea(null, this.Map, rect.Start, rect.End, this);

            UpdateRegion();
        }

        [Constructable]
        public RegionControl(Rectangle2D[] rects): base(5609)
        {
            Visible = false;
            Movable = false;
            Name = "Region Controller";

            if (m_AllControls == null)
                m_AllControls = new List<RegionControl>();
            m_AllControls.Add(this);

            m_RegionName = FindNewName("Custom Region");
            m_RegionPriority = CustomRegion.DefaultPriority;

            m_RestrictedSpells = new BitArray(SpellRegistry.Types.Length);
            m_RestrictedSkills = new BitArray(SkillInfo.Table.Length);

            foreach (Rectangle2D rect2d in rects)
            {
                Rectangle3D newrect = Server.Region.ConvertTo3D(rect2d);
                DoChooseArea(null, this.Map, newrect.Start, newrect.End, this);
            }

            UpdateRegion();
        }

        [Constructable]
        public RegionControl(Rectangle3D[] rects): base(5609)
        {
            Visible = false;
            Movable = false;
            Name = "Region Controller";

            if (m_AllControls == null)
                m_AllControls = new List<RegionControl>();
            m_AllControls.Add(this);

            m_RegionName = FindNewName("Custom Region");
            m_RegionPriority = CustomRegion.DefaultPriority;

            m_RestrictedSpells = new BitArray(SpellRegistry.Types.Length);
            m_RestrictedSkills = new BitArray(SkillInfo.Table.Length);

            foreach (Rectangle3D rect3d in rects)
            {
                DoChooseArea(null, this.Map, rect3d.Start, rect3d.End, this);
            }

            UpdateRegion();
        }

        public RegionControl( Serial serial ) : base( serial )
        {
        }
 
        #region Control Special Voids

        public bool RegionNameTaken(string testName)
        {

            if (m_AllControls != null)
            {
                foreach (RegionControl control in m_AllControls)
                {
                    if (control.RegionName == testName && control != this)
                        return true;
                }
            }

            return false;
        }

        public string FindNewName(string oldName)
        {
            int i = 1;

            string newName = oldName;
            while( RegionNameTaken(newName) )
            {
                newName = oldName;
                newName += String.Format(" {0}", i);
                i++;
            }

            return newName;
        }

        public void UpdateRegion()
        {
            if (m_Region != null)
                m_Region.Unregister();

            if (this.Map != null && this.Active)
            {
                if (this != null && this.RegionArea != null && this.RegionArea.Length > 0)
                {
                    m_Region = new CustomRegion(this);
                    // m_Region.GoLocation = m_CustomGoLocation;  // REMOVED
                    m_Region.Register();
                }
                else
                    m_Region = null;
            }
            else
                m_Region = null;
        }

        public void RemoveArea(int index, Mobile from)
        {
            try
            {
                List<Rectangle3D> rects = new List<Rectangle3D>();
                foreach (Rectangle3D rect in m_RegionArea)
                    rects.Add(rect);

                rects.RemoveAt(index);
                m_RegionArea = rects.ToArray();

                UpdateRegion();
                from.SendMessage("Area Removed!");
            }
            catch
            {
                from.SendMessage("Removing of Area Failed!");
            }
        }
        public static int GetRegistryNumber(ISpell s)
        {
            Type[] t = SpellRegistry.Types;

            for (int i = 0; i < t.Length; i++)
            {
                if (s.GetType() == t[i])
                    return i;
            }

            return -1;
        }
 
        public bool IsRestrictedSpell(ISpell s)
        {

            if (m_RestrictedSpells.Length != SpellRegistry.Types.Length)
            {

                m_RestrictedSpells = new BitArray(SpellRegistry.Types.Length);

                for (int i = 0; i < m_RestrictedSpells.Length; i++)
                    m_RestrictedSpells[i] = false;

            }

            int regNum = GetRegistryNumber(s);
 
            if (regNum < 0)    //Happens with unregistered Spells
                return false;

            return m_RestrictedSpells[regNum];
        }

        public bool IsRestrictedSkill(int skill)
        {
            if (m_RestrictedSkills.Length != SkillInfo.Table.Length)
            {

                m_RestrictedSkills = new BitArray(SkillInfo.Table.Length);

                for (int i = 0; i < m_RestrictedSkills.Length; i++)
                    m_RestrictedSkills[i] = false;

            }

            if (skill < 0)
                return false;
 
            return m_RestrictedSkills[skill];
        }

        public void ChooseArea(Mobile m)
        {
            BoundingBoxPicker.Begin(m, new BoundingBoxCallback(CustomRegion_Callback), this);
        }

        public void CustomRegion_Callback(Mobile from, Map map, Point3D start, Point3D end, object state)
        {
            DoChooseArea(from, map, start, end, state);
        }

        public void DoChooseArea(Mobile from, Map map, Point3D start, Point3D end, object control)
        {
            if (this != null)
            {
                List<Rectangle3D> areas = new List<Rectangle3D>();

                if (this.m_RegionArea != null)
                {
                    foreach (Rectangle3D rect in this.m_RegionArea)
                        areas.Add(rect);
                }
// Added Lord Dio's Z Value Fix
                if (start.Z == end.Z || start.Z < end.Z)
                {
                    if (start.Z != Server.Region.MinZ)
                        start.Z = Server.Region.MinZ;
                    if (end.Z != Server.Region.MaxZ)
                        end.Z = Server.Region.MaxZ;
                }
                else
                {
                    if (start.Z != Server.Region.MaxZ)
                        start.Z = Server.Region.MaxZ;
                    if (end.Z != Server.Region.MinZ)
                        end.Z = Server.Region.MinZ;
                }

                Rectangle3D newrect = new Rectangle3D(start, end);
                areas.Add(newrect);

                this.m_RegionArea = areas.ToArray();

                this.UpdateRegion();
// Added by nerun, so the RemoveAreaGump will be refreshed after added a new area
                from.CloseGump( typeof( RegionControlGump ) );
                from.SendGump( new RegionControlGump( this ) );
                from.CloseGump( typeof( RemoveAreaGump ) );
                from.SendGump( new RemoveAreaGump( this ) );
            }
        }

        # endregion
 
        #region Control Overrides

        public override void OnDoubleClick(Mobile m)
        {
            if (m.AccessLevel >= AccessLevel.GameMaster)
            {
                if (m_RestrictedSpells.Length != SpellRegistry.Types.Length)
                {
                    m_RestrictedSpells = new BitArray(SpellRegistry.Types.Length);

                    for (int i = 0; i < m_RestrictedSpells.Length; i++)
                        m_RestrictedSpells[i] = false;

                    m.SendMessage("Resetting all restricted Spells due to Spell change");
                }

                if (m_RestrictedSkills.Length != SkillInfo.Table.Length)
                {

                    m_RestrictedSkills = new BitArray(SkillInfo.Table.Length);

                    for (int i = 0; i < m_RestrictedSkills.Length; i++)
                        m_RestrictedSkills[i] = false;

                    m.SendMessage("Resetting all restricted Skills due to Skill change");

                }

                m.CloseGump(typeof(RegionControlGump));
                m.SendGump(new RegionControlGump(this));
                m.SendMessage("Don't forget to props this object for more options!");
                m.CloseGump(typeof(RemoveAreaGump));
                m.SendGump(new RemoveAreaGump(this));
            }
        }

        public override void OnMapChange()
        {
            UpdateRegion();
            base.OnMapChange();
        }

        public override void OnDelete()
        {
            if (m_Region != null)
                m_Region.Unregister();

            if (m_AllControls != null)
                m_AllControls.Remove(this);

            base.OnDelete();
        }

        # endregion
 
        #region Ser/Deser Helpers

        public static void WriteBitArray(GenericWriter writer, BitArray ba)
        {
            writer.Write(ba.Length);

            for (int i = 0; i < ba.Length; i++)
            {
                writer.Write(ba[i]);
            }
            return;
        }

        public static BitArray ReadBitArray(GenericReader reader)
        {
            int size = reader.ReadInt();

            BitArray newBA = new BitArray(size);

            for (int i = 0; i < size; i++)
            {
                newBA[i] = reader.ReadBool();
            }

            return newBA;
        }
 
        public static void WriteRect3DArray(GenericWriter writer, Rectangle3D[] ary)
        {
            if (ary == null)
            {
                writer.Write(0);
                return;
            }

            writer.Write(ary.Length);

            for (int i = 0; i < ary.Length; i++)
            {
                Rectangle3D rect = ((Rectangle3D)ary[i]);
                writer.Write((Point3D)rect.Start);
                writer.Write((Point3D)rect.End);
            }
            return;
        }

        public static List<Rectangle2D> ReadRect2DArray(GenericReader reader)
        {
            int size = reader.ReadInt();
            List<Rectangle2D> newAry = new List<Rectangle2D>();

            for (int i = 0; i < size; i++)
            {
                newAry.Add(reader.ReadRect2D());
            }

            return newAry;
        }

        public static Rectangle3D[] ReadRect3DArray(GenericReader reader)
        {
            int size = reader.ReadInt();
            List<Rectangle3D> newAry = new List<Rectangle3D>();

            for (int i = 0; i < size; i++)
            {
                Point3D start = reader.ReadPoint3D();
                Point3D end = reader.ReadPoint3D();
                newAry.Add(new Rectangle3D(start,end));
            }

            return newAry.ToArray();
        }

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

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

            // writer.Write((Point3D)CustomGoLocation);  // REMOVED

            WriteRect3DArray(writer, m_RegionArea);

            writer.Write((int)m_Flags);

            WriteBitArray(writer, m_RestrictedSpells);
            WriteBitArray(writer, m_RestrictedSkills);

            writer.Write((bool)m_Active);

            writer.Write((string)m_RegionName);
            writer.Write((int)m_RegionPriority);
            writer.Write((int)m_Music);
            writer.Write((TimeSpan)m_PlayerLogoutDelay);
            writer.Write((int)m_LightLevel);

            writer.Write((Map)m_MoveNPCToMap);
            writer.Write((Point3D)m_MoveNPCToLoc);
            writer.Write((Map)m_MovePlayerToMap);
            writer.Write((Point3D)m_MovePlayerToLoc);
        }

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

            int version = reader.ReadInt();

            // Point3D customGoLoc = new Point3D(0,0,0); // REMOVED
            switch (version)
            {
                // New RunUO 2.0 Version (case 5 and 4)
                case 5:
                {
                    // customGoLoc = reader.ReadPoint3D(); // REMOVED
                    goto case 4;
                }
                case 4:
                {
                    m_RegionArea = ReadRect3DArray(reader);

                    m_Flags = (RegionFlag)reader.ReadInt();

                    m_RestrictedSpells = ReadBitArray(reader);
                    m_RestrictedSkills = ReadBitArray(reader);

                    m_Active = reader.ReadBool();

                    m_RegionName = reader.ReadString();
                    m_RegionPriority = reader.ReadInt();
                    m_Music = (MusicName)reader.ReadInt();
                    m_PlayerLogoutDelay = reader.ReadTimeSpan();
                    m_LightLevel = reader.ReadInt();

                    m_MoveNPCToMap = reader.ReadMap();
                    m_MoveNPCToLoc = reader.ReadPoint3D();
                    m_MovePlayerToMap = reader.ReadMap();
                    m_MovePlayerToLoc = reader.ReadPoint3D();

                    break;
                }

                // Old RunUO 1.0 Version (cases 3-0)
                case 3:
                {
                    m_LightLevel = reader.ReadInt();
                    goto case 2;
                }
                case 2:
                {
                    m_Music = (MusicName)reader.ReadInt();
                    goto case 1;
                }
                case 1:
                {
                    List<Rectangle2D> rects2d = ReadRect2DArray(reader);
                    foreach (Rectangle2D rect in rects2d)
                    {
                        Rectangle3D newrect = Server.Region.ConvertTo3D(rect);
                        DoChooseArea(null, this.Map, newrect.Start, newrect.End, this);
                    }

                    m_RegionPriority = reader.ReadInt();
                    m_PlayerLogoutDelay = reader.ReadTimeSpan();

                    m_RestrictedSpells = ReadBitArray(reader);
                    m_RestrictedSkills = ReadBitArray(reader);

                    m_Flags = (RegionFlag)reader.ReadInt();
                    if (NoPlayerCorpses)
                    {
                        DeleteNPCCorpse = true;
                        DeletePlayerCorpse = true;
                    }
                    if (NoItemDrop)
                    {
                        NoPlayerItemDrop = true;
                        NoNPCItemDrop = true;
                    }
                    // Invert because of change from "Cannot" to "Can"
                    if (CanLootOwnCorpse)
                    {
                        CanLootOwnCorpse = false;
                    }
                    if (CanEnter)
                    {
                        CanEnter = false;
                    }

                    m_RegionName = reader.ReadString();
                    break;
                }
                case 0:
                {
                    List<Rectangle2D> rects2d = ReadRect2DArray(reader);
                    foreach (Rectangle2D rect in rects2d)
                    {
                        Rectangle3D newrect = Server.Region.ConvertTo3D(rect);
                        DoChooseArea(null, this.Map, newrect.Start, newrect.End, this);
                    }

                    m_RestrictedSpells = ReadBitArray(reader);
                    m_RestrictedSkills = ReadBitArray(reader);

                    m_Flags = (RegionFlag)reader.ReadInt();
                    if (NoPlayerCorpses)
                    {
                        DeleteNPCCorpse = true;
                        DeletePlayerCorpse = true;
                    }
                    if (NoItemDrop)
                    {
                        NoPlayerItemDrop = true;
                        NoNPCItemDrop = true;
                    }
                    // Invert because of change from "Cannot" to "Can"
                    if (CanLootOwnCorpse)
                    {
                        CanLootOwnCorpse = false;
                    }
                    if (CanEnter)
                    {
                        CanEnter = false;
                    }

                    m_RegionName = reader.ReadString();
                    break;
                }
            }

            m_AllControls.Add(this);

            if(RegionNameTaken(m_RegionName))
                m_RegionName = FindNewName(m_RegionName);

            UpdateRegion();
          // m_CustomGoLocation = customGoLoc;  // REMOVED
          // CustomGoLocation = customGoLoc;  // REMOVED
            UpdateRegion();
        }
    }
}
 

aj9251

Sorceror
Hi guys, I want to apologise for my outburst in my prior post. I have been going through some tough times this week. I know there is really no place on the forums for venting such rage. Thanks guys for understanding. Also thank you Nerun for you're script post as well.
 

Teagan

Sorceror
OK, don't know what I'm doing wrong. I set up a region control flag on a champion spawn to delete NPC corpses. In the green acres (trammel and felucca), the DeleteNPCCorpse wouldn't work, so I had to move the priority to 5000 (at 500, not all the corpses were being deleted, half remained). At 5000, it worked for my player character for some quick tests no problem. I set up a region control flag in Destard Felucca at the Rikktor spawn and got everything done (deleted default region when you first create a control flag). I do simple [kill with my owner character and get this.

Code:
Server Crash Report
===================
 
RunUO Version 2.0, Build 3567.2838
Operating System: Microsoft Windows NT 5.1.2600 Service Pack 2
.NET Framework: 2.0.50727.42
Time: 1/24/2012 9:53:20 AM
Mobiles: 38178
Items: 192033
Exception:
System.NullReferenceException: Object reference not set to an instance of an object.
  at Server.Regions.CustomRegion.OnDeath(Mobile m)
  at Server.Mobile.Kill()
  at Server.Commands.Generic.KillCommand.Execute(CommandEventArgs e, Object obj)
  at Server.Commands.Generic.BaseCommandImplementor.RunCommand(Mobile from, Object obj, BaseCommand command, String[] args)
  at Server.Commands.Generic.SingleCommandImplementor.OnTarget(Mobile from, Object targeted, Object state)
  at Server.Mobile.SimpleStateTarget.OnTarget(Mobile from, Object targeted)
  at Server.Targeting.Target.Invoke(Mobile from, Object targeted)
  at Server.Network.PacketHandlers.TargetResponse(NetState state, PacketReader pvSrc)
  at Server.Network.MessagePump.HandleReceive(NetState ns)
  at Server.Network.MessagePump.Slice()
  at Server.Core.Main(String[] args)
 
Clients:
- Count: 1
+ 127.0.0.1: (account = Spanky) (mobile = 0x21 'Mr Jingles')

I restart, get the same area set up and use the player character and it crashes again on very first kill. This time, when I killed a lizardman and the shard crashes, the lizardman is replaced with a gray human bare naked.
Code:
Server Crash Report
===================
 
RunUO Version 2.0, Build 3567.2838
Operating System: Microsoft Windows NT 5.1.2600 Service Pack 2
.NET Framework: 2.0.50727.42
Time: 1/24/2012 10:00:37 AM
Mobiles: 38199
Items: 191510
Exception:
System.NullReferenceException: Object reference not set to an instance of an object.
  at Server.Regions.CustomRegion.OnDeath(Mobile m)
  at Server.Mobile.Kill()
  at Server.Mobile.Damage(Int32 amount, Mobile from, Boolean informMount)
  at Server.Mobile.Damage(Int32 amount, Mobile from)
  at Server.Mobiles.BaseCreature.Damage(Int32 amount, Mobile from)
  at Server.AOS.Damage(Mobile m, Mobile from, Int32 damage, Boolean ignoreArmor, Int32 phys, Int32 fire, Int32 cold, Int32 pois, Int32 nrgy, Boolean keepAlive)
  at Server.Items.BaseWeapon.OnHit(Mobile attacker, Mobile defender, Double damageBonus)
  at Server.Items.BasePoleArm.OnHit(Mobile attacker, Mobile defender, Double damageBonus)
  at Server.Items.BaseWeapon.OnSwing(Mobile attacker, Mobile defender, Double damageBonus)
  at Server.Items.BaseWeapon.OnSwing(Mobile attacker, Mobile defender)
  at Server.Mobile.CombatTimer.OnTick()
  at Server.Timer.Slice()
  at Server.Core.Main(String[] args)
 
Clients:
- Count: 1
+ 127.0.0.1: (account = Wooldor) (mobile = 0x6 'Husky Dumper')

2.0 Final Repack with Custom Regions 5.0.

Code:
Server Crash Report
===================

RunUO Version 2.0, Build 3567.2838
Operating System: Microsoft Windows NT 5.1.2600 Service Pack 2
.NET Framework: 2.0.50727.42
Time: 1/24/2012 12:11:12 PM
Mobiles: 38192
Items: 191440
Exception:
System.NullReferenceException: Object reference not set to an instance of an object.
   at Server.Regions.CustomRegion.OnDeath(Mobile m)
   at Server.Mobile.Kill()
   at Server.Mobile.Damage(Int32 amount, Mobile from, Boolean informMount)
   at Server.Mobile.Damage(Int32 amount, Mobile from)
   at Server.Mobiles.BaseCreature.Damage(Int32 amount, Mobile from)
   at Server.AOS.Damage(Mobile m, Mobile from, Int32 damage, Boolean ignoreArmor, Int32 phys, Int32 fire, Int32 cold, Int32 pois, Int32 nrgy, Boolean keepAlive)
   at Server.Items.BaseWeapon.OnHit(Mobile attacker, Mobile defender, Double damageBonus)
   at Server.Items.BasePoleArm.OnHit(Mobile attacker, Mobile defender, Double damageBonus)
   at Server.Items.BaseWeapon.OnSwing(Mobile attacker, Mobile defender, Double damageBonus)
   at Server.Items.BaseWeapon.OnSwing(Mobile attacker, Mobile defender)
   at Server.Mobile.CombatTimer.OnTick()
   at Server.Timer.Slice()
   at Server.Core.Main(String[] args)

Clients:
- Count: 1
+ 127.0.0.1: (account = Wooldor) (mobile = 0x6 'Husky Dumper')
Got this while testing the Underworld Dungeon script. Same priority level, same gray humanoid standing when enemy AI fell.
 

Iraq-

Sorceror
Make certain you have a null check in the OnDeath method of CustomRegion.cs

It should look like this:
Code:
  if ( m != null && !m.Deleted)
            {

You also should run your server with "-debug" so you get a better crash report (with filenames and line numbers).
 

ArisBB

Sorceror
Would be great a button that mark all spells ans other to skills... and can edit the enter and exit text mensage =D
 

Miracle99

Squire
Question to anyone using this mod. If you dont allow certain spells in a custom region a player is still able to pre cast the spell outside of the region and then run into the region and still use that spell.

Does anyone have a way to stop this?
 
yeah pretty simple build a blockade at the boundry of your area and force the player to tele into the area or non-automated gate *use the kind with ok gump* to get rid of their target icon is a quick and effective way to stop that
 

Miracle99

Squire
Thanks Black. I actually just decided to edit the SpellHelper.cs file and added my own region there to stop from being able to mark in the region.
 
Top