Пример #1
0
 public void Visit(CellCoord standing_cell, Visitor visitor, Map map, WorldObject obj, float radius)
 {
     //we should increase search radius by object's radius, otherwise
     //we could have problems with huge creatures, which won't attack nearest players etc
     Visit(standing_cell, visitor, map, obj.GetPositionX(), obj.GetPositionY(), radius + obj.GetObjectSize());
 }
Пример #2
0
        public void Visit(CellCoord standing_cell, Visitor visitor, Map map, float x_off, float y_off, float radius)
        {
            if (!standing_cell.IsCoordValid())
            {
                return;
            }

            //no jokes here... Actually placing ASSERT() here was good idea, but
            //we had some problems with DynamicObjects, which pass radius = 0.0f (DB issue?)
            //maybe it is better to just return when radius <= 0.0f?
            if (radius <= 0.0f)
            {
                map.Visit(this, visitor);
                return;
            }
            //lets limit the upper value for search radius
            if (radius > MapConst.SizeofGrids)
            {
                radius = MapConst.SizeofGrids;
            }

            //lets calculate object coord offsets from cell borders.
            CellArea area = CalculateCellArea(x_off, y_off, radius);

            //if radius fits inside standing cell
            if (area == null)
            {
                map.Visit(this, visitor);
                return;
            }

            //visit all cells, found in CalculateCellArea()
            //if radius is known to reach cell area more than 4x4 then we should call optimized VisitCircle
            //currently this technique works with MAX_NUMBER_OF_CELLS 16 and higher, with lower values
            //there are nothing to optimize because SIZE_OF_GRID_CELL is too big...
            if ((area.high_bound.X_coord > (area.low_bound.X_coord + 4)) && (area.high_bound.Y_coord > (area.low_bound.Y_coord + 4)))
            {
                VisitCircle(visitor, map, area.low_bound, area.high_bound);
                return;
            }

            //ALWAYS visit standing cell first!!! Since we deal with small radiuses
            //it is very essential to call visitor for standing cell firstly...
            map.Visit(this, visitor);

            // loop the cell range
            for (uint x = area.low_bound.X_coord; x <= area.high_bound.X_coord; ++x)
            {
                for (uint y = area.low_bound.Y_coord; y <= area.high_bound.Y_coord; ++y)
                {
                    CellCoord cellCoord = new CellCoord(x, y);
                    //lets skip standing cell since we already visited it
                    if (cellCoord != standing_cell)
                    {
                        Cell r_zone = new Cell(cellCoord);
                        r_zone.data.nocreate = data.nocreate;
                        map.Visit(r_zone, visitor);
                    }
                }
            }
        }
Пример #3
0
 public CellArea(CellCoord low, CellCoord high)
 {
     low_bound  = low;
     high_bound = high;
 }
Пример #4
0
        void LoadHelper <T>(SortedSet <ulong> guid_set, CellCoord cell, ref uint count, Map map) where T : WorldObject, new()
        {
            foreach (var guid in guid_set)
            {
                T obj = new T();
                // Don't spawn at all if there's a respawn time
                if ((obj.IsTypeId(TypeId.Unit) && map.GetCreatureRespawnTime(guid) == 0) || (obj.IsTypeId(TypeId.GameObject) && map.GetGORespawnTime(guid) == 0))
                {
                    //TC_LOG_INFO("misc", "DEBUG: LoadHelper from table: %s for (guid: %u) Loading", table, guid);
                    if (obj.IsTypeId(TypeId.Unit))
                    {
                        CreatureData cdata = Global.ObjectMgr.GetCreatureData(guid);
                        Cypher.Assert(cdata != null, $"Tried to load creature with spawnId {guid}, but no such creature exists.");

                        SpawnGroupTemplateData group = cdata.spawnGroupData;
                        // If creature in manual spawn group, don't spawn here, unless group is already active.
                        if (!group.flags.HasAnyFlag(SpawnGroupFlags.System))
                        {
                            if (!map.IsSpawnGroupActive(group.groupId))
                            {
                                obj.Dispose();
                                continue;
                            }
                        }

                        // If script is blocking spawn, don't spawn but queue for a re-check in a little bit
                        if (!group.flags.HasFlag(SpawnGroupFlags.CompatibilityMode) && !Global.ScriptMgr.CanSpawn(guid, cdata.Id, cdata, map))
                        {
                            map.SaveRespawnTime(SpawnObjectType.Creature, guid, cdata.Id, Time.UnixTime + RandomHelper.URand(4, 7), map.GetZoneId(PhasingHandler.EmptyPhaseShift, cdata.spawnPoint), GridDefines.ComputeGridCoord(cdata.spawnPoint.GetPositionX(), cdata.spawnPoint.GetPositionY()).GetId(), false);
                            obj.Dispose();
                            continue;
                        }
                    }
                    else if (obj.IsTypeId(TypeId.GameObject))
                    {
                        // If gameobject in manual spawn group, don't spawn here, unless group is already active.
                        GameObjectData godata = Global.ObjectMgr.GetGameObjectData(guid);
                        Cypher.Assert(godata != null, $"Tried to load gameobject with spawnId {guid}, but no such object exists.");

                        if (!godata.spawnGroupData.flags.HasAnyFlag(SpawnGroupFlags.System))
                        {
                            if (!map.IsSpawnGroupActive(godata.spawnGroupData.groupId))
                            {
                                obj.Dispose();
                                continue;
                            }
                        }
                    }

                    if (!obj.LoadFromDB(guid, map, false, false))
                    {
                        obj.Dispose();
                        continue;
                    }
                    AddObjectHelper(cell, ref count, map, obj);
                }
                else
                {
                    obj.Dispose();
                }
            }
        }