<commit_before>using ACE.Entity;
using System;
using System.Numerics;
using ACE.Server.Physics.Common;
using ACE.Server.Physics.Extensions;
using ACE.Server.Physics.Util;
using Position = ACE.Entity.Position;

namespace ACE.Server.Entity
{
    public static class PositionExtensions
    {
        public static Vector3 ToGlobal(this Position p)
        {
            var landblock = LScape.get_landblock(p.LandblockId.Raw);

            if (landblock.IsDungeon)
                return p.Pos;

            var x = p.LandblockId.LandblockX * Position.BlockLength + p.PositionX;
            var y = p.LandblockId.LandblockY * Position.BlockLength + p.PositionY;
            var z = p.PositionZ;

            return new Vector3(x, y, z);
        }

        public static Position FromGlobal(this Position p, Vector3 pos)
        {
            var landblock = LScape.get_landblock(p.LandblockId.Raw);

            if (landblock.IsDungeon)
            {
                var iPos = new Position();
                iPos.LandblockId = p.LandblockId;
                iPos.Pos = new Vector3(pos.X, pos.Y, pos.Z);
                iPos.Rotation = p.Rotation;
                iPos.LandblockId = new LandblockId(GetCell(iPos));
                return iPos;
            }

            var blockX = (uint)pos.X / Position.BlockLength;
            var blockY = (uint)pos.Y / Position.BlockLength;

            var localX = pos.X % Position.BlockLength;
            var localY = pos.Y % Position.BlockLength;

            var landblockID = blockX << 24 | blockY << 16 | 0xFFFF;

            var position = new Position();
            position.LandblockId = new LandblockId((byte)blockX, (byte)blockY);
            position.PositionX = localX;
            position.PositionY = localY;
            position.PositionZ = pos.Z;
            position.Rotation = p.Rotation;
            position.LandblockId = new LandblockId(GetCell(position));
            return position;
        }

        /// <summary>
        /// Gets the cell ID for a position within a landblock
        /// </summary>
        public static uint GetCell(this Position p)
        {
            var landblock = LScape.get_landblock(p.LandblockId.Raw);

            // dungeons
            if (landblock.IsDungeon)
                return GetIndoorCell(p);

            // outside - could be on landscape, in building, or underground cave
            var cellID = GetOutdoorCell(p);
            var landcell = (LandCell)LScape.get_landcell(cellID);
            if (landcell.has_building())
            {
                var envCells = landcell.Building.get_building_cells();
                foreach (var envCell in envCells)
                    if (envCell.point_in_cell(p.Pos))
                        return envCell.ID;
            }

            // handle underground areas ie. caves
            // get the terrain Z-height for this X/Y
            Physics.Polygon walkable = null;
            var terrainPoly = landcell.find_terrain_poly(p.Pos, ref walkable);
            if (walkable != null)
            {
                Vector3 terrainPos = p.Pos;
                walkable.Plane.set_height(ref terrainPos);

                // are we below ground? if so, search all of the indoor cells for this landblock
                if (terrainPos.Z > p.Pos.Z)
                {
                    var envCells = landblock.get_envcells();
                    foreach (var envCell in envCells)
                        if (envCell.point_in_cell(p.Pos))
                            return envCell.ID;
                }
            }
            return cellID;
        }

        /// <summary>
        /// Gets an outdoor cell ID for a position within a landblock
        /// </summary>
        private static uint GetOutdoorCell(this Position p)
        {
            var cellX = (uint)p.PositionX / Position.CellLength;
            var cellY = (uint)p.PositionY / Position.CellLength;

            var cellID = cellX * Position.CellSide + cellY + 1;

            var blockCellID = (uint)((p.LandblockId.Raw & 0xFFFF0000) | cellID);
            return blockCellID;
        }

        /// <summary>
        /// Gets an indoor cell ID for a position within a dungeon
        /// </summary>
        private static uint GetIndoorCell(this Position p)
        {
            var adjustCell = AdjustCell.Get(p.Landblock);
            var envCell = adjustCell.GetCell(p.Pos);
            if (envCell != null)
                return envCell.Value;
            else
                return p.Cell;
        }

        /// <summary>
        /// Returns the greatest single-dimension square distance between 2 positions
        /// </summary>
        public static uint CellDist(this Position p1, Position p2)
        {
            if (!p1.Indoors && !p2.Indoors)
            {
                return Math.Max(p1.GlobalCellX, p1.GlobalCellY);
            }

            // handle dungeons
            /*var block1 = LScape.get_landblock(p1.LandblockId.Raw);
            var block2 = LScape.get_landblock(p2.LandblockId.Raw);
            if (block1.IsDungeon || block2.IsDungeon)
            {
                // 2 separate dungeons = infinite distance
                if (block1.ID != block2.ID)
                    return uint.MaxValue;

                return GetDungeonCellDist(p1, p2);
            }*/

            var _p1 = new Position(p1);
            var _p2 = new Position(p2);

            if (_p1.Indoors)
                _p1.LandblockId = new LandblockId(_p1.GetOutdoorCell());
            if (_p2.Indoors)
                _p2.LandblockId = new LandblockId(_p2.GetIndoorCell());

            return Math.Max(_p1.GlobalCellX, _p2.GlobalCellY);
        }

        public static uint GetDungeonCellDist(Position p1, Position p2)
        {
            // not implemented yet
            return uint.MaxValue;
        }
    }
}
<commit_msg>Handle null result from LScape.get_landcell() in GetCell() (#1135)<commit_after>using ACE.Entity;
using System;
using System.Numerics;
using ACE.Server.Physics.Common;
using ACE.Server.Physics.Extensions;
using ACE.Server.Physics.Util;
using Position = ACE.Entity.Position;

namespace ACE.Server.Entity
{
    public static class PositionExtensions
    {
        public static Vector3 ToGlobal(this Position p)
        {
            var landblock = LScape.get_landblock(p.LandblockId.Raw);

            if (landblock.IsDungeon)
                return p.Pos;

            var x = p.LandblockId.LandblockX * Position.BlockLength + p.PositionX;
            var y = p.LandblockId.LandblockY * Position.BlockLength + p.PositionY;
            var z = p.PositionZ;

            return new Vector3(x, y, z);
        }

        public static Position FromGlobal(this Position p, Vector3 pos)
        {
            var landblock = LScape.get_landblock(p.LandblockId.Raw);

            if (landblock.IsDungeon)
            {
                var iPos = new Position();
                iPos.LandblockId = p.LandblockId;
                iPos.Pos = new Vector3(pos.X, pos.Y, pos.Z);
                iPos.Rotation = p.Rotation;
                iPos.LandblockId = new LandblockId(GetCell(iPos));
                return iPos;
            }

            var blockX = (uint)pos.X / Position.BlockLength;
            var blockY = (uint)pos.Y / Position.BlockLength;

            var localX = pos.X % Position.BlockLength;
            var localY = pos.Y % Position.BlockLength;

            var landblockID = blockX << 24 | blockY << 16 | 0xFFFF;

            var position = new Position();
            position.LandblockId = new LandblockId((byte)blockX, (byte)blockY);
            position.PositionX = localX;
            position.PositionY = localY;
            position.PositionZ = pos.Z;
            position.Rotation = p.Rotation;
            position.LandblockId = new LandblockId(GetCell(position));
            return position;
        }

        /// <summary>
        /// Gets the cell ID for a position within a landblock
        /// </summary>
        public static uint GetCell(this Position p)
        {
            var landblock = LScape.get_landblock(p.LandblockId.Raw);

            // dungeons
            if (landblock.IsDungeon)
                return GetIndoorCell(p);

            // outside - could be on landscape, in building, or underground cave
            var cellID = GetOutdoorCell(p);
            var landcell = (LandCell)LScape.get_landcell(cellID);

            if (landcell == null)
                return cellID;

            if (landcell.has_building())
            {
                var envCells = landcell.Building.get_building_cells();
                foreach (var envCell in envCells)
                    if (envCell.point_in_cell(p.Pos))
                        return envCell.ID;
            }

            // handle underground areas ie. caves
            // get the terrain Z-height for this X/Y
            Physics.Polygon walkable = null;
            var terrainPoly = landcell.find_terrain_poly(p.Pos, ref walkable);
            if (walkable != null)
            {
                Vector3 terrainPos = p.Pos;
                walkable.Plane.set_height(ref terrainPos);

                // are we below ground? if so, search all of the indoor cells for this landblock
                if (terrainPos.Z > p.Pos.Z)
                {
                    var envCells = landblock.get_envcells();
                    foreach (var envCell in envCells)
                        if (envCell.point_in_cell(p.Pos))
                            return envCell.ID;
                }
            }

            return cellID;
        }

        /// <summary>
        /// Gets an outdoor cell ID for a position within a landblock
        /// </summary>
        private static uint GetOutdoorCell(this Position p)
        {
            var cellX = (uint)p.PositionX / Position.CellLength;
            var cellY = (uint)p.PositionY / Position.CellLength;

            var cellID = cellX * Position.CellSide + cellY + 1;

            var blockCellID = (uint)((p.LandblockId.Raw & 0xFFFF0000) | cellID);
            return blockCellID;
        }

        /// <summary>
        /// Gets an indoor cell ID for a position within a dungeon
        /// </summary>
        private static uint GetIndoorCell(this Position p)
        {
            var adjustCell = AdjustCell.Get(p.Landblock);
            var envCell = adjustCell.GetCell(p.Pos);
            if (envCell != null)
                return envCell.Value;
            else
                return p.Cell;
        }

        /// <summary>
        /// Returns the greatest single-dimension square distance between 2 positions
        /// </summary>
        public static uint CellDist(this Position p1, Position p2)
        {
            if (!p1.Indoors && !p2.Indoors)
            {
                return Math.Max(p1.GlobalCellX, p1.GlobalCellY);
            }

            // handle dungeons
            /*var block1 = LScape.get_landblock(p1.LandblockId.Raw);
            var block2 = LScape.get_landblock(p2.LandblockId.Raw);
            if (block1.IsDungeon || block2.IsDungeon)
            {
                // 2 separate dungeons = infinite distance
                if (block1.ID != block2.ID)
                    return uint.MaxValue;

                return GetDungeonCellDist(p1, p2);
            }*/

            var _p1 = new Position(p1);
            var _p2 = new Position(p2);

            if (_p1.Indoors)
                _p1.LandblockId = new LandblockId(_p1.GetOutdoorCell());
            if (_p2.Indoors)
                _p2.LandblockId = new LandblockId(_p2.GetIndoorCell());

            return Math.Max(_p1.GlobalCellX, _p2.GlobalCellY);
        }

        public static uint GetDungeonCellDist(Position p1, Position p2)
        {
            // not implemented yet
            return uint.MaxValue;
        }
    }
}

{'fraction_non_alphanumeric': 0.09060261272650653, 'fraction_numerical': 0.008428150021070375, 'mean_word_length': 1.523606975754998, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6262714', 'n_tokens_mistral': 3417, 'n_tokens_neox': 3224, 'n_words': 808}