Esempio n. 1
0
        private void PlaceElementsInZone(DOL.GS.Collections.Hashtable elements)
        {
            DOL.GS.Collections.DictionaryEntry currentEntry = null;
            ArrayList      currentList         = null;
            SubNodeElement currentStartElement = null;
            SubNodeElement currentElement      = null;

            IEnumerator entryEnumerator = elements.GetEntryEnumerator();

            while (entryEnumerator.MoveNext())
            {
                currentEntry        = (DOL.GS.Collections.DictionaryEntry)entryEnumerator.Current;
                currentStartElement = (SubNodeElement)currentEntry.key;

                currentList = (ArrayList)currentEntry.value;

                lock (currentStartElement)
                {
                    for (int i = 0; i < currentList.Count; i++)
                    {
                        currentElement = (SubNodeElement)currentList[i];
                        currentStartElement.PushBack(currentElement);
                    }
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Handles movement of objects from zone to zone
        /// </summary>
        /// <param name="objectType"></param>
        /// <param name="element"></param>
        private void ObjectEnterZone(eGameObjectType objectType, SubNodeElement element)
        {
            if (!m_initialized)
            {
                InitializeZone();
            }
            int subZoneIndex = GetSubZoneIndex(element.data);

            if (log.IsDebugEnabled)
            {
                log.Debug("Object " + element.data.ObjectID + "(" + objectType + ") entering (inner) subzone " + subZoneIndex + " in zone " + this.ID + " in region " + m_Region.ID);
            }

            if ((subZoneIndex >= 0) && (subZoneIndex < SUBZONE_NBR))
            {
                int type = (int)objectType;

                lock (m_subZoneElements[subZoneIndex][type])
                {
                    // add to subzone list
                    m_subZoneElements[subZoneIndex][type].PushBack(element);
                }

                Interlocked.Increment(ref m_objectCount);
            }
        }
Esempio n. 3
0
 /// <summary>
 /// Insert a node before this one
 /// </summary>
 /// <param name="p_elem">The node to insert</param>
 public void PushBack(SubNodeElement p_elem)
 {
     p_elem.previous = this;
     p_elem.next     = next;
     next.previous   = p_elem;
     next            = p_elem;
 }
Esempio n. 4
0
        private void PlaceElementsInOtherZones(DOL.GS.Collections.Hashtable elements)
        {
            DOL.GS.Collections.DictionaryEntry currentEntry = null;

            int       currentType = 0;
            ArrayList currentList = null;

            Zone           currentZone    = null;
            SubNodeElement currentElement = null;

            IEnumerator entryEnumerator = elements.GetEntryEnumerator();

            while (entryEnumerator.MoveNext())
            {
                currentEntry = (DOL.GS.Collections.DictionaryEntry)entryEnumerator.Current;
                currentType  = (int)currentEntry.key;

                currentList = (ArrayList)currentEntry.value;

                for (int i = 0; i < currentList.Count; i++)
                {
                    currentElement = (SubNodeElement)currentList[i];
                    currentZone    = ZoneRegion.GetZone(currentElement.data.Position);

                    if (currentZone != null)
                    {
                        currentZone.ObjectEnterZone((eGameObjectType)currentType, currentElement);
                    }
                }
            }
        }
Esempio n. 5
0
        private void UnsafeAddToListWithoutDistanceCheck(SubNodeElement startElement, int typeIndex, int subZoneIndex, ArrayList partialList, DOL.GS.Collections.Hashtable inZoneElements, DOL.GS.Collections.Hashtable outOfZoneElements)
        {
            SubNodeElement currentElement  = startElement.next;
            SubNodeElement elementToRemove = null;
            GameObject     currentObject   = null;

            do
            {
                currentObject = currentElement.data;
                if (ShouldElementMove(currentElement, typeIndex, subZoneIndex, inZoneElements, outOfZoneElements))
                {
                    elementToRemove = currentElement;
                    currentElement  = currentElement.next;

                    elementToRemove.Remove();

                    if (log.IsDebugEnabled)
                    {
                        log.Debug("Zone" + ID + ": " + ((currentObject != null) ? "object " + currentObject.ObjectID : "ghost object") + " removed for subzone");
                    }
                }
                else
                {
                    // the current object exists, is Active and still in the current subzone
                    // => add it
                    if (!partialList.Contains(currentObject))
                    {
                        partialList.Add(currentObject);
                    }

                    currentElement = currentElement.next;
                }
            } while (currentElement != startElement);
        }
Esempio n. 6
0
            /// <summary>
            /// Remove this node from the list
            /// </summary>
            public void Remove()
            {
                if (previous != this)
                {
                    previous.next = next;
                    next.previous = previous;
                }

                previous = this;
                next     = this;
            }
Esempio n. 7
0
        /// <summary>
        /// Handle a GameObject entering a zone
        /// </summary>
        /// <param name="p_Obj">The GameObject object</param>
        public void ObjectEnterZone(GameObject p_Obj)
        {
            if (!m_initialized)
            {
                InitializeZone();
            }

            int subZoneIndex = GetSubZoneIndex(p_Obj);

            if ((subZoneIndex >= 0) && (subZoneIndex < SUBZONE_NBR))
            {
                SubNodeElement element = new SubNodeElement();
                element.data = p_Obj;

                int type = -1;

                // Only GamePlayer, GameNPC and GameStaticItem classes
                // are handled.
                if (p_Obj is GamePlayer)
                {
                    type = (int)eGameObjectType.PLAYER;
                }
                else if (p_Obj is GameNPC)
                {
                    type = (int)eGameObjectType.NPC;
                }
                else if (p_Obj is GameStaticItem)
                {
                    type = (int)eGameObjectType.ITEM;
                }
                else if (p_Obj is IDoor)
                {
                    type = (int)eGameObjectType.DOOR;
                }

                if (type == -1)
                {
                    return;
                }

                if (log.IsDebugEnabled)
                {
                    log.Debug($"Object {p_Obj.ObjectID} ({(eGameObjectType)type}) entering subzone {subZoneIndex} in zone {ID} in region {ZoneRegion.ID}");
                }

                lock (m_subZoneElements[subZoneIndex][type])
                {
                    // add to subzone list
                    m_subZoneElements[subZoneIndex][type].PushBack(element);
                }

                Interlocked.Increment(ref m_objectCount);
            }
        }
Esempio n. 8
0
        private void UnsafeAddToListWithDistanceCheck(
            SubNodeElement startElement,
            float x,
            float y,
            float z,
            uint sqRadius,
            int typeIndex,
            int subZoneIndex,
            ArrayList partialList,
            DOL.GS.Collections.Hashtable inZoneElements,
            DOL.GS.Collections.Hashtable outOfZoneElements,
            bool ignoreZ)
        {
            // => check all distances for all objects in the subzone

            SubNodeElement currentElement  = startElement.next;
            SubNodeElement elementToRemove = null;
            GameObject     currentObject   = null;

            do
            {
                currentObject = currentElement.data;

                if (ShouldElementMove(currentElement, typeIndex, subZoneIndex, inZoneElements, outOfZoneElements))
                {
                    elementToRemove = currentElement;
                    currentElement  = currentElement.next;

                    elementToRemove.Remove();

                    if (log.IsDebugEnabled)
                    {
                        log.Debug("Zone" + ID + ": " + ((currentObject != null) ? "object " + currentObject.ObjectID : "ghost object") + " removed for subzone");
                    }
                }
                else
                {
                    if (CheckSquareDistance(x, y, z, currentObject.Position.X, currentObject.Position.Y, currentObject.Position.Z, sqRadius, ignoreZ) && !partialList.Contains(currentObject))
                    {
                        // the current object exists, is Active and still in the current subzone
                        // moreover it is in the right range and not yet in the result set
                        // => add it
                        partialList.Add(currentObject);
                    }

                    currentElement = currentElement.next;
                }
            } while (currentElement != startElement);
        }
Esempio n. 9
0
 private void InitializeZone()
 {
     if (m_initialized)
     {
         return;
     }
     for (int i = 0; i < SUBZONE_NBR; i++)
     {
         m_subZoneElements[i] = new SubNodeElement[4];
         for (int k = 0; k < m_subZoneElements[i].Length; k++)
         {
             m_subZoneElements[i][k] = new SubNodeElement();
         }
     }
     m_subZoneTimestamps = new int[SUBZONE_NBR << 2];
     m_initialized       = true;
 }
Esempio n. 10
0
        private void UnsafeAddToListWithoutDistanceCheck(SubNodeElement startElement, int typeIndex, int subZoneIndex, ArrayList partialList, DOL.GS.Collections.Hashtable inZoneElements, DOL.GS.Collections.Hashtable outOfZoneElements)
        {
            SubNodeElement currentElement = startElement.next;
            SubNodeElement elementToRemove = null;
            GameObject currentObject = null;

            do
            {
                currentObject = currentElement.data;
                if (ShouldElementMove(currentElement, typeIndex, subZoneIndex, inZoneElements, outOfZoneElements))
                {
                    elementToRemove = currentElement;
                    currentElement = currentElement.next;

                    elementToRemove.Remove();

                    if (log.IsDebugEnabled)
                    {
                        log.Debug("Zone" + ID + ": " + ((currentObject != null) ? "object " + currentObject.ObjectID : "ghost object") + " removed for subzone");
                    }
                }
                else
                {
                    // the current object exists, is Active and still in the current subzone
                    // => add it
                    if (!partialList.Contains(currentObject))
                    {
                        partialList.Add(currentObject);
                    }

                    currentElement = currentElement.next;
                }
            } while (currentElement != startElement);
        }
Esempio n. 11
0
        private void UnsafeAddToListWithDistanceCheck(
            SubNodeElement startElement,
            int x,
            int y,
            int z,
            uint sqRadius,
            int typeIndex,
            int subZoneIndex,
            ArrayList partialList,
            DOL.GS.Collections.Hashtable inZoneElements,
            DOL.GS.Collections.Hashtable outOfZoneElements,
            bool ignoreZ)
        {
            // => check all distances for all objects in the subzone

            SubNodeElement currentElement = startElement.next;
            SubNodeElement elementToRemove = null;
            GameObject currentObject = null;

            do
            {
                currentObject = currentElement.data;

                if (ShouldElementMove(currentElement, typeIndex, subZoneIndex, inZoneElements, outOfZoneElements))
                {
                    elementToRemove = currentElement;
                    currentElement = currentElement.next;

                    elementToRemove.Remove();

                    if (log.IsDebugEnabled)
                    {
                        log.Debug("Zone" + ID + ": " + ((currentObject != null) ? "object " + currentObject.ObjectID : "ghost object") + " removed for subzone");
                    }
                }
                else
                {
                    if (CheckSquareDistance(x, y, z, currentObject.X, currentObject.Y, currentObject.Z, sqRadius, ignoreZ) && !partialList.Contains(currentObject))
                    {
                        // the current object exists, is Active and still in the current subzone
                        // moreover it is in the right range and not yet in the result set
                        // => add it
                        partialList.Add(currentObject);
                    }

                    currentElement = currentElement.next;
                }
            } while (currentElement != startElement);
        }
Esempio n. 12
0
        private bool ShouldElementMove(SubNodeElement currentElement, int typeIndex, int subZoneIndex, DOL.GS.Collections.Hashtable inZoneElements, DOL.GS.Collections.Hashtable outOfZoneElements)
        {
            if (!m_initialized) InitializeZone();
            bool removeElement = true;
            GameObject currentObject = currentElement.data;

            if ((currentObject != null) &&
                (((int)currentObject.ObjectState) == (int)GameObject.eObjectState.Active)
                && (currentObject.CurrentRegion == ZoneRegion))
            {
                // the current object exists, is Active and still in the Region where this Zone is located

                int currentElementSubzoneIndex = GetSubZoneIndex(currentObject.X, currentObject.Y);

                if (currentElementSubzoneIndex == -1)
                {
                    // the object has moved in another Zone in the same Region

                    ArrayList movedElements = (ArrayList)outOfZoneElements[typeIndex];

                    if (movedElements == null)
                    {
                        movedElements = new ArrayList();
                        outOfZoneElements[typeIndex] = movedElements;
                    }

                    movedElements.Add(currentElement);

                    Interlocked.Decrement(ref m_objectCount);
                }
                else
                {
                    // the object is still inside this Zone

                    if (removeElement = (currentElementSubzoneIndex != subZoneIndex))
                    {
                        // it has changed of subzone
                        SubNodeElement newSubZoneStartElement = m_subZoneElements[currentElementSubzoneIndex][typeIndex];
                        ArrayList movedElements = (ArrayList)inZoneElements[newSubZoneStartElement];

                        if (movedElements == null)
                        {
                            movedElements = new ArrayList();
                            inZoneElements[newSubZoneStartElement] = movedElements;
                        }

                        // make it available for relocation
                        movedElements.Add(currentElement);
                    }
                }
            }
            else
            {
                // ghost object
                // => remove it

                Interlocked.Decrement(ref m_objectCount);
            }

            return removeElement;
        }
Esempio n. 13
0
        /// <summary>
        /// Handles movement of objects from zone to zone
        /// </summary>
        /// <param name="objectType"></param>
        /// <param name="element"></param>
        private void ObjectEnterZone(eGameObjectType objectType, SubNodeElement element)
        {
            if (!m_initialized) InitializeZone();
            int subZoneIndex = GetSubZoneIndex(element.data);

            if (log.IsDebugEnabled)
            {
                log.Debug("Object " + element.data.ObjectID + "(" + objectType + ") entering (inner) subzone " + subZoneIndex + " in zone " + this.ID + " in region " + m_Region.ID);
            }

            if ((subZoneIndex >= 0) && (subZoneIndex < SUBZONE_NBR))
            {
                int type = (int)objectType;

                lock (m_subZoneElements[subZoneIndex][type])
                {
                    // add to subzone list
                    m_subZoneElements[subZoneIndex][type].PushBack(element);
                }

                Interlocked.Increment(ref m_objectCount);
            }
        }
Esempio n. 14
0
 private void InitializeZone()
 {
     if (m_initialized) return;
     for (int i = 0; i < SUBZONE_NBR; i++)
     {
         m_subZoneElements[i] = new SubNodeElement[4];
         for (int k = 0; k < m_subZoneElements[i].Length; k++)
         {
             m_subZoneElements[i][k] = new SubNodeElement();
         }
     }
     m_subZoneTimestamps = new int[SUBZONE_NBR << 2];
     m_initialized = true;
 }
Esempio n. 15
0
        /// <summary>
        /// Get NPCs of a zone given various parameters
        /// </summary>
        /// <param name="realms"></param>
        /// <param name="minLevel"></param>
        /// <param name="maxLevel"></param>
        /// <param name="compareLevel"></param>
        /// <param name="conLevel"></param>
        /// <param name="firstOnly"></param>
        /// <returns></returns>
        public List <GameNPC> GetNPCsOfZone(eRealm[] realms, int minLevel, int maxLevel, int compareLevel, int conLevel, bool firstOnly)
        {
            List <GameNPC> list = new List <GameNPC>();

            try
            {
                if (!m_initialized)
                {
                    InitializeZone();
                }
                // select random starting subzone and iterate over all objects in subzone than in all subzone...
                int     currentSubZoneIndex = Util.Random(SUBZONE_NBR);
                int     startSubZoneIndex   = currentSubZoneIndex;
                GameNPC currentNPC          = null;
                bool    stopSearching       = false;
                do
                {
                    SubNodeElement startElement = m_subZoneElements[currentSubZoneIndex][(int)eGameObjectType.NPC];
                    lock (startElement)
                    {
                        // if list is not empty
                        if (startElement != startElement.next)
                        {
                            SubNodeElement curElement = startElement.next;
                            do
                            {
                                currentNPC = (GameNPC)curElement.data;
                                bool added = false;
                                // Check for specified realms
                                for (int i = 0; i < realms.Length; ++i)
                                {
                                    eRealm realm = realms[i];
                                    if (currentNPC.Realm == realm)
                                    {
                                        // Check for min-max level, if any specified
                                        bool addToList = true;
                                        if (compareLevel > 0 && conLevel > 0)
                                        {
                                            addToList = ((int)GameObject.GetConLevel(compareLevel, currentNPC.Level) == conLevel);
                                        }
                                        else
                                        {
                                            if (minLevel > 0 && currentNPC.Level < minLevel)
                                            {
                                                addToList = false;
                                            }
                                            if (maxLevel > 0 && currentNPC.Level > maxLevel)
                                            {
                                                addToList = false;
                                            }
                                        }
                                        if (addToList)
                                        {
                                            list.Add(currentNPC);
                                            added = true;
                                            break;
                                        }
                                    }
                                }
                                // If we have added and must return one only result,
                                // then mark for stop searching
                                if (firstOnly && added)
                                {
                                    stopSearching = true;
                                    break;
                                }
                                curElement = curElement.next;
                            } while (curElement != startElement);
                        }
                    }
                    if (++currentSubZoneIndex >= SUBZONE_NBR)
                    {
                        currentSubZoneIndex = 0;
                    }
                    // If stop searching forced, then exit
                    if (stopSearching)
                    {
                        break;
                    }
                } while (currentSubZoneIndex != startSubZoneIndex);
            }
            catch (Exception ex)
            {
                log.Error("GetNPCsOfZone: Caught Exception for zone " + Description + ".", ex);
            }

            return(list);
        }
Esempio n. 16
0
        private bool ShouldElementMove(SubNodeElement currentElement, int typeIndex, int subZoneIndex, DOL.GS.Collections.Hashtable inZoneElements, DOL.GS.Collections.Hashtable outOfZoneElements)
        {
            if (!m_initialized)
            {
                InitializeZone();
            }
            bool       removeElement = true;
            GameObject currentObject = currentElement.data;

            if ((currentObject != null) &&
                (((int)currentObject.ObjectState) == (int)GameObject.eObjectState.Active) &&
                (currentObject.CurrentRegion == ZoneRegion))
            {
                // the current object exists, is Active and still in the Region where this Zone is located

                int currentElementSubzoneIndex = GetSubZoneIndex(currentObject.Position.X, currentObject.Position.Y);

                if (currentElementSubzoneIndex == -1)
                {
                    // the object has moved in another Zone in the same Region

                    ArrayList movedElements = (ArrayList)outOfZoneElements[typeIndex];

                    if (movedElements == null)
                    {
                        movedElements = new ArrayList();
                        outOfZoneElements[typeIndex] = movedElements;
                    }

                    movedElements.Add(currentElement);

                    Interlocked.Decrement(ref m_objectCount);
                }
                else
                {
                    // the object is still inside this Zone

                    if (removeElement = (currentElementSubzoneIndex != subZoneIndex))
                    {
                        // it has changed of subzone
                        SubNodeElement newSubZoneStartElement = m_subZoneElements[currentElementSubzoneIndex][typeIndex];
                        ArrayList      movedElements          = (ArrayList)inZoneElements[newSubZoneStartElement];

                        if (movedElements == null)
                        {
                            movedElements = new ArrayList();
                            inZoneElements[newSubZoneStartElement] = movedElements;
                        }

                        // make it available for relocation
                        movedElements.Add(currentElement);
                    }
                }
            }
            else
            {
                // ghost object
                // => remove it

                Interlocked.Decrement(ref m_objectCount);
            }

            return(removeElement);
        }
Esempio n. 17
0
            /// <summary>
            /// Remove this node from the list
            /// </summary>
            public void Remove()
            {
                if (previous != this)
                {
                    previous.next = next;
                    next.previous = previous;
                }

                previous = this;
                next = this;
            }
Esempio n. 18
0
 public SubNodeElement()
 {
     next = this;
     previous = this;
 }
Esempio n. 19
0
        /// <summary>
        /// Gets the lists of objects, located in the current Zone and of the given type, that are at most at a 'radius' distance from (x,y,z)
        /// The found objects are appended to the given 'partialList'.
        /// </summary>
        /// <param name="type">the type of objects to look for</param>
        /// <param name="x">the x coordinate of the observation position</param>
        /// <param name="y">the y coordinate of the observation position</param>
        /// <param name="z">the z coordinate of the observation position</param>
        /// <param name="radius">the radius to check against</param>
        /// <param name="partialList">an initial (eventually empty but initialized, i.e. never null !!) list of objects</param>
        /// <returns>partialList augmented with the new objects verigying both type and radius in the current Zone</returns>
        internal ArrayList GetObjectsInRadius(eGameObjectType type, float x, float y, float z, ushort radius, ArrayList partialList, bool ignoreZ)
        {
            if (!m_initialized)
            {
                InitializeZone();
            }
            // initialise parameters
            uint sqRadius = (uint)radius * (uint)radius;
            int  referenceSubzoneIndex = GetSubZoneIndex(x, y);
            int  typeIndex             = (int)type;

            int xInZone = (int)(x - m_XOffset);             // x in zone coordinates
            int yInZone = (int)(y - m_YOffset);             // y in zone coordinates

            int cellNbr = (radius >> SUBZONE_SHIFT) + 1;    // radius in terms of subzone number
            int xInCell = xInZone >> SUBZONE_SHIFT;         // xInZone in terms of subzone coord
            int yInCell = yInZone >> SUBZONE_SHIFT;         // yInZone in terms of subzone coord

            int minColumn = xInCell - cellNbr;

            if (minColumn < 0)
            {
                minColumn = 0;
            }

            int maxColumn = xInCell + cellNbr;

            if (maxColumn > (SUBZONE_NBR_ON_ZONE_SIDE - 1))
            {
                maxColumn = SUBZONE_NBR_ON_ZONE_SIDE - 1;
            }

            int minLine = yInCell - cellNbr;

            if (minLine < 0)
            {
                minLine = 0;
            }

            int maxLine = yInCell + cellNbr;

            if (maxLine > (SUBZONE_NBR_ON_ZONE_SIDE - 1))
            {
                maxLine = SUBZONE_NBR_ON_ZONE_SIDE - 1;
            }

            DOL.GS.Collections.Hashtable inZoneElements    = new DOL.GS.Collections.Hashtable();
            DOL.GS.Collections.Hashtable outOfZoneElements = new DOL.GS.Collections.Hashtable();

            for (int currentLine = minLine; currentLine <= maxLine; ++currentLine)
            {
                int            currentSubZoneIndex = 0;
                SubNodeElement startElement        = null;

                for (int currentColumn = minColumn; currentColumn <= maxColumn; ++currentColumn)
                {
                    currentSubZoneIndex = GetSubZoneOffset(currentLine, currentColumn);

                    // get the right list of objects
                    startElement = m_subZoneElements[currentSubZoneIndex][typeIndex];

                    if (startElement != startElement.next)
                    {                     // allow dirty read here to enable a more efficient and fine grained locking later...
                        // the current subzone contains some objects

                        if (currentSubZoneIndex == referenceSubzoneIndex)
                        {
                            lock (startElement)
                            {
                                // we are in the subzone of the observation point
                                // => check all distances for all objects in the subzone
                                UnsafeAddToListWithDistanceCheck(startElement, x, y, z, sqRadius, typeIndex, currentSubZoneIndex, partialList, inZoneElements, outOfZoneElements, ignoreZ);
                                UnsafeUpdateSubZoneTimestamp(currentSubZoneIndex, typeIndex);
                            }
                        }
                        else
                        {
                            int xLeft   = currentColumn << SUBZONE_SHIFT;
                            int xRight  = xLeft + SUBZONE_SIZE;
                            int yTop    = currentLine << SUBZONE_SHIFT;
                            int yBottom = yTop + SUBZONE_SIZE;

                            if (CheckMinDistance(xInZone, yInZone, xLeft, xRight, yTop, yBottom, sqRadius))
                            {
                                // the minimum distance is smaller than radius

                                if (CheckMaxDistance(xInZone, yInZone, xLeft, xRight, yTop, yBottom, sqRadius))
                                {
                                    // the current subzone is fully enclosed within the radius
                                    // => add all the objects of the current subzone

                                    lock (startElement)
                                    {
                                        UnsafeAddToListWithoutDistanceCheck(startElement, typeIndex, currentSubZoneIndex, partialList, inZoneElements, outOfZoneElements);
                                        UnsafeUpdateSubZoneTimestamp(currentSubZoneIndex, typeIndex);
                                    }
                                }
                                else
                                {
                                    // the current subzone is partially enclosed within the radius
                                    // => only add the objects within the right area

                                    lock (startElement)
                                    {
                                        UnsafeAddToListWithDistanceCheck(startElement, x, y, z, sqRadius, typeIndex, currentSubZoneIndex, partialList, inZoneElements, outOfZoneElements, ignoreZ);
                                        UnsafeUpdateSubZoneTimestamp(currentSubZoneIndex, typeIndex);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            //
            // perform needed relocations
            //

            if (inZoneElements.Count > 0)
            {
                PlaceElementsInZone(inZoneElements);

                if (log.IsDebugEnabled)
                {
                    log.Debug("Zone" + ID + " " + inZoneElements.Count + " objects moved inside zone");
                }
            }

            if (outOfZoneElements.Count > 0)
            {
                PlaceElementsInOtherZones(outOfZoneElements);

                if (log.IsDebugEnabled)
                {
                    log.Debug("Zone" + ID + " " + outOfZoneElements.Count + " objects moved outside zone");
                }
            }


            return(partialList);
        }
Esempio n. 20
0
 /// <summary>
 /// Insert a node before this one
 /// </summary>
 /// <param name="p_elem">The node to insert</param>
 public void PushBack(SubNodeElement p_elem)
 {
     p_elem.previous = this;
     p_elem.next = next;
     next.previous = p_elem;
     next = p_elem;
 }
Esempio n. 21
0
        internal void Relocate(object state)
        {
            if (!m_initialized)
            {
                return;
            }
            if (m_objectCount > 0)
            {
                SubNodeElement startElement   = null;
                SubNodeElement currentElement = null;

                SubNodeElement elementToRemove = null;

                DOL.GS.Collections.Hashtable outOfZoneElements = new DOL.GS.Collections.Hashtable();
                DOL.GS.Collections.Hashtable inZoneElements    = new DOL.GS.Collections.Hashtable();

                for (int subZoneIndex = 0; subZoneIndex < m_subZoneElements.Length; subZoneIndex++)
                {
                    for (int typeIndex = 0; typeIndex < m_subZoneElements[subZoneIndex].Length; typeIndex++)
                    {
                        if (Environment.TickCount > m_subZoneTimestamps[(subZoneIndex << 2) | typeIndex])
                        {
                            // it is time to relocate some elements in this subzone
                            // => perform needed relocations of elements
                            startElement = m_subZoneElements[subZoneIndex][typeIndex];

                            lock (startElement)
                            {
                                if (startElement != startElement.next)
                                {
                                    // there are some elements in the list

                                    currentElement = startElement.next;

                                    do
                                    {
                                        if (ShouldElementMove(currentElement, typeIndex, subZoneIndex, inZoneElements, outOfZoneElements))
                                        {
                                            elementToRemove = currentElement;
                                            currentElement  = currentElement.next;

                                            elementToRemove.Remove();

                                            if (log.IsDebugEnabled)
                                            {
                                                log.Debug("Zone" + ID + " object " + elementToRemove.data.ObjectID + " removed for subzone");
                                            }
                                        }
                                        else
                                        {
                                            currentElement = currentElement.next;
                                        }
                                    } while (currentElement != startElement);

                                    UnsafeUpdateSubZoneTimestamp(subZoneIndex, typeIndex);
                                }
                            }
                        }
                    }
                }


                if (inZoneElements.Count > 0)
                {
                    PlaceElementsInZone(inZoneElements);

                    if (log.IsDebugEnabled)
                    {
                        log.Debug("Zone" + ID + " " + inZoneElements.Count + " objects moved inside zone");
                    }
                }

                if (outOfZoneElements.Count > 0)
                {
                    PlaceElementsInOtherZones(outOfZoneElements);

                    if (log.IsDebugEnabled)
                    {
                        log.Debug("Zone" + ID + " " + outOfZoneElements.Count + " objects moved outside zone");
                    }
                }
            }
        }
Esempio n. 22
0
        /// <summary>
        /// Handle a GameObject entering a zone
        /// </summary>
        /// <param name="p_Obj">The GameObject object</param>
        public void ObjectEnterZone(GameObject p_Obj)
        {
            if (!m_initialized) InitializeZone();
            int subZoneIndex = GetSubZoneIndex(p_Obj);
            if ((subZoneIndex >= 0) && (subZoneIndex < SUBZONE_NBR))
            {
                SubNodeElement element = new SubNodeElement();
                element.data = p_Obj;

                int type = -1;

                //Only GamePlayer, GameNPC and GameStaticItem classes
                //are handled.
                if (p_Obj is GamePlayer)
                    type = (int)eGameObjectType.PLAYER;
                else if (p_Obj is GameNPC)
                    type = (int)eGameObjectType.NPC;
                else if (p_Obj is GameStaticItem)
                    type = (int)eGameObjectType.ITEM;
                else if (p_Obj is IDoor)
                    type = (int)eGameObjectType.DOOR;

                if (type == -1)
                    return;

                if (log.IsDebugEnabled)
                {
                    log.Debug("Object " + p_Obj.ObjectID + " (" + ((eGameObjectType)type) + ") entering subzone " + subZoneIndex + " in zone " + this.ID + " in region " + m_Region.ID);
                }

                lock (m_subZoneElements[subZoneIndex][type])
                {
                    // add to subzone list
                    m_subZoneElements[subZoneIndex][type].PushBack(element);
                }

                Interlocked.Increment(ref m_objectCount);
            }
        }
Esempio n. 23
0
 public SubNodeElement()
 {
     next     = this;
     previous = this;
 }