예제 #1
0
			public TmpFile GetTmpFile(MapTile t, bool damaged = false) {
				if (TmpFiles.Count == 0)
					return null;
				var randomChosen = TmpFiles[Rand.Next(TmpFiles.Count)];
				// if this is not a randomizing tileset, but instead one with damaged data,
				// then return the "undamaged" version
				randomChosen.Initialize();
				if (randomChosen.Images[Math.Min(t.SubTile, randomChosen.Images.Count - 1)].HasDamagedData)
					return TmpFiles[Math.Min(damaged ? 1 : 0, TmpFiles.Count - 1)];
				else
					return randomChosen;
			}
예제 #2
0
		private void ProcessTile(MapTile tile) {
			// "lock" this tile at least until we've examined its neighbourhood
			AddDependency(tile, null);
			ExamineNeighbourhood(tile);
			foreach (var obj in tile.AllObjects) {
				// every object depends on its bottom-most host tile at least
				AddDependency(obj, null);
				ExamineNeighbourhood(obj);
			}

			_graph[tile].Remove(tile);
			if (_graph[tile].Count == 0)
				// mark this tile and remove it as dependency from all other objects
				MarkDependencies(tile);

			// Debug.WriteLine("----------------------- processed " + tile);
		}
예제 #3
0
		public static Rectangle GetBounds(MapTile tile, TmpFile tmp) {
			tmp.Initialize();

			if (tile.SubTile >= tmp.Images.Count) return Rectangle.Empty;
			var img = tmp.Images[tile.SubTile];

			int left = tile.Dx * tmp.BlockWidth / 2;
			int top = (tile.Dy - tile.Z) * tmp.BlockHeight / 2;
			int width = tmp.BlockWidth;
			int height = tmp.BlockHeight;
			if (img.HasExtraData) {
				if (img.ExtraX < 0) { left += img.ExtraX; width -= img.ExtraX; }
				if (img.ExtraY < 0) { top += img.ExtraY; height -= img.ExtraY; }
				width = Math.Max(width, img.ExtraWidth);
				height = Math.Max(height, img.ExtraHeight);
			}

			return new Rectangle(left, top, width, height);
		}
예제 #4
0
        /// <summary>Recalculates tile system. </summary>
        public static void FixTiles(TileLayer tiles, TileCollection collection)
        {
            Logger.Info("Recalculating tile LAT system");

            // change all CLAT tiles to their corresponding LAT tiles
            foreach (MapTile t in tiles)
            {
                // If this tile comes from a CLAT (connecting lat) set,
                // then replace it's set and tilenr by corresponding LAT sets'
                t.SetNum = collection.GetSetNum(t.TileNum);

                if (collection.IsCLAT(t.SetNum))
                {
                    t.SetNum  = collection.GetLAT(t.SetNum);
                    t.TileNum = collection.GetTileNumFromSet(t.SetNum);
                }
            }

            // apply autolat
            foreach (MapTile t in tiles)
            {
                // If this tile is a LAT tile, we might have to connect it
                if (collection.IsLAT(t.SetNum))
                {
                    // Which tile to use from CLAT tileset
                    byte    transitionTile  = 0;
                    MapTile tileTopRight    = tiles.GetNeighbourTile(t, TileLayer.TileDirection.TopRight);
                    MapTile tileBottomRight = tiles.GetNeighbourTile(t, TileLayer.TileDirection.BottomRight);
                    MapTile tileBottomLeft  = tiles.GetNeighbourTile(t, TileLayer.TileDirection.BottomLeft);
                    MapTile tileTopLeft     = tiles.GetNeighbourTile(t, TileLayer.TileDirection.TopLeft);


                    // Find out setnums of adjacent cells
                    if (tileTopRight != null && collection.ConnectTiles(t.SetNum, tileTopRight.SetNum))
                    {
                        transitionTile += 1;
                    }

                    if (tileBottomRight != null && collection.ConnectTiles(t.SetNum, tileBottomRight.SetNum))
                    {
                        transitionTile += 2;
                    }

                    if (tileBottomLeft != null && collection.ConnectTiles(t.SetNum, tileBottomLeft.SetNum))
                    {
                        transitionTile += 4;
                    }

                    if (tileTopLeft != null && collection.ConnectTiles(t.SetNum, tileTopLeft.SetNum))
                    {
                        transitionTile += 8;
                    }

                    if (transitionTile > 0)
                    {
                        // Find Tileset that contains the connecting pieces
                        short clatSet = collection.GetCLATSet(t.SetNum);
                        // Do not change this setnum, as then we could recognize it as
                        // a different tileset for later tiles around this one.
                        // (T->SetNum = clatSet;)
                        t.TileNum  = collection.GetTileNumFromSet(clatSet, transitionTile);
                        t.Drawable = collection.GetDrawable(t);
                    }
                }

                // apply ramp fixup
                else if (t.SetNum == collection.RampBase)
                {
                    var ti = t.GetTileImage();
                    if (ti.RampType < 1 || 4 < ti.TerrainType)
                    {
                        continue;
                    }

                    int     fixup           = -1;
                    MapTile tileTopRight    = tiles.GetNeighbourTile(t, TileLayer.TileDirection.TopRight);
                    MapTile tileBottomRight = tiles.GetNeighbourTile(t, TileLayer.TileDirection.BottomRight);
                    MapTile tileBottomLeft  = tiles.GetNeighbourTile(t, TileLayer.TileDirection.BottomLeft);
                    MapTile tileTopLeft     = tiles.GetNeighbourTile(t, TileLayer.TileDirection.TopLeft);


                    switch (ti.RampType)
                    {
                    case 1:
                        // northwest facing
                        if (tileTopLeft != null && tileTopLeft.GetTileImage().RampType == 0)
                        {
                            fixup++;
                        }
                        if (tileBottomRight != null && tileBottomRight.GetTileImage().RampType == 0)
                        {
                            fixup += 2;
                        }
                        break;

                    case 2:                             // northeast facing
                        if (tileTopRight != null && tileTopRight.GetTileImage().RampType == 0)
                        {
                            fixup++;
                        }
                        if (tileBottomLeft != null && tileBottomLeft.GetTileImage().RampType == 0)
                        {
                            fixup += 2;
                        }
                        break;

                    case 3:                             // southeast facing
                        if (tileBottomRight != null && tileBottomRight.GetTileImage().RampType == 0)
                        {
                            fixup++;
                        }
                        if (tileTopLeft != null && tileTopLeft.GetTileImage().RampType == 0)
                        {
                            fixup += 2;
                        }
                        break;

                    case 4:                             // southwest facing
                        if (tileBottomLeft != null && tileBottomLeft.GetTileImage().RampType == 0)
                        {
                            fixup++;
                        }
                        if (tileTopRight != null && tileTopRight.GetTileImage().RampType == 0)
                        {
                            fixup += 2;
                        }
                        break;
                    }

                    if (fixup != -1)
                    {
                        t.TileNum = collection.GetTileNumFromSet(collection.RampSmooth, (byte)((ti.RampType - 1) * 3 + fixup));
                        // update drawable too
                        t.Drawable = collection.GetDrawable(t);
                    }
                }
            }
        }
예제 #5
0
        private static int CountNeighbouringVeins(MapTile ne, MapTile se, MapTile sw, MapTile nw, Func <OverlayObject, bool> test)
        {
            bool neV           = ne != null && ne.AllObjects.OfType <OverlayObject>().Any(test);
            bool seV           = se != null && se.AllObjects.OfType <OverlayObject>().Any(test);
            bool swV           = sw != null && sw.AllObjects.OfType <OverlayObject>().Any(test);
            bool nwV           = nw != null && nw.AllObjects.OfType <OverlayObject>().Any(test);
            int  numNeighbours =
                (neV ? 1 : 0) + (seV ? 1 : 0) + (swV ? 1 : 0) + (nwV ? 1 : 0);

            return(numNeighbours);
        }
예제 #6
0
		unsafe public static void Draw(MapTile tile, TmpFile tmp, DrawingSurface ds) {
			tmp.Initialize();

			if (tile.SubTile >= tmp.Images.Count) return;
			TmpFile.TmpImage img = tmp.Images[tile.SubTile];
			var zBuffer = ds.GetZBuffer();
			var heightBuffer = ds.GetHeightBuffer();
			Palette p = tile.Palette;

			// calculate tile index -> pixel index
			Point offset = new Point(tile.Dx * tmp.BlockWidth / 2, (tile.Dy - tile.Z) * tmp.BlockHeight / 2);

			// make touched tiles (used for determining image cutoff)
			Point center = offset + new Size(tmp.BlockWidth / 2, tmp.BlockHeight / 2);
			var centerGridTile = tile.Layer.GetTileScreen(center, true, true);
			if (centerGridTile != null) {
				tile.Layer.GridTouched[centerGridTile.Dx, centerGridTile.Dy / 2] |= TileLayer.TouchType.ByNormalData;
				tile.Layer.GridTouchedBy[centerGridTile.Dx, centerGridTile.Dy / 2] = tile;
			}

			Logger.Trace("Drawing TMP file {0} (subtile {1}) at ({2},{3})", tmp.FileName, tile.SubTile, offset.X, offset.Y);

			int stride = ds.BitmapData.Stride;

			int halfCx = tmp.BlockWidth / 2,
				halfCy = tmp.BlockHeight / 2;

			// writing bounds
			var w_low = (byte*)ds.BitmapData.Scan0;
			byte* w_high = (byte*)ds.BitmapData.Scan0 + stride * ds.BitmapData.Height;
			byte* w = (byte*)ds.BitmapData.Scan0 + stride * offset.Y + (offset.X + halfCx - 2) * 3;

			int rIdx = 0, x, y = 0;
			int zIdx = offset.Y * ds.Width + offset.X + halfCx - 2;
			int cx = 0; // Amount of pixel to copy

			for (; y < halfCy; y++) {
				cx += 4;
				for (ushort c = 0; c < cx; c++) {
					byte paletteValue = img.TileData[rIdx];

					short zBufVal = (short)((tile.Rx + tile.Ry) * tmp.BlockHeight / 2 - (img.ZData != null ? img.ZData[rIdx] : 0));
					if (paletteValue != 0 && w_low <= w && w < w_high && zBufVal >= zBuffer[zIdx]) {
						*(w + 0) = p.Colors[paletteValue].B;
						*(w + 1) = p.Colors[paletteValue].G;
						*(w + 2) = p.Colors[paletteValue].R;
						zBuffer[zIdx] = zBufVal;
						heightBuffer[zIdx] = (short)(tile.Z * Drawable.TileHeight / 2);
					}
					w += 3;
					zIdx++;
					rIdx++;
				}
				w += stride - 3 * (cx + 2);
				zIdx += ds.Width - (cx + 2);
			}

			w += 12;
			zIdx += 4;
			for (; y < tmp.BlockHeight; y++) {
				cx -= 4;
				for (ushort c = 0; c < cx; c++) {
					byte paletteValue = img.TileData[rIdx];

					short zBufVal = (short)((tile.Rx + tile.Ry) * tmp.BlockHeight / 2 - (img.ZData != null ? img.ZData[rIdx] : 0));
					if (paletteValue != 0 && w_low <= w && w < w_high && zBufVal >= zBuffer[zIdx]) {
						*(w + 0) = p.Colors[paletteValue].B;
						*(w + 1) = p.Colors[paletteValue].G;
						*(w + 2) = p.Colors[paletteValue].R;
						zBuffer[zIdx] = zBufVal;
						heightBuffer[zIdx] = (short)(tile.Z * Drawable.TileHeight / 2);
					}
					w += 3;
					zIdx++;
					rIdx++;
				}
				w += stride - 3 * (cx - 2);
				zIdx += ds.Width - (cx - 2);
			}

			if (!img.HasExtraData) return; // we're done now

			offset.X += img.ExtraX - img.X;
			offset.Y += img.ExtraY - img.Y;
			w = w_low + stride * offset.Y + 3 * offset.X;
			zIdx = offset.X + offset.Y * ds.Width;
			rIdx = 0;

			// identify extra-data affected tiles for cutoff
			var extraScreenBounds = Rectangle.FromLTRB(
				Math.Max(0, offset.X), Math.Max(0, offset.Y),
				Math.Min(offset.X + img.ExtraWidth, ds.Width), Math.Min(offset.Y + img.ExtraHeight, ds.Height));

			for (int by = extraScreenBounds.Top; by < extraScreenBounds.Bottom; by += tmp.BlockHeight / 2) {
				for (int bx = extraScreenBounds.Left; bx < extraScreenBounds.Right; bx += tmp.BlockWidth / 2) {
					var gridTileNoZ = tile.Layer.GetTileScreen(new Point(bx, by), true, true);
					if (gridTileNoZ != null) {
						Logger.Trace("Tile at ({0},{1}) has extradata affecting ({2},{3})", tile.Dx, tile.Dy, gridTileNoZ.Dx,
							gridTileNoZ.Dy);
						tile.Layer.GridTouched[gridTileNoZ.Dx, gridTileNoZ.Dy / 2] |= TileLayer.TouchType.ByExtraData;
						tile.Layer.GridTouchedBy[gridTileNoZ.Dx, gridTileNoZ.Dy / 2] = tile;
					}
				}
			}

			// Extra graphics are just a square
			for (y = 0; y < img.ExtraHeight; y++) {
				for (x = 0; x < img.ExtraWidth; x++) {
					// Checking per line is required because v needs to be checked every time
					byte paletteValue = img.ExtraData[rIdx];
					short zBufVal = (short)((tile.Rx + tile.Ry) * tmp.BlockHeight / 2 + (img.ExtraZData != null ? img.ExtraZData[rIdx] : 0));

					if (paletteValue != 0 && w_low <= w && w < w_high && zBufVal >= zBuffer[zIdx]) {
						*w++ = p.Colors[paletteValue].B;
						*w++ = p.Colors[paletteValue].G;
						*w++ = p.Colors[paletteValue].R;
						zBuffer[zIdx] = zBufVal;
						heightBuffer[zIdx] = (short)(img.ExtraHeight - y + tile.Z * Drawable.TileHeight / 2);
					}
					else
						w += 3;
					zIdx++;
					rIdx++;
				}
				w += stride - img.ExtraWidth * 3;
				zIdx += ds.Width - img.ExtraWidth;
			}
		}
예제 #7
0
		public TmpFile.TmpImage GetTileImage(MapTile t) {
			var tmp = TsEntry.GetTmpFile(t);
			if (tmp.Images.Count > t.SubTile) return tmp.Images[t.SubTile];
			return tmp.Images.Count > 0 ? tmp.Images[0] : null;
		}
예제 #8
0
		public TmpFile GetTileFile(MapTile t) {
			return TsEntry.GetTmpFile(t);
		}
예제 #9
0
		private static int CountNeighbouringVeins(MapTile ne, MapTile se, MapTile sw, MapTile nw, Func<OverlayObject, bool> test) {
			bool neV = ne != null && ne.AllObjects.OfType<OverlayObject>().Any(test);
			bool seV = se != null && se.AllObjects.OfType<OverlayObject>().Any(test);
			bool swV = sw != null && sw.AllObjects.OfType<OverlayObject>().Any(test);
			bool nwV = nw != null && nw.AllObjects.OfType<OverlayObject>().Any(test);
			int numNeighbours =
							(neV ? 1 : 0) + (seV ? 1 : 0) + (swV ? 1 : 0) + (nwV ? 1 : 0);
			return numNeighbours;
		}
예제 #10
0
		public static int CountNeighbouringVeins(MapTile t, Func<OverlayObject, bool> test) {
			var ne = t.Layer.GetNeighbourTile(t, TileLayer.TileDirection.TopRight);
			var se = t.Layer.GetNeighbourTile(t, TileLayer.TileDirection.BottomRight);
			var sw = t.Layer.GetNeighbourTile(t, TileLayer.TileDirection.BottomLeft);
			var nw = t.Layer.GetNeighbourTile(t, TileLayer.TileDirection.TopLeft);
			return CountNeighbouringVeins(ne, se, sw, nw, test);
		}
예제 #11
0
파일: Map.cs 프로젝트: dkeetonx/ccmaps-net
		public void DebugDrawTile(MapTile tile) {
			_theater.Draw(tile, _drawingSurface);
			foreach (GameObject o in GetObjectsAt(tile.Dx, tile.Dy / 2))
				_theater.Draw(o, _drawingSurface);
			Operations.CountNeighbouringVeins(tile, Operations.IsVeins);
		}
예제 #12
0
파일: Map.cs 프로젝트: zzattack/ccmaps-net
        private void ChangeTileToClear(TileCollection coll, MapTile tile)
        {
            tile.TileNum = 0;
            tile.SubTile = 0;
            tile.Drawable = coll.GetDrawable(0);

            var t = _mapFile.Tiles.GetTileR(tile.Rx, tile.Ry);
            t.TileNum = 0;
            t.SubTile = 0;
        }