コード例 #1
0
		private List<Address> checkColumn(ColumnPortion cp, Address origin, Map map, Queue<ColumnPortion> queue, int octant, int range)
		{
			List<Address> result = new List<Address>();
			DirectionVector topVector = cp.TopVector;
			DirectionVector bottomVector = cp.BottomVector;
			int x = cp.X;
			int topY;
			if (cp.X == 0)
				topY = 0;
			else
			{
				int quotient = (2 * cp.X + 1) * cp.TopVector.Y / (2 * cp.TopVector.X);
				int remainder = (2 * cp.X + 1) * cp.TopVector.Y % (2 * cp.TopVector.X);

				topY = quotient;
				if (remainder > cp.TopVector.X)
					topY = quotient++;
			}

			int bottomY;
			if (cp.X == 0)
				bottomY = 0;
			else
			{
				int quotient = (2 * cp.X - 1) * cp.BottomVector.Y / (2 * cp.BottomVector.X);
				int remainder = (2 * cp.X - 1) * cp.BottomVector.Y % (2 * cp.BottomVector.X);

				bottomY = quotient;
				if (remainder >= cp.BottomVector.X)
					bottomY = quotient++;

			}

			bool? wasLastCellOpaque = null;

			for (int y = topY; y >= bottomY; --y)
			{
				bool inRadius = IsInRadius(x, y, range);
				if (inRadius)
				{
					Address temp = TranslateOctant(new Address(x, y), octant);
					// The current cell is in the field of view.
					result.Add(new Address(origin.x + temp.x, origin.y + temp.y));
				}

				// A cell that was too far away to be seen is effectively
				// an opaque cell; nothing "above" it is going to be visible
				// in the next column, so we might as well treat it as 
				// an opaque cell and not scan the cells that are also too
				// far away in the next column.

				bool currentIsOpaque = !inRadius || isOpaque(map, origin, x, y, octant);
				if (wasLastCellOpaque != null)
				{
					if (currentIsOpaque)
					{
						// We've found a boundary from transparent to opaque. Make a note
						// of it and revisit it later.
						if (!wasLastCellOpaque.Value)
						{
							// The new bottom vector touches the upper left corner of 
							// opaque cell that is below the transparent cell. 
							queue.Enqueue(new ColumnPortion(
								x + 1,
								new DirectionVector(x * 2 - 1, y * 2 + 1),
								topVector));
						}
					}
					else if (wasLastCellOpaque.Value)
					{
						// We've found a boundary from opaque to transparent. Adjust the
						// top vector so that when we find the next boundary or do
						// the bottom cell, we have the right top vector.
						//
						// The new top vector touches the lower right corner of the 
						// opaque cell that is above the transparent cell, which is
						// the upper right corner of the current transparent cell.
						topVector = new DirectionVector(x * 2 + 1, y * 2 + 1);
					}
				}
				wasLastCellOpaque = currentIsOpaque;
			}

			// Make a note of the lowest opaque-->transparent transition, if there is one. 
			if (wasLastCellOpaque != null && !wasLastCellOpaque.Value)
				queue.Enqueue(new ColumnPortion(x + 1, bottomVector, topVector));

			return result;
		}
コード例 #2
0
        private static void computeFieldOfViewInOctantZero(
            byte octant,
            bool[] fovGrid,
            int fovGridMinX,
            int fovGridMinY,
            int fovGridWidth,
            bool[] oldFovGrid,
            int oldFovGridMinX,
            int oldFovGridMaxX,
            int oldFovGridMinY,
            int oldFovGridMaxY,
            int oldFovGridWidth,
            int radius,
            int r_r_4,
            int startX,
            int startY,
            int maxX,
            int maxY,
            bool[] viewBlockerCells,
            bool handleSeenAndCache,
            MapComponentSeenFog mapCompSeenFog,
            Faction faction,
            int[] factionShownCells,
            int targetX,
            int targetY,
            int x,
            int topVectorX,
            int topVectorY,
            int bottomVectorX,
            int bottomVectorY)
        {
            int  topY;
            int  bottomY;
            bool inRadius;
            bool currentIsOpaque;

            bool wasLastCellOpaque;
            bool lastCellCalcuated;

            int quotient;
            int remainder;

            int fogGridIdx;
            int oldFogGridIdx;

            int x2;
            int y2;

            int worldY = 0;
            int worldX = 0;

            bool firstIteration = true;

            while (firstIteration || !queue.Empty())
            {
                if (!firstIteration)
                {
                    ref ColumnPortion columnPortion = ref queue.Dequeue();
                    x             = columnPortion.x;
                    topVectorX    = columnPortion.topVectorX;
                    topVectorY    = columnPortion.topVectorY;
                    bottomVectorX = columnPortion.bottomVectorX;
                    bottomVectorY = columnPortion.bottomVectorY;
                }