Changeset - cbcdc45e1b92
[Not reviewed]
default
0 1 0
Jason Maltzen - 5 years ago 2019-11-02 18:43:43
jason@hiddenachievement.com
Remove a debug message.
1 file changed with 1 insertions and 1 deletions:
0 comments (0 inline, 0 general)
ReactionRecorder.cs
Show inline comments
...
 
@@ -390,317 +390,317 @@ namespace DesertPaintLab
 
            {
 
                result &= pixels.DoesPixelMatch(x, y + i, color.IsMatch);
 
            }
 

	
 
            if (!result)
 
            {
 
                WriteLog("Swatch slice at {0}, {1} failed to match", x, y);
 
            }
 

	
 
            return result;
 
        }
 

	
 
        unsafe private bool IsPossibleSwatchUpperLeft(Pixels pixels, int x, int y)
 
        {
 
            int testPixelStart = pixels.ComputeOffset(x, y);
 

	
 
            if (testPixelStart < pixels.stride)
 
            {
 
                return false;
 
            }
 

	
 
            bool result = true;
 

	
 
            int swatchSolidWidth = swatchWidth - 4;
 
            int swatchSolidHeight = swatchHeight - 5; // 2 top and 3 bottom pixels are slightly different colors
 
            int swatchSolidLeftX = x + 2;
 
            int swatchSolidTopY = y + 2;
 
            int swatchSolidRightX = swatchSolidLeftX + swatchSolidWidth - 1;
 
            int swatchSolidBottomY = swatchSolidTopY + swatchSolidHeight - 1;
 

	
 
            PixelColor swatchColor = new PixelColor();
 
            pixels.ColorAt(swatchSolidLeftX, swatchSolidTopY, ref swatchColor);
 

	
 
            // Check the other 3 corners of the swatch size for color match
 
            PixelColor testColor = new PixelColor();
 
            result &= pixels.DoesPixelMatch(swatchSolidRightX, swatchSolidTopY, swatchColor.IsMatch);
 
            result &= pixels.DoesPixelMatch(swatchSolidLeftX, swatchSolidBottomY, swatchColor.IsMatch);
 
            result &= pixels.DoesPixelMatch(swatchSolidRightX, swatchSolidBottomY, swatchColor.IsMatch);
 

	
 
            if (!result)
 
            {
 
                // Box corners test failed
 
                // WriteLog("Failed to find left edge for potential swatch of color {2}, {3}, {4} at {0}, {1}", x, y, swatch_r, swatch_g, swatch_b);
 
                return false;
 
            }
 

	
 
            // scan down the right and left sides
 
            for (int yOff = 1; yOff < (swatchSolidHeight - 1); ++yOff)
 
            {
 
                result &= pixels.DoesPixelMatch(swatchSolidLeftX, swatchSolidTopY + yOff, swatchColor.IsMatch);
 
                if (!result)
 
                {
 
                    pixels.ColorAt(swatchSolidLeftX, swatchSolidTopY + yOff, ref testColor);
 
                    break;
 
                }
 
                result &= pixels.DoesPixelMatch(swatchSolidRightX, swatchSolidTopY + yOff, swatchColor.IsMatch);
 
                if (!result)
 
                {
 
                    pixels.ColorAt(swatchSolidRightX, swatchSolidTopY + yOff, ref testColor);
 
                }
 
            }
 
            if (!result)
 
            {
 
                WriteLog("Failed to find left/right edges for potential swatch of color {2}, {3}, {4} at {0}, {1} [failed color = {5},{6},{7}]", x, y, swatchColor.r, swatchColor.g, swatchColor.b, testColor.r, testColor.g, testColor.b);
 
                return false;
 
            }
 
            for (int xOff = 1; xOff < (swatchSolidWidth - 1); ++xOff)
 
            {
 
                result &= pixels.DoesPixelMatch(swatchSolidLeftX + xOff, swatchSolidTopY, swatchColor.IsMatch);
 
                if (!result)
 
                {
 
                    pixels.ColorAt(swatchSolidLeftX + xOff, swatchSolidTopY, ref testColor);
 
                    break;
 
                }
 
                result &= pixels.DoesPixelMatch(swatchSolidLeftX + xOff, swatchSolidBottomY, swatchColor.IsMatch);
 
                if (!result)
 
                {
 
                    pixels.ColorAt(swatchSolidLeftX + xOff, swatchSolidBottomY, ref testColor);
 
                    break;
 
                }
 
            }
 
            if (!result)
 
            {
 
                WriteLog("Failed to match upper/lower edges for potential swatch of color {2}, {3}, {4} at {0}, {1} [failed color = {5},{6},{7}]", x, y, swatchColor.r, swatchColor.g, swatchColor.b, testColor.r, testColor.g, testColor.b);
 
                return false;
 
            }
 

	
 

	
 
            // test the left edge for dark pixels -- the bottom-most pixel is bright now
 
            int i = 0;
 
            for (i = 1; result && i < swatchHeight - 1; ++i)
 
            {
 
                result &= pixels.DoesPixelMatch(x, y + i, PixelColor.IsDark);
 
            }
 
            if (!result)
 
            {
 
                // No dark border on the left side
 
                WriteLog("Failed to find left border for potential swatch of color {2}, {3}, {4} at {0}, {1}", x, y, swatchColor.r, swatchColor.g, swatchColor.b);
 
                return false;
 
            }
 

	
 
            // test the dark top border and for papyrus above and below the swatch
 
            bool borderError = false;
 
            int papyErrorCount = 0;
 
            for (i = 0; result && (i < swatchWidth); ++i)
 
            {
 
                bool isBorder = pixels.DoesPixelMatch(x + i, y, PixelColor.IsDark);
 
                result &= isBorder;
 
                if (!isBorder)
 
                {
 
                    borderError = true;
 
                }
 

	
 
                // Checking along the top of the swatch for papyrus
 
                // The row just above is shaded, so check 2 above
 
                if (y > 1)
 
                {
 
                    bool isPapyrus = pixels.DoesPixelMatch(x + i, y - 2, PixelColor.IsPapyrus);
 
                    papyErrorCount += isPapyrus ? 0 : 1;
 

	
 
                }
 
                else
 
                {
 
                    ++papyErrorCount;
 
                }
 

	
 
                // Checking along the bottom of the swatch for papyrus
 
                if (y < pixels.height)
 
                {
 
                    bool isPapyrus = pixels.DoesPixelMatch(x + i, y + swatchHeight, PixelColor.IsPapyrus);
 
                    papyErrorCount += isPapyrus ? 0 : 1;
 
                }
 
                else
 
                {
 
                    ++papyErrorCount;
 
                }
 
            }
 

	
 
            result &= (papyErrorCount < (swatchWidth / 20)); // allow up to 5% error rate checking for papy texture, because this seems to be inconsistent
 
            if (!result && ((i > (swatchWidth*0.8)) || (papyErrorCount >= (swatchWidth/20))))
 
            {
 
                if (!borderError && (papyErrorCount < swatchWidth))
 
                {
 
                    WriteLog("Found a potential swatch candidate of width {0} at {1},{2} that had {3} failures matching papyrus texture", i, x, y, papyErrorCount);
 
                }
 
            }
 

	
 
            return result;
 
        }
 

	
 
        unsafe private bool TestPosition(int x, int y, Pixels pixels, ref PaintColor reactedColor, ref int redPixelStart)
 
        {
 
            PixelColor pixelColor = new PixelColor();
 

	
 
            // Check 4 corners of solid area and left/right solid bar areas
 
            bool foundSwatch = IsPossibleSwatchUpperLeft(pixels, x, y); // ((pixel_r < 0x46) && (pixel_g < 0x46) && (pixel_b < 0x46));
 
            if (foundSwatch)
 
            {
 
                int borderXOffset = 0;
 
                for (borderXOffset = 2; foundSwatch && (borderXOffset < swatchTestWidth); ++borderXOffset)
 
                {
 
                    foundSwatch &= IsPossibleSwatchSlice(pixels, x + borderXOffset, y);
 
                    foundSwatch &= IsPossibleSwatchSlice(pixels, x + swatchWidth - borderXOffset, y);
 
                }
 
            }
 

	
 
            if (foundSwatch)
 
            {
 
                // WE FOUND THE SWATCH!
 
                // Now we know where the color bars are.
 
                int redPixelCount = pixels.LengthOfColorAt(x, y + redBarSpacing, PixelColor.IsRed);
 
                reactedColor.Red = (byte)Math.Round((float)redPixelCount * 255f / (float)colorBarWidth);
 

	
 
                int greenPixelCount = pixels.LengthOfColorAt(x, y + greenBarSpacing, PixelColor.IsGreen);
 
                reactedColor.Green = (byte)Math.Round((float)greenPixelCount * 255f / (float)colorBarWidth);
 

	
 
                int bluePixelCount = pixels.LengthOfColorAt(x, y + blueBarSpacing, PixelColor.IsBlue);
 
                reactedColor.Blue = (byte)Math.Round((float)bluePixelCount * 255f / (float)colorBarWidth);
 
                WriteLog("Found the color swatch at {0}, {1}. Color={2} Red={3}px Green={4}px Blue={5}px", x, y, reactedColor, redPixelCount, greenPixelCount, bluePixelCount);
 
                return true;
 
            }
 
            return false;
 
        }
 

	
 
        unsafe public bool CaptureReaction(byte* pixBytes, int screenshotWidth, int screenshotHeight, int stride)
 
        {
 
            PaintColor reactedColor = new PaintColor();
 
            int redPixelStart = 0;
 
            ScreenWidth = screenshotWidth;
 
            ScreenHeight = screenshotHeight;
 
            IsCaptured = false;
 
            _recordedColor.Clear();
 

	
 
            Pixels pixels = new Pixels
 
            {
 
                pixBytes = pixBytes,
 
                width = screenshotWidth,
 
                height = screenshotHeight,
 
                stride = stride,
 
                pixelMultiplier = pixelMultiplier
 
            };
 
            IsCaptured = false;
 
            if (!firstRun)
 
            {
 
                // If this is not the first run, let's check the last location, to see if the UI is still there.
 
                if (TestPosition(lastSwatchX, lastSwatchY, pixels, ref reactedColor, ref redPixelStart))
 
                {
 
                    IsCaptured = true;
 
                    RedBarX = (redPixelStart % stride) / 3;
 
                    RedBarY = redPixelStart / stride;
 
                    RecordedColor = reactedColor;
 
                    return true;
 
                }
 
                else
 
                {
 
                    firstRun = true;
 
                }
 
            }
 

	
 
            int startX;
 
            int endX;
 
            int startY;
 
            int endY;
 
            DesertPaintLab.AppSettings.Get("ScanOffsetX", out startX);
 
            DesertPaintLab.AppSettings.Get("ScanOffsetY", out startY);
 
            DesertPaintLab.AppSettings.Get("ScanLimitX", out endX);
 
            DesertPaintLab.AppSettings.Get("ScanLimitY", out endY);
 
            if (endX == 0) endX = screenshotWidth;
 
            if (endY == 0) endY = screenshotHeight;
 

	
 
            int patchTestSize = (swatchHeight / 2) - 1;
 
            PixelColor patchColor = new PixelColor();
 
            for (int roughX = startX; roughX < endX - colorBarWidth - patchTestSize; roughX += patchTestSize)
 
            {
 
                for (int roughY = startY; roughY < (endY - (blueBarSpacing + 10) - patchTestSize  /*53*/); roughY += patchTestSize)
 
                {
 
                    OnCaptureProgress?.Invoke(roughX, roughY);
 
                    if (!pixels.IsSolidPatchAt(roughX, roughY, patchTestSize, patchTestSize)) continue;
 
                    pixels.ColorAt(roughX, roughY, ref patchColor);
 
                    for (X = roughX - patchTestSize; X < roughX; ++X)
 
                    {
 
                        for (Y = roughY - patchTestSize; Y < roughY; ++Y)
 
                        {
 
                            if (TestPosition(X, Y, pixels, ref reactedColor, ref redPixelStart))
 
                            {
 
                                RedBarX = (redPixelStart % stride) / 3;
 
                                RedBarY = redPixelStart / stride;
 
                                RecordedColor = reactedColor;
 
                                lastSwatchX = X;
 
                                lastSwatchY = Y;
 
                                firstRun = false;
 
                                IsCaptured = true;
 
                                return true;
 
                            }
 
                        }
 
                    }
 
                    System.Console.WriteLine("False-positive patch of color {0},{1},{2} at {3},{4}", patchColor.r, patchColor.g, patchColor.b, roughX, roughY);
 
                    //System.Console.WriteLine("False-positive patch of color {0},{1},{2} at {3},{4}", patchColor.r, patchColor.g, patchColor.b, roughX, roughY);
 
                }
 
            }
 
            return false;
 
        }
 

	
 
        public bool RecordReaction(PlayerProfile profile, PaintColor expectedColor, PaintColor reactedColor, Reagent[] reagents)
 
        {
 
            bool saved = false;
 
            int r, g, b;
 
            if (reagents[2] != null)
 
            {
 
                // A 3-reagent reaction.
 
                Reaction reaction1 = profile.FindReaction(reagents[0], reagents[1]);
 
                Reaction reaction2 = profile.FindReaction(reagents[0], reagents[2]);
 
                Reaction reaction3 = profile.FindReaction(reagents[1], reagents[2]);
 
                
 
                r = reactedColor.Red - expectedColor.Red;
 
                g = reactedColor.Green - expectedColor.Green;
 
                b = reactedColor.Blue - expectedColor.Blue;
 
                
 
                if (reaction2 == null)
 
                {
 
                    r = r - reaction1.Red - reaction3.Red;
 
                    g = g - reaction1.Green - reaction3.Green;
 
                    b = b - reaction1.Blue - reaction3.Blue;
 
                    Reaction reaction = new Reaction(r, g, b);
 
                    profile.SetReaction(reagents[0], reagents[2], reaction);
 
                    profile.Save();
 
                    saved = true;
 
                    OnReactionRecorded?.Invoke(reagents[0], reagents[2], reaction);
 
                }
 
                else if (reaction3 == null)
 
                {
 
                    r = r - reaction1.Red - reaction2.Red;
 
                    g = g - reaction1.Green - reaction2.Green;
 
                    b = b - reaction1.Blue - reaction2.Blue;
 
                    Reaction reaction = new Reaction(r, g, b);
 
                    profile.SetReaction(reagents[1], reagents[2], reaction);
 
                    profile.Save();
 
                    saved = true;
 
                    OnReactionRecorded?.Invoke(reagents[1], reagents[2], reaction);
 
                }
 
            }
 
            else if ((reagents[0] != null) && (reagents[1] != null))
 
            {
 
                // A 2-reagent reaction.
 
                r = reactedColor.Red - expectedColor.Red;
 
                g = reactedColor.Green - expectedColor.Green;
 
                b = reactedColor.Blue - expectedColor.Blue;
 
                Reaction reaction = new Reaction(r, g, b);
 
                profile.SetReaction(reagents[0], reagents[1], reaction);
 
                profile.Save();
 
                saved = true;
 
                OnReactionRecorded?.Invoke(reagents[0], reagents[1], reaction);
 
            }
 
            return saved;
 
        }
 
    }
 
}
 

	
0 comments (0 inline, 0 general)