/// <summary> /// /// </summary> /// <param name="cell"></param> void UpdateProjection(CPos cell) { MPos uv; if (Grid.MaximumTerrainHeight == 0) { uv = cell.ToMPos(Grid.Type); cellProjection[cell] = new[] { (PPos)uv }; var inverse = inverseCellProjection[uv]; inverse.Clear(); inverse.Add(uv); return; } if (!initializedCellProjection) { InitializeCellPojection(); } uv = cell.ToMPos(Grid.Type); // Remove old reverse projection // 删除旧的反向投影 foreach (var puv in cellProjection[uv]) { var temp = (MPos)puv; inverseCellProjection[(MPos)puv].Remove(uv); projectedHeight[temp] = ProjectedCellHeightInner(puv); } var projected = ProjectCellInner(uv); cellProjection[uv] = projected; foreach (var puv in projected) { var temp = (MPos)puv; inverseCellProjection[temp].Add(uv); var height = ProjectedCellHeightInner(puv); projectedHeight[temp] = height; // Propagate height up cliff faces while (true) { temp = new MPos(temp.U, temp.V - 1); if (!inverseCellProjection.Contains(temp) || inverseCellProjection[temp].Any()) { break; } projectedHeight[temp] = height; } } }
/// <summary> /// 获取某一单元格所代表的地形索引 /// Transparently cache results of GetTerrainIndex in Map. /// /// This method performs an expensive calculation and is called often during pathfinding. /// We create a cache of the terrain indicies for the map to vastly reduce the cost. /// </summary> /// <param name="cell"></param> /// <returns></returns> public byte GetTerrainIndex(CPos cell) { const short InvalidCachedTerrainIndex = -1; //Lazily initialize a cache for terrain indexes;懒初始化地形索引缓存 if (cachedTerrainIndexes == null) { cachedTerrainIndexes = new CellLayer <short>(this); cachedTerrainIndexes.Clear(InvalidCachedTerrainIndex); //Invalidate the entry for a cell if anything could cause the terrain index to change; Action <CPos> invalidateTerrainIndex = c => cachedTerrainIndexes[c] = InvalidCachedTerrainIndex; CustomTerrain.CellEntryChanged += invalidateTerrainIndex; Tiles.CellEntryChanged += invalidateTerrainIndex; } var uv = cell.ToMPos(this); var terrainIndex = cachedTerrainIndexes[uv]; //PERF:Cache terrain indexes per cell on demand.//按需求对每个单元格缓存地形索引 if (terrainIndex == InvalidCachedTerrainIndex) { var custom = CustomTerrain[uv]; terrainIndex = cachedTerrainIndexes[uv] = custom != byte.MaxValue ? custom : Rules.TileSet.GetTerrainIndex(Tiles[uv]); } return((byte)terrainIndex); }
public bool Contains(CPos cell) { if (GridT == MapGridT.RectangularIsometric && cell.X < cell.Y) { return(false); } return(Contains(cell.ToMPos(GridT))); }
public bool Contains(CPos cell) { //.ToMPos() returns the same result if the X and Y coordinates are switched.X<Y is invalid in the RectangularIsometric coordinate system. //so we pre-filter these to avoid returning the wrong result. if (Grid.Type == MapGridT.RectangularIsometric && cell.X < cell.Y) { return(false); } return(Contains(cell.ToMPos(this))); }
public CPos Clamp(CPos cell) { return(Clamp(cell.ToMPos(this)).ToCPos(this)); }
/// <summary> /// Resolve an array index from cell coordinates /// </summary> /// <param name="cell"></param> /// <returns></returns> int Index(CPos cell) { return(Index(cell.ToMPos(GridT))); }