Пример #1
0
        public static bool TraceLine(FastBitmapHSV bitmap, int posX, int posY, int incX, int incY, int traceLen, FastPixelMatch colorMatch, out Point posHit, bool bDebugMode = false)
        {
            if (bDebugMode)
            {
                Console.WriteLine("TraceLine [" + posX + ", " + posY + "] -> [" + (posX + (incX * traceLen)) + ", " + (posY + (incY * traceLen)) + "]");
            }

            for (int stepIdx = 0; stepIdx < traceLen; stepIdx++)
            {
                int          scanX       = posX + (stepIdx * incX);
                int          scanY       = posY + (stepIdx * incY);
                FastPixelHSV testPx      = bitmap.GetPixel(scanX, scanY);
                bool         bIsMatching = colorMatch.IsMatching(testPx);

                if (bDebugMode)
                {
                    Console.WriteLine("  [" + scanX + ", " + scanY + "] " + testPx + " => match:" + bIsMatching);
                }

                if (bIsMatching)
                {
                    posHit = new Point(scanX, scanY);
                    return(true);
                }
            }

            if (bDebugMode)
            {
                Console.WriteLine("  >> failed");
            }
            posHit = new Point(posX + (traceLen * incX), posY + (traceLen * incY));
            return(false);
        }
Пример #2
0
        public static Color GetColorFromHSV(FastPixelHSV pixel)
        {
            int R = 0, G = 0, B = 0;

            HsvToRgb(pixel.GetHue(), pixel.GetSaturation() / 100.0, pixel.GetValue() / 100.0, out R, out G, out B);
            return(Color.FromArgb(R, G, B));
        }
Пример #3
0
        private bool HasBurstMarker(FastBitmapHSV bitmap, int testX, int testY)
        {
            //bool wantsLogs = testX == 153 && testY == 112;

            for (int idx = 0; idx < posBurstMarkerI.Length; idx++)
            {
                FastPixelHSV testPx  = bitmap.GetPixel(posBurstMarkerI[idx].X + testX, posBurstMarkerI[idx].Y + testY);
                bool         isMatch = matchBurstMarker.IsMatching(testPx);
                //if (wantsLogs) Console.WriteLine("HasBurstMarker({0}, {1}) - inner[{2}]({3},{4}) = {5}", testX, testY, idx, posBurstMarkerI[idx].X + testX, posBurstMarkerI[idx].Y + testY, testPx);
                if (!isMatch)
                {
                    return(false);
                }
            }

            for (int idx = 0; idx < posBurstMarkerO.Length; idx++)
            {
                FastPixelHSV testPx  = bitmap.GetPixel(posBurstMarkerO[idx].X + testX, posBurstMarkerO[idx].Y + testY);
                bool         isMatch = matchBurstMarker.IsMatching(testPx);
                //if (wantsLogs) Console.WriteLine("HasBurstMarker({0}, {1}) - outer[{2}]({3},{4}) = {5}", testX, testY, idx, posBurstMarkerO[idx].X + testX, posBurstMarkerO[idx].Y + testY, testPx);
                if (isMatch)
                {
                    return(false);
                }
            }

            return(true);
        }
Пример #4
0
        public float[] ExtractActionSlotWeaponData(FastBitmapHSV bitmap, int slotIdx)
        {
            // scan area: 10x10 (rectActionIcon)
            float[] values = new float[10 * 10];
            for (int idx = 0; idx < values.Length; idx++)
            {
                values[idx] = 0.0f;
            }

            const int   monoSteps = 16;
            const float monoScale = 1.0f / monoSteps;

            Point slotPos = rectActionSlots[slotIdx].Location;

            for (int idxY = 0; idxY < 10; idxY++)
            {
                for (int idxX = 0; idxX < 10; idxX++)
                {
                    FastPixelHSV pixel = bitmap.GetPixel(slotPos.X + rectActionIcon.X + idxX, slotPos.Y + rectActionIcon.Y + idxY);
                    int          monoV = pixel.GetMonochrome() / (256 / monoSteps);

                    values[idxX + (idxY * 10)] = monoV * monoScale;
                }
            }

            return(values);
        }
Пример #5
0
        public float[] ExtractButtonData(FastBitmapHSV bitmap, int slotIdx)
        {
            // scan area: 16x8 (rectButtonText scaled down)
            float[] values = new float[16 * 8];
            for (int idx = 0; idx < values.Length; idx++)
            {
                values[idx] = 0.0f;
            }

            const int   monoSteps = 16;
            const float monoScale = 1.0f / monoSteps;

            Point slotPos = rectButtonPos[slotIdx].Location;

            slotPos.X += rectButtonText.Location.X;
            slotPos.Y += rectButtonText.Location.Y;

            for (int idxY = 0; idxY < 16; idxY++)
            {
                for (int idxX = 0; idxX < 32; idxX++)
                {
                    FastPixelHSV pixel = bitmap.GetPixel(slotPos.X + idxX, slotPos.Y + idxY);
                    int          monoV = pixel.GetMonochrome() / (256 / monoSteps);

                    values[(idxX / 2) + ((idxY / 2) * 16)] += monoV * monoScale * 0.25f;
                }
            }

            return(values);
        }
Пример #6
0
        public float[] ExtractDemonTypeData(FastBitmapHSV bitmap)
        {
            // scan area: 10x10 (rectActionIcon)
            float[] values = new float[10 * 10];
            for (int idx = 0; idx < values.Length; idx++)
            {
                values[idx] = 0.0f;
            }

            const int   monoSteps = 16;
            const float monoScale = 1.0f / monoSteps;

            for (int idxY = 0; idxY < 10; idxY++)
            {
                for (int idxX = 0; idxX < 10; idxX++)
                {
                    FastPixelHSV pixel = bitmap.GetPixel(rectDemonType.X + idxX, rectDemonType.Y + idxY);
                    int          monoV = pixel.GetMonochrome() / (256 / monoSteps);

                    values[idxX + (idxY * 10)] = monoV * monoScale;
                }
            }

            return(values);
        }
Пример #7
0
        protected bool HasMatchingSamples(FastBitmapHSV bitmap, Point[] points, int offsetX, int offsetY, FastPixelMatch match, string debugName)
        {
            if (DebugLevel == EDebugLevel.Verbose)
            {
                string desc = "";
                for (int idx = 0; idx < points.Length; idx++)
                {
                    if (idx > 0)
                    {
                        desc += ", ";
                    }
                    var testPx   = bitmap.GetPixel(points[idx].X + offsetX, points[idx].Y + offsetY);
                    var matching = match.IsMatching(testPx);

                    desc += "(" + testPx + "):" + matching;
                }

                Console.WriteLine("HasMatchingSamples: {2}> filter({0}) vs {1}", match, desc, debugName);
            }

            for (int idx = 0; idx < points.Length; idx++)
            {
                FastPixelHSV testPx  = bitmap.GetPixel(points[idx].X + offsetX, points[idx].Y + offsetY);
                bool         isMatch = match.IsMatching(testPx);
                if (!isMatch)
                {
                    return(false);
                }
            }

            return(true);
        }
Пример #8
0
        public float[] ExtractHeaderPatternData(FastBitmapHSV bitmap, int patternIdx)
        {
            // scan area: 20x8
            float[] values = new float[20 * 8];
            for (int idx = 0; idx < values.Length; idx++)
            {
                values[idx] = 0.0f;
            }

            const int   monoSteps = 16;
            const float monoScale = 1.0f / monoSteps;

            for (int idxY = 0; idxY < 8; idxY++)
            {
                for (int idxX = 0; idxX < 20; idxX++)
                {
                    FastPixelHSV pixel = bitmap.GetPixel(posHeaderPattern[patternIdx].X + idxX, posHeaderPattern[patternIdx].Y + idxY);
                    int          monoV = pixel.GetMonochrome() / (256 / monoSteps);

                    values[idxX + (idxY * 20)] = monoV * monoScale;
                }
            }

            return(values);
        }
Пример #9
0
        public static List <Point> TraceSpansH(FastBitmapHSV bitmap, Rectangle box, FastPixelMatch colorMatch, int minSize, bool bDebugMode = false)
        {
            List <Point> result    = new List <Point>();
            int          lastX     = -1;
            bool         bHasMatch = false;

            for (int IdxX = box.Left; IdxX <= box.Right; IdxX++)
            {
                bHasMatch = false;
                for (int IdxY = box.Top; IdxY <= box.Bottom; IdxY++)
                {
                    FastPixelHSV testPx = bitmap.GetPixel(IdxX, IdxY);
                    bHasMatch = colorMatch.IsMatching(testPx);
                    if (bHasMatch)
                    {
                        if (bDebugMode)
                        {
                            Console.WriteLine("[" + IdxX + ", " + IdxY + "] " + testPx + " => match!");
                        }
                        break;
                    }
                }

                if (lastX == -1 && bHasMatch)
                {
                    lastX = IdxX;
                }
                else if (lastX >= 0 && !bHasMatch)
                {
                    int spanSize = IdxX - lastX;
                    if (spanSize > minSize)
                    {
                        if (bDebugMode)
                        {
                            Console.WriteLine(">> adding span: " + lastX + ", size:" + spanSize);
                        }
                        result.Add(new Point(lastX, spanSize));
                    }

                    lastX = -1;
                }
            }

            if (lastX >= 0 && bHasMatch)
            {
                int spanSize = box.Right - lastX + 1;
                if (spanSize > minSize)
                {
                    if (bDebugMode)
                    {
                        Console.WriteLine(">> adding span: " + lastX + ", size:" + spanSize);
                    }
                    result.Add(new Point(lastX, spanSize));
                }
            }

            return(result);
        }
Пример #10
0
        private void ScanBurst(FastBitmapHSV bitmap, ScreenData screenData)
        {
            float monoAcc = 0.0f;

            for (int idxY = 0; idxY < rectBurstActive.Height; idxY++)
            {
                for (int idxX = 0; idxX < rectBurstActive.Width; idxX++)
                {
                    FastPixelHSV testPx = bitmap.GetPixel(rectBurstActive.X + idxX, rectBurstActive.Y + idxY);
                    monoAcc += testPx.GetMonochrome();
                }
            }

            float monoAvg       = monoAcc / (rectBurstActive.Width * rectBurstActive.Height);
            float centerFillPct = 0;

            if (monoAvg < 15)
            {
                screenData.BurstState = EBurstState.Active;
            }
            else
            {
                centerFillPct = ScreenshotUtilities.CountFillPct(bitmap, rectBurstCenter, matchBurstCenter);
                if (centerFillPct > 0.75f)
                {
                    screenData.BurstState      = EBurstState.ReadyAndCenter;
                    screenData.BurstMarkerPctX = 0.5f;
                    screenData.BurstMarkerPctY = 0.5f;

                    if (DebugLevel >= EDebugLevel.Verbose)
                    {
                        Rectangle box = GetSpecialActionBox((int)ESpecialBox.BurstCenter);
                        DrawRectangle(bitmap, box.X, box.Y, box.Width, box.Height, 255);
                    }
                }
                else
                {
                    ScanBurstPosition(bitmap, screenData);

                    if (DebugLevel >= EDebugLevel.Verbose && screenData.BurstState == EBurstState.Ready)
                    {
                        Rectangle box = GetSpecialActionBox((int)ESpecialBox.BurstReady);
                        DrawRectangle(bitmap, box.X, box.Y, box.Width, box.Height, 255);
                    }
                }
            }

            if (DebugLevel >= EDebugLevel.Simple)
            {
                Console.WriteLine("{0} ScanBurst: {1}", ScannerName, screenData.BurstState);
            }
            if (DebugLevel >= EDebugLevel.Verbose)
            {
                Console.WriteLine(">> monoAvg: {0}, centerFillPct: {1}", monoAvg, centerFillPct);
            }
        }
Пример #11
0
        public override bool IsMatching(FastPixelHSV pixel)
        {
            if ((pixel.Monochrome >= MonoMin) && (pixel.Monochrome <= MonoMax))
            {
                int Hue = pixel.GetHue();
                return((Hue >= HueMin) && (Hue <= HueMax));
            }

            return(false);
        }
Пример #12
0
        protected void ScanActionSlot(FastBitmapHSV bitmap, Rectangle bounds, ActionData actionData, int slotIdx)
        {
            for (int idxY = 0; idxY < rectActionAvail.Height; idxY++)
            {
                for (int idxX = 0; idxX < rectActionAvail.Width; idxX++)
                {
                    FastPixelHSV testPx = bitmap.GetPixel(bounds.X + rectActionAvail.X + idxX, bounds.Y + rectActionAvail.Y + idxY);
                    bool         match  = matchActionAvail.IsMatching(testPx);
                    if (match)
                    {
                        actionData.isValid = true;
                        break;
                    }
                }
            }

            if (actionData.isValid)
            {
                float[] pixelInput = ExtractActionSlotWeaponData(bitmap, slotIdx);
                actionData.weaponClass = (EWeaponType)classifierWeapon.Calculate(pixelInput, out float dummyPct);
                actionData.element     = ScanElementType(bitmap, bounds);
                actionData.hasBoost    = HasElemBoost(bitmap, slotIdx);
            }

            if (DebugLevel >= EDebugLevel.Simple)
            {
                Console.WriteLine("{0} Action[{1}]: valid:{2}, class:{3}, elem: {4}", ScannerName, slotIdx,
                                  actionData.isValid,
                                  actionData.weaponClass,
                                  actionData.element);
            }
            if (DebugLevel >= EDebugLevel.Verbose)
            {
                var minMono = 255;
                var maxMono = 0;
                for (int idxY = 0; idxY < rectActionAvail.Height; idxY++)
                {
                    for (int idxX = 0; idxX < rectActionAvail.Width; idxX++)
                    {
                        FastPixelHSV testPx = bitmap.GetPixel(bounds.X + rectActionAvail.X + idxX, bounds.Y + rectActionAvail.Y + idxY);
                        minMono = Math.Min(minMono, testPx.GetMonochrome());
                        maxMono = Math.Max(maxMono, testPx.GetMonochrome());
                    }
                }

                Console.WriteLine(">> avail M:{0}..{1} (x:{2},y:{3},w:{4},h:{5})",
                                  minMono, maxMono,
                                  bounds.X + rectActionAvail.X, bounds.Y + rectActionAvail.Y,
                                  rectActionAvail.Width, rectActionAvail.Height);
            }
        }
Пример #13
0
 public static void FindColorRange(FastBitmapHSV bitmap, Rectangle box, out int minMono, out int maxMono)
 {
     minMono = 255;
     maxMono = 0;
     for (int IdxY = box.Top; IdxY <= box.Bottom; IdxY++)
     {
         for (int IdxX = box.Left; IdxX <= box.Right; IdxX++)
         {
             FastPixelHSV testPx = bitmap.GetPixel(IdxX, IdxY);
             minMono = Math.Min(minMono, testPx.Monochrome);
             maxMono = Math.Max(maxMono, testPx.Monochrome);
         }
     }
 }
Пример #14
0
        private float GetActionSlotPixelValue(FastPixelHSV pixel)
        {
            const int hueSteps  = 16;
            const int monoSteps = 16;

            const float monoScale = 1.0f / monoSteps;
            const float hueScale  = monoScale / hueSteps;

            int hueV  = pixel.GetHue() / (360 / hueSteps);
            int monoV = pixel.GetMonochrome() / (256 / monoSteps);

            float pixelV = (hueV * hueScale) + (monoV * monoScale);

            return(pixelV);
        }
Пример #15
0
        public static float CountFillPct(FastBitmapHSV bitmap, Rectangle box, FastPixelMatch colorMatch)
        {
            int totalPixels = (box.Width + 1) * (box.Height + 1);
            int matchPixels = 0;

            for (int IdxY = box.Top; IdxY <= box.Bottom; IdxY++)
            {
                for (int IdxX = box.Left; IdxX <= box.Right; IdxX++)
                {
                    FastPixelHSV testPx = bitmap.GetPixel(IdxX, IdxY);
                    matchPixels += colorMatch.IsMatching(testPx) ? 1 : 0;
                }
            }

            return((float)matchPixels / totalPixels);
        }
Пример #16
0
        protected void DrawRectangle(FastBitmapHSV bitmap, int posX, int posY, int width, int height, byte color, int border = 1)
        {
            FastPixelHSV pixelOb = new FastPixelHSV(color, color, color);

            for (int idxX = 0; idxX < width; idxX++)
            {
                bitmap.SetPixel(posX + idxX, posY - border, pixelOb);
                bitmap.SetPixel(posX + idxX, posY + height + border, pixelOb);
            }

            for (int idxY = 0; idxY < height; idxY++)
            {
                bitmap.SetPixel(posX - border, posY + idxY, pixelOb);
                bitmap.SetPixel(posX + width + border, posY + idxY, pixelOb);
            }
        }
Пример #17
0
        protected void GetAverageChestColor(FastBitmapHSV bitmap, Point chestPos, out int avgHue, out int avgSat)
        {
            float scale  = 1.0f / (rectChestArea.Width * rectChestArea.Height);
            float accHue = 0;
            float accSat = 0;

            for (int idxX = 0; idxX < rectChestArea.Width; idxX++)
            {
                for (int idxY = 0; idxY < rectChestArea.Height; idxY++)
                {
                    FastPixelHSV testPx = bitmap.GetPixel(chestPos.X + rectChestArea.X + idxX, chestPos.Y + rectChestArea.Y + idxY);
                    accHue += testPx.GetHue();
                    accSat += testPx.GetSaturation();
                }
            }

            avgHue = (int)(accHue * scale);
            avgSat = (int)(accSat * scale);
        }
Пример #18
0
        public override bool IsMatching(FastPixelHSV pixel)
        {
            int Saturation = pixel.GetSaturation();

            if ((Saturation < SaturationMin) || (Saturation > SaturationMax) ||
                (pixel.Value < ValueMin) || (pixel.Value > ValueMax))
            {
                return(false);
            }

            int Hue = pixel.GetHue();

            if (HueMin < 0 && Hue > 200)
            {
                Hue -= 360;
            }

            return((Hue >= HueMin) && (Hue <= HueMax));
        }
Пример #19
0
        public static FastPixelHSV GetAverageColor(FastBitmapHSV bitmap, Rectangle bounds)
        {
            float hueAcc = 0.0f;
            float satAcc = 0.0f;
            float valAcc = 0.0f;
            float scale  = 1.0f / bounds.Width;

            for (int idx = 0; idx < bounds.Width; idx++)
            {
                FastPixelHSV testPx = bitmap.GetPixel(bounds.X + idx, bounds.Y);
                hueAcc += testPx.GetHue();
                satAcc += testPx.GetSaturation();
                valAcc += testPx.GetValue();
            }

            FastPixelHSV avgPx = new FastPixelHSV();

            avgPx.SetHSV((int)(hueAcc * scale), (int)(satAcc * scale), (int)(valAcc * scale));
            return(avgPx);
        }
Пример #20
0
        private void ScanBurstPosition(FastBitmapHSV bitmap, ScreenData screenData)
        {
            bool hasMarker = false;

            for (int idxY = 0; idxY < rectBurstArea.Height; idxY++)
            {
                for (int idxX = 0; idxX < rectBurstArea.Width; idxX++)
                {
                    FastPixelHSV testPx  = bitmap.GetPixel(rectBurstArea.X + idxX, rectBurstArea.Y + idxY);
                    bool         isMatch = matchBurstMarker.IsMatching(testPx);
                    if (isMatch)
                    {
                        hasMarker = HasBurstMarker(bitmap, rectBurstArea.X + idxX, rectBurstArea.Y + idxY);
                        if (hasMarker)
                        {
                            screenData.BurstState      = EBurstState.Ready;
                            screenData.BurstMarkerPctX = idxX * 1.0f / rectBurstArea.Width;
                            screenData.BurstMarkerPctY = idxY * 1.0f / rectBurstArea.Height;
                            cachedBurstPos             = new Point(rectBurstArea.X + idxX, rectBurstArea.Y + idxY);

                            DrawRectangle(bitmap, rectBurstArea.X + idxX - 15, rectBurstArea.Y + idxY - 15, 30, 30, 255);
                            break;
                        }
                    }
                }

                if (hasMarker)
                {
                    break;
                }
            }

            if (DebugLevel >= EDebugLevel.Simple)
            {
                Console.WriteLine("{0} ScanBurstPosition: {1}", ScannerName, screenData.BurstState);
            }
            if (DebugLevel >= EDebugLevel.Verbose)
            {
                Console.WriteLine(">> marker.X:{0:P2}, marker.Y:{1:P2}", screenData.BurstMarkerPctX, screenData.BurstMarkerPctY);
            }
        }
Пример #21
0
        protected FastPixelHSV[] FindSpecialActionButton(FastBitmapHSV bitmap)
        {
            FastPixelHSV[] samples = new FastPixelHSV[posBigButton.Length];
            samples[0] = bitmap.GetPixel(posBigButton[0].X, posBigButton[0].Y);

            int maxHDiff = 0;

            for (int idx = 1; idx < samples.Length; idx++)
            {
                samples[idx] = bitmap.GetPixel(posBigButton[idx].X, posBigButton[idx].Y);

                int hDiff = Math.Abs(samples[idx].GetHue() - samples[0].GetHue());
                if (maxHDiff < hDiff)
                {
                    maxHDiff = hDiff;
                }
            }

            var hasSpecialAction = (maxHDiff < 20);

            return(hasSpecialAction ? samples : null);
        }
Пример #22
0
        public float[] ExtractDemonCounterData(FastBitmapHSV bitmap, int side)
        {
            // scan area: 50x10
            float[] values = new float[50 * 10];
            for (int idx = 0; idx < values.Length; idx++)
            {
                values[idx] = 0.0f;
            }

            Rectangle bounds = (side == 0) ? rectDemonL : rectDemonR;

            for (int idxY = 0; idxY < 10; idxY++)
            {
                for (int idxX = 0; idxX < 50; idxX++)
                {
                    FastPixelHSV pixel = bitmap.GetPixel(bounds.X + idxX, bounds.Y + idxY);
                    values[idxX + (idxY * 50)] = GetDemonPixelValue(pixel);
                }
            }

            return(values);
        }
Пример #23
0
        public static Bitmap CreateBitmapWithShapes(FastBitmapHSV bitmap, List <Rectangle> listBounds)
        {
            Bitmap bmp = new Bitmap(bitmap.Width, bitmap.Height);

            unsafe
            {
                BitmapData bitmapData    = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, bmp.PixelFormat);
                int        bytesPerPixel = Image.GetPixelFormatSize(bmp.PixelFormat) / 8;
                int        bytesPerRow   = bitmapData.Width * bytesPerPixel;

                for (int IdxY = 0; IdxY < bmp.Height; IdxY++)
                {
                    byte *pixels = (byte *)bitmapData.Scan0 + (IdxY * bitmapData.Stride);
                    for (int IdxByte = 0; IdxByte < bytesPerRow; IdxByte += bytesPerPixel)
                    {
                        FastPixelHSV writePx    = bitmap.GetPixel(IdxByte / bytesPerPixel, IdxY);
                        Color        writeColor = Color.FromArgb(writePx.Monochrome, writePx.Monochrome, writePx.Monochrome);
                        //Color writeColor = GetColorFromHSV(writePx);
                        pixels[IdxByte + 3] = writeColor.A;
                        pixels[IdxByte + 2] = writeColor.R;
                        pixels[IdxByte + 1] = writeColor.G;
                        pixels[IdxByte + 0] = writeColor.B;
                    }
                }

                bmp.UnlockBits(bitmapData);
            }

            using (Graphics gBmp = Graphics.FromImage(bmp))
            {
                if (listBounds.Count > 0)
                {
                    Pen boundsPen = new Pen(Color.Cyan);
                    gBmp.DrawRectangles(boundsPen, listBounds.ToArray());
                }
            }

            return(bmp);
        }
Пример #24
0
        protected float[] ExtractStatData(FastBitmapHSV bitmap, Point[] playerPos, int playerIdx, int statIdx)
        {
            // scan area: (9+1)x7
            float[] values   = new float[(11 + 1) * 9];
            int     writeIdx = 0;

            for (int idxY = 0; idxY < 9; idxY++)
            {
                float accHueLine = 0.0f;
                for (int idxX = 0; idxX < 11; idxX++)
                {
                    FastPixelHSV pixel = bitmap.GetPixel(playerPos[playerIdx].X + posStatOffset[statIdx].X + idxX - 1, playerPos[playerIdx].Y + posStatOffset[statIdx].Y + idxY - 1);
                    values[writeIdx] = pixel.GetMonochrome() / 255.0f;
                    accHueLine      += pixel.GetHue() / 360.0f;
                    writeIdx++;
                }

                values[writeIdx] = accHueLine / 11;
                writeIdx++;
            }

            return(values);
        }
Пример #25
0
        public static bool CreateFloodFillBitmap(FastBitmapHSV srcBitmap, Point floodOrigin, Size floodExtent, FastPixelMatch colorMatch,
                                                 out FastBitmapHSV floodBitmap, out Rectangle floodBounds, bool bDebugMode = false)
        {
            List <Point> floodPoints = new List <Point>();
            int          minX        = floodOrigin.X;
            int          maxX        = floodOrigin.X;
            int          minY        = floodOrigin.Y;
            int          maxY        = floodOrigin.Y;
            Rectangle    boundRect   = new Rectangle(floodOrigin.X - floodExtent.Width, floodOrigin.Y - floodExtent.Height, floodExtent.Width * 2, floodExtent.Height * 2);

            Stack <Point> openList = new Stack <Point>();

            openList.Push(floodOrigin);

            while (openList.Count > 0)
            {
                Point testPoint = openList.Pop();
                if (floodPoints.Contains(testPoint))
                {
                    continue;
                }

                FastPixelHSV testPx = srcBitmap.GetPixel(testPoint.X, testPoint.Y);
                if (bDebugMode)
                {
                    Console.WriteLine("[" + testPoint.X + ", " + testPoint.Y + "] " + testPx + ", match:" + colorMatch.IsMatching(testPx) + ", inBounds:" + boundRect.Contains(testPoint));
                }

                if (colorMatch.IsMatching(testPx) && boundRect.Contains(testPoint))
                {
                    floodPoints.Add(testPoint);

                    minX = Math.Min(minX, testPoint.X);
                    maxX = Math.Max(maxX, testPoint.X);
                    minY = Math.Min(minY, testPoint.Y);
                    maxY = Math.Max(maxY, testPoint.Y);

                    openList.Push(new Point(testPoint.X - 1, testPoint.Y));
                    openList.Push(new Point(testPoint.X + 1, testPoint.Y));
                    openList.Push(new Point(testPoint.X, testPoint.Y - 1));
                    openList.Push(new Point(testPoint.X, testPoint.Y + 1));
                    openList.Push(new Point(testPoint.X - 1, testPoint.Y - 1));
                    openList.Push(new Point(testPoint.X + 1, testPoint.Y - 1));
                    openList.Push(new Point(testPoint.X - 1, testPoint.Y + 1));
                    openList.Push(new Point(testPoint.X + 1, testPoint.Y + 1));
                }
            }

            floodBounds = new Rectangle(minX, minY, maxX - minX + 1, maxY - minY + 1);
            if (floodPoints.Count > 0)
            {
                floodBitmap = new FastBitmapHSV(floodBounds.Width, floodBounds.Height);
                int numPx = floodBounds.Width * floodBounds.Height;

                for (int Idx = 0; Idx < numPx; Idx++)
                {
                    floodBitmap.SetPixel(Idx, new FastPixelHSV(false));
                }

                foreach (Point p in floodPoints)
                {
                    int Idx = (p.X - minX) + ((p.Y - minY) * floodBounds.Width);
                    floodBitmap.SetPixel(Idx, new FastPixelHSV(true));
                }
            }
            else
            {
                floodBitmap = null;
            }

            return(floodBitmap != null);
        }
Пример #26
0
        protected bool HasElemBoostMarker(FastBitmapHSV bitmap, int posX, int posY, int slotIdx)
        {
            // samplesIn: hue: 20 +- 30, higher Y = lower hue, first 3 (center column) can be a super bright wildcard
            // samplesOut: similar hue, low V (dark)

            FastPixelHSV[] samplesIn    = new FastPixelHSV[posBoostIn.Length];
            int            numHueDec    = 0;
            int            numWildCards = 0;
            int            numMatching  = 0;

            for (int idx = 0; idx < samplesIn.Length; idx++)
            {
                samplesIn[idx] = bitmap.GetPixel(posX + posBoostIn[idx].X, posY + posBoostIn[idx].Y);
                bool isMatching = matchBoostIn.IsMatching(samplesIn[idx]);
                numMatching += isMatching ? 1 : 0;

                if ((idx > 0) && (posBoostIn[idx - 1].Y < posBoostIn[idx].Y))
                {
                    numHueDec += (samplesIn[idx - 1].GetHue() >= samplesIn[idx].GetHue()) ? 1 : 0;
                }

                if (idx < 3 && !isMatching)
                {
                    numWildCards += matchBoostInW.IsMatching(samplesIn[idx]) ? 1 : 0;
                }
            }

            bool matchIn = ((numMatching + numWildCards) == samplesIn.Length) && (numHueDec == 3) && (numWildCards < 2);

            FastPixelHSV[] samplesOut = new FastPixelHSV[posBoostOut.Length];
            bool           matchOut   = true;

            for (int idx = 0; idx < samplesOut.Length; idx++)
            {
                samplesOut[idx] = bitmap.GetPixel(posX + posBoostOut[idx].X, posY + posBoostOut[idx].Y);
                matchOut        = matchOut && matchBoostOut.IsMatching(samplesOut[idx]);
            }

            var showLogs =
                //(slotIdx == 2) && (posY == 501);
                //((slotIdx == 1) || (slotIdx == 3)) && (matchIn && matchOut);
                false;

            if (DebugLevel >= EDebugLevel.Verbose && showLogs)
            {
                Console.WriteLine("HasElemBoostMarker[{0}], Y:{1}, In.HueDec:{2}, matchIn:{3}, matchOut:{4} => {5}",
                                  slotIdx, posY, numHueDec, matchIn, matchOut, matchIn && matchOut);

                string desc = "";
                for (int idx = 0; idx < samplesIn.Length; idx++)
                {
                    if (idx > 0)
                    {
                        desc += ", ";
                    }
                    desc += string.Format("({0},{1} = {2}):{3}",
                                          posX + posBoostIn[idx].X, posY + posBoostIn[idx].Y,
                                          samplesIn[idx],
                                          matchBoostIn.IsMatching(samplesIn[idx]) ? "Yes" : matchBoostInW.IsMatching(samplesIn[idx]) ? "Maybe" : "No");
                }
                Console.WriteLine("   IN({0}): {1}", matchBoostIn, desc);

                desc = "";
                for (int idx = 0; idx < samplesOut.Length; idx++)
                {
                    if (idx > 0)
                    {
                        desc += ", ";
                    }
                    desc += string.Format("({0},{1} = {2}):{3}",
                                          posX + posBoostOut[idx].X, posY + posBoostOut[idx].Y,
                                          samplesOut[idx], matchBoostOut.IsMatching(samplesOut[idx]));
                }
                Console.WriteLine("  OUT({0}): {1}", matchBoostOut, desc);
            }

            return(matchIn && matchOut);
        }
Пример #27
0
        protected EElementType ScanElementType(FastBitmapHSV bitmap, Rectangle bounds)
        {
            EElementType element    = EElementType.Unknown;
            int          countElemR = 0;
            int          countElemG = 0;
            int          countElemB = 0;
            int          countTotal = 0;

            const int hueDrift = 30;
            const int hueB     = 180;
            const int hueG     = 130;
            const int hueR     = 15;

            foreach (var sampleBounds in rectActionElements)
            {
                for (int idxY = 0; idxY < sampleBounds.Height; idxY++)
                {
                    for (int idxX = 0; idxX < sampleBounds.Width; idxX++)
                    {
                        FastPixelHSV testPx = bitmap.GetPixel(bounds.X + sampleBounds.X + idxX, bounds.Y + sampleBounds.Y + idxY);
                        countTotal++;

                        int testMono = testPx.GetMonochrome();
                        if (testMono < 210)
                        {
                            int testHue = testPx.GetHue();
                            countElemR += ((testHue > (hueR + 360 - hueDrift)) || (testHue < (hueR + hueDrift))) ? 1 : 0;
                            countElemG += ((testHue > (hueG - hueDrift)) && (testHue < (hueG + hueDrift))) ? 1 : 0;
                            countElemB += ((testHue > (hueB - hueDrift)) && (testHue < (hueB + hueDrift))) ? 1 : 0;
                        }
                    }
                }
            }

            int minThr = countTotal * 30 / 100;

            if ((countElemR > minThr) && (countElemR > countElemG) && (countElemR > countElemB))
            {
                element = EElementType.Fire;
            }
            else if ((countElemG > minThr) && (countElemG > countElemR) && (countElemG > countElemB))
            {
                element = EElementType.Wind;
            }
            else if ((countElemB > minThr) && (countElemB > countElemR) && (countElemB > countElemG))
            {
                element = EElementType.Water;
            }

            if (element == EElementType.Unknown)
            {
                countElemR = 0;
                countElemG = 0;
                countElemB = 0;

                for (int idxY = 0; idxY < bounds.Height; idxY++)
                {
                    for (int idxX = 0; idxX < bounds.Width; idxX++)
                    {
                        FastPixelHSV testPx = bitmap.GetPixel(bounds.X + idxX, bounds.Y + idxY);

                        int testMono = testPx.GetMonochrome();
                        if (testMono < 210)
                        {
                            int testHue = testPx.GetHue();
                            countElemR += ((testHue > (hueR + 360 - hueDrift)) || (testHue < (hueR + hueDrift))) ? 1 : 0;
                            countElemG += ((testHue > (hueG - hueDrift)) && (testHue < (hueG + hueDrift))) ? 1 : 0;
                            countElemB += ((testHue > (hueB - hueDrift)) && (testHue < (hueB + hueDrift))) ? 1 : 0;
                        }
                    }
                }

                countTotal = bounds.Width * bounds.Height;

                minThr = countTotal * 30 / 100;
                if ((countElemR > minThr) && (countElemR > countElemG) && (countElemR > countElemB))
                {
                    element = EElementType.Fire;
                }
                else if ((countElemG > minThr) && (countElemG > countElemR) && (countElemG > countElemB))
                {
                    element = EElementType.Wind;
                }
                else if ((countElemB > minThr) && (countElemB > countElemR) && (countElemB > countElemG))
                {
                    element = EElementType.Water;
                }
            }

            if (DebugLevel >= EDebugLevel.Verbose)
            {
                Console.WriteLine(">> elem counters: R:{0}, G:{1}, B:{2} => {3}", countElemR, countElemG, countElemB, element);
            }
            return(element);
        }
Пример #28
0
        protected bool HasOkButtonArea(FastBitmapHSV bitmap, ScreenData screenData)
        {
            FastPixelHSV[] avgPx = new FastPixelHSV[rectButtonPos.Length];
            for (int idx = 1; idx < avgPx.Length; idx++)
            {
                avgPx[idx] = ScreenshotUtilities.GetAverageColor(bitmap, rectButtonPos[idx]);

                var scanOb = new ActionData();
                scanOb.buttonColor =
                    matchAvgRed.IsMatching(avgPx[idx]) ? EButtonColor.Red :
                    matchAvgWhite.IsMatching(avgPx[idx]) ? EButtonColor.White :
                    matchAvgSpec.IsMatching(avgPx[idx]) ? EButtonColor.Spec :
                    EButtonColor.Unknown;

                if (scanOb.buttonColor != EButtonColor.Unknown)
                {
                    float[] values = ExtractButtonData(bitmap, idx);
                    scanOb.buttonType = (EButtonType)classifierButtons.Calculate(values, out float DummyPct);

                    switch (scanOb.buttonColor)
                    {
                    case EButtonColor.Red: scanOb.isDisabled = avgPx[idx].GetValue() < 40; break;

                    case EButtonColor.White: scanOb.isDisabled = avgPx[idx].GetValue() < 70; break;

                    default: break;
                    }
                }

                screenData.actions[idx] = scanOb;
            }

            if (screenData.actions[(int)EButtonPos.CombatReportOk].buttonColor == EButtonColor.Red &&
                screenData.actions[(int)EButtonPos.CombatReportOk].buttonType == EButtonType.Ok &&
                screenData.actions[(int)EButtonPos.CombatReportRetry].buttonColor == EButtonColor.White &&
                (screenData.actions[(int)EButtonPos.CombatReportRetry].buttonType == EButtonType.Retry || screenData.actions[(int)EButtonPos.CombatReportRetry].buttonType == EButtonType.Next))
            {
                screenData.mode = EMessageType.CombatReport;
            }
            else if (screenData.actions[(int)EButtonPos.CombatStart].buttonColor == EButtonColor.Red &&
                     screenData.actions[(int)EButtonPos.CombatStart].buttonType == EButtonType.Start &&
                     screenData.actions[(int)EButtonPos.CombatDetails].buttonColor == EButtonColor.Spec &&
                     (screenData.actions[(int)EButtonPos.CombatDetails].buttonType == EButtonType.Details))
            {
                screenData.mode = EMessageType.CombatStart;
            }
            else if (screenData.actions[(int)EButtonPos.Center].buttonColor == EButtonColor.Red &&
                     screenData.actions[(int)EButtonPos.Center].buttonType == EButtonType.Ok)
            {
                screenData.mode = EMessageType.Ok;
            }
            else if (screenData.actions[(int)EButtonPos.CenterTwoLeft].buttonColor == EButtonColor.White &&
                     screenData.actions[(int)EButtonPos.CenterTwoLeft].buttonType == EButtonType.Cancel &&
                     screenData.actions[(int)EButtonPos.CenterTwoRight].buttonColor == EButtonColor.Red &&
                     screenData.actions[(int)EButtonPos.CenterTwoRight].buttonType == EButtonType.Ok)
            {
                screenData.mode = EMessageType.OkCancel;
            }
            else if (screenData.actions[(int)EButtonPos.Center].buttonColor == EButtonColor.White &&
                     screenData.actions[(int)EButtonPos.Center].buttonType == EButtonType.Close)
            {
                screenData.mode = EMessageType.Close;
            }

            if (DebugLevel >= EDebugLevel.Simple)
            {
                Console.WriteLine("{0} Mode: {1}", ScannerName, screenData.mode);
            }
            if (DebugLevel >= EDebugLevel.Verbose)
            {
                Console.WriteLine("  filterRed:({0}), filterWhite:({1}), filterSpec({2})", matchAvgRed, matchAvgWhite, matchAvgSpec);
                for (int idx = 1; idx < avgPx.Length; idx++)
                {
                    Console.WriteLine("  [{0}]:({1}), color:{2}, class:{3}",
                                      (EButtonPos)idx, avgPx[idx],
                                      screenData.actions[idx].buttonColor,
                                      screenData.actions[idx].buttonType);
                }
            }

            return(screenData.mode != EMessageType.Unknown);
        }
Пример #29
0
        public static List <int> TraceLineSegments(FastBitmapHSV bitmap, int posX, int posY, int incX, int incY, int traceLen,
                                                   FastPixelMatch colorMatch, int minSegSize, int segLimit, bool bDebugMode = false)
        {
            FastPixelHSV[] streakBuffer = new FastPixelHSV[minSegSize];
            int            bufferIdx    = 0;

            for (int Idx = 0; Idx < streakBuffer.Length; Idx++)
            {
                streakBuffer[Idx] = new FastPixelHSV(255, 255, 255);
            }

            List <int> result    = new List <int>();
            bool       bWasMatch = false;

            if (bDebugMode)
            {
                Console.WriteLine("TraceLineSegments [" + posX + ", " + posY + "] -> [" + (posX + (incX * traceLen)) + ", " + (posY + (incY * traceLen)) + "]");
            }

            for (int stepIdx = 0; stepIdx < traceLen; stepIdx++)
            {
                int          scanX  = posX + (stepIdx * incX);
                int          scanY  = posY + (stepIdx * incY);
                FastPixelHSV testPx = bitmap.GetPixel(scanX, scanY);

                streakBuffer[bufferIdx] = testPx;
                bufferIdx = (bufferIdx + 1) % minSegSize;

                bool bBufferMatching = true;
                for (int Idx = 0; Idx < streakBuffer.Length; Idx++)
                {
                    bBufferMatching = bBufferMatching && colorMatch.IsMatching(streakBuffer[Idx]);
                }

                if (bDebugMode)
                {
                    Console.WriteLine("  [" + scanX + ", " + scanY + "] " + testPx + " => match:" + colorMatch.IsMatching(testPx) + ", buffer:" + bBufferMatching);
                }

                if (bBufferMatching != bWasMatch)
                {
                    bWasMatch = bBufferMatching;

                    int segPos = bBufferMatching ?
                                 (incX != 0) ? (scanX - (incX * minSegSize)) : (scanY - (incY * minSegSize)) :
                                 (incX != 0) ? scanX : scanY;

                    result.Add(segPos);
                    if (bDebugMode)
                    {
                        Console.WriteLine("  >> mark segment:" + segPos);
                    }

                    if (result.Count >= segLimit && segLimit > 0)
                    {
                        break;
                    }
                }
            }

            return(result);
        }
Пример #30
0
        public static Point TraceBoundsH(FastBitmapHSV bitmap, Rectangle box, FastPixelMatch colorMatch, int maxGapSize, bool bDebugMode = false)
        {
            int boxCenter = (box.Right + box.Left) / 2;

            int  minX       = -1;
            int  gapStart   = -1;
            bool bPrevMatch = false;

            for (int IdxX = box.Left; IdxX < boxCenter; IdxX++)
            {
                bool bHasMatch = false;
                for (int IdxY = box.Top; IdxY <= box.Bottom; IdxY++)
                {
                    FastPixelHSV testPx = bitmap.GetPixel(IdxX, IdxY);
                    bHasMatch = colorMatch.IsMatching(testPx);
                    if (bHasMatch)
                    {
                        if (bDebugMode)
                        {
                            Console.WriteLine("[" + IdxX + ", " + IdxY + "] " + testPx + " => match!");
                        }
                        break;
                    }
                }

                if (bHasMatch)
                {
                    int gapSize = IdxX - gapStart;
                    if ((gapSize > maxGapSize && gapStart > 0) || (minX < 0))
                    {
                        minX     = IdxX;
                        gapStart = -1;
                    }

                    if (bDebugMode)
                    {
                        Console.WriteLine(">> gapSize:" + gapSize + ", gapStart:" + gapStart + ", bPrevMatch:" + bPrevMatch + " => minX:" + minX);
                    }
                }
                else
                {
                    if (bPrevMatch)
                    {
                        gapStart = IdxX;
                        if (bDebugMode)
                        {
                            Console.WriteLine(">> gapStart:" + gapStart);
                        }
                    }
                }

                bPrevMatch = bHasMatch;
            }

            if (minX >= 0)
            {
                int maxX = -1;
                gapStart   = -1;
                bPrevMatch = false;
                for (int IdxX = box.Right; IdxX > boxCenter; IdxX--)
                {
                    bool bHasMatch = false;
                    for (int IdxY = box.Top; IdxY <= box.Bottom; IdxY++)
                    {
                        FastPixelHSV testPx = bitmap.GetPixel(IdxX, IdxY);
                        bHasMatch = colorMatch.IsMatching(testPx);
                        if (bHasMatch)
                        {
                            if (bDebugMode)
                            {
                                Console.WriteLine("[" + IdxX + ", " + IdxY + "] " + testPx + " => match!");
                            }
                            break;
                        }
                    }

                    if (bHasMatch)
                    {
                        int gapSize = gapStart - IdxX;
                        if ((gapSize > maxGapSize && gapStart > 0) || (maxX < 0))
                        {
                            maxX     = IdxX;
                            gapStart = -1;
                        }

                        if (bDebugMode)
                        {
                            Console.WriteLine(">> gapSize:" + gapSize + ", gapStart:" + gapStart + ", bPrevMatch:" + bPrevMatch + " => maxX:" + maxX);
                        }
                    }
                    else
                    {
                        if (bPrevMatch)
                        {
                            gapStart = IdxX;
                            if (bDebugMode)
                            {
                                Console.WriteLine(">> gapStart:" + gapStart);
                            }
                        }
                    }

                    bPrevMatch = bHasMatch;
                }

                if (maxX > minX)
                {
                    return(new Point(minX, maxX - minX));
                }
                else
                {
                    if (bDebugMode)
                    {
                        Console.WriteLine(">> TraceBoundsH: no match on right side!");
                    }
                }
            }
            else
            {
                if (bDebugMode)
                {
                    Console.WriteLine(">> TraceBoundsH: no match on left side!");
                }
            }

            return(new Point());
        }