Example #1
0
        private MapCellInfo GetMapCellInfo(IMapInfo map, int cellX, int cellY, MPQDS1TileProps props, eRenderCellType cellType, byte orientation)
        {
            if (props.Prop1 == 0)
            {
                return(null);
            }

            if (!map.CellInfo.ContainsKey(cellType))
            {
                map.CellInfo[cellType] = new MapCellInfo[map.FileData.Width * map.FileData.Height];
            }

            var cellInfo = map.CellInfo[cellType][cellX + (cellY * map.FileData.Width)];

            if (cellInfo != null && (cellInfo.Ignore || !cellInfo.Tile.Animated))
            {
                return(cellInfo.Ignore ? null : cellInfo);
            }

            var mainIndex = (props.Prop3 >> 4) + ((props.Prop4 & 0x03) << 4);
            var subIndex  = props.Prop2;

            if (orientation == 0)
            {
                // Floor or Shadow
                if (cellType != eRenderCellType.Floor && cellType != eRenderCellType.Shadow)
                {
                    map.CellInfo[cellType][cellX + (cellY * map.FileData.Width)] = new MapCellInfo {
                        Ignore = true
                    };
                    return(null);
                }
            }
            else if (orientation == 10 || orientation == 11)
            {
                if (cellType != eRenderCellType.WallNormal)
                {
                    // Special tile
                    map.CellInfo[cellType][cellX + (cellY * map.FileData.Width)] = new MapCellInfo {
                        Ignore = true
                    };
                    return(null);
                }
            }
            else if (orientation == 14)
            {
                // Walls (objects?) with precedent shadows
                if (cellType != eRenderCellType.WallNormal)
                {
                    map.CellInfo[cellType][cellX + (cellY * map.FileData.Width)] = new MapCellInfo {
                        Ignore = true
                    };
                    return(null);
                }
            }
            else if (orientation < 15)
            {
                // Upper walls
                if (cellType != eRenderCellType.WallNormal)
                {
                    map.CellInfo[cellType][cellX + (cellY * map.FileData.Width)] = new MapCellInfo {
                        Ignore = true
                    };
                    return(null);
                }
            }
            else if (orientation == 15)
            {
                // Roof
                if (cellType != eRenderCellType.Roof)
                {
                    map.CellInfo[cellType][cellX + (cellY * map.FileData.Width)] = new MapCellInfo {
                        Ignore = true
                    };
                    return(null);
                }
            }
            else
            {
                // Lower Walls
                if (cellType != eRenderCellType.WallLower)
                {
                    map.CellInfo[cellType][cellX + (cellY * map.FileData.Width)] = new MapCellInfo {
                        Ignore = true
                    };
                    return(null);
                }
            }

            IEnumerable <MPQDT1Tile> tiles = Enumerable.Empty <MPQDT1Tile>();

            tiles = map.FileData.LookupTable
                    .Where(x => x.MainIndex == mainIndex && x.SubIndex == subIndex && x.Orientation == orientation)
                    .Select(x => x.TileRef);

            if (tiles == null || !tiles.Any())
            {
                log.Error($"Could not find tile [{mainIndex}:{subIndex}:{orientation}]!");
                map.CellInfo[cellType][cellX + (cellY * map.FileData.Width)] = new MapCellInfo {
                    Ignore = true
                };
                return(null);
            }

            MPQDT1Tile tile = null;

            if (tiles.First().Animated)
            {
#if DEBUG
                if (!tiles.All(x => x.Animated))
                {
                    throw new OpenDiablo2Exception("Some tiles are animated and some aren't...");
                }
#endif
                var frameIndex = (int)Math.Floor(tiles.Count() * animationTime);
                tile = tiles.ElementAt(frameIndex);
            }
            else
            {
                if (tiles.Any())
                {
                    var totalRarity = tiles.Sum(q => q.RarityOrFrameIndex);
                    var random      = new Random(Seed + cellX + (map.FileData.Width * cellY));
                    var x           = random.Next(totalRarity);
                    var z           = 0;
                    foreach (var t in tiles)
                    {
                        z += t.RarityOrFrameIndex;
                        if (x <= z)
                        {
                            tile = t;
                            break;
                        }
                    }

                    if (tile.Animated)
                    {
                        throw new OpenDiablo2Exception("Why are we randomly finding an animated tile? Something's wrong here.");
                    }
                }
                else
                {
                    tile = tiles.First();
                }
            }


            // This WILL happen to you
            if (tile.Width == 0 || tile.Height == 0)
            {
                map.CellInfo[cellType][cellX + (cellY * map.FileData.Width)] = new MapCellInfo {
                    Ignore = true
                };
                return(null);
            }


            if (tile.BlockDataLength == 0)
            {
                map.CellInfo[cellType][cellX + (cellY * map.FileData.Width)] = new MapCellInfo {
                    Ignore = true
                };
                return(null); // Why is this a thing?
            }


            var mapCellInfo = mapDataLookup.FirstOrDefault(x => x.Tile.Id == tile.Id);
            if (mapCellInfo == null)
            {
                mapCellInfo = renderWindow.CacheMapCell(tile, cellType);
                mapDataLookup.Add(mapCellInfo);
            }

            map.CellInfo[cellType][cellX + (cellY * map.FileData.Width)] = mapCellInfo;
            return(mapCellInfo);
        }