Results 1 to 13 of 13

Thread: Enhancement/Question - Finding Road Colors

  1. #1
    Join Date
    Oct 2006
    Posts
    119
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default Enhancement/Question - Finding Road Colors

    I couldn't figure out how to work the road color thing in SRL (unless i did figure it out and it doesn't work like i liked), so I made this thing. You might need to edit the numbers 4000000 and 8000000 which is what i've found all road colors being with the exception of barbarian village. Even if it finds a bad color it doesn't jack up. Still in a beta form, never been tested limitless.

    Edit: If you're looking for enhancement use tarajunky's posted below. Dominates mine...

    SCAR Code:
    program New;
    {.Include SRL\SRL.Scar}
    {.Include SRL\SRL\Extended\xColor.Scar}

    var
      RememberRoadColors: Boolean;
      ABadColor: Array of Integer;

    Function InArray(One:Integer; Arrays:Array of Integer):Boolean;
    var c:integer;
      Begin
        For c:=0 to (GetArrayLength(Arrays) - 1) Do
          If(One = Arrays[c])Then
            Result:= true;
      End;

    //Start of Read/Write Arrays to Files
    Function ArrayToString(Arrays: Array of Integer):String;
    var
     c, arraylength:integer;
     thestring:string;
      Begin
        Arraylength:= GetArrayLength(Arrays) - 1;
        for c:=0 to Arraylength do
          thestring:= (thestring + IntToStr(Arrays[c])+',');
        Result:= thestring;
      End;

    Function StringToArray(Source, Split:String):Array of Integer;
    Var
      Arrays: Array of Integer;
      ArrayLength, c, v:integer;
      Char: String;
      Begin
        Source:= Trim(Source);
        Split:= Trim(Split);
        ArrayLength := 1;
        SetArrayLength(Arrays, ArrayLength);
        //Writeln('Source: '+Source);
        //Writeln('Length: '+ IntToStr(Length(Source)));
        For c := 0 to (Length(Source) - 1) do
          Begin
            //Writeln('C: '+ IntToStr(c));
            Char:= Trim(StrGet(Source, c + 1));
            //Writeln('Char: '+Char);
            //if((Char = Split) or (Char = (' ' + Split))) or (Char = (Split + ' ')))Then
            if(Char = Split)Then
              Begin
                Arrays[ArrayLength - 1]:= V;
                V:= 0;
                ArrayLength:= ArrayLength + 1;
                SetArrayLength(Arrays, ArrayLength + 1);
              End else
                Begin
                  V:= StrToInt(Trim(IntToStr(V) + Char));
                End;
          End;
        SetArrayLength(Arrays, ArrayLength - 1);// There's an Extra Slot added so this removes it
        Result:= Arrays;
      End;

    Function ReadArrayFromFile(Path, Split:String):Array of Integer;
    Var
      Filenum: Integer;
      Thestuff: String;
      Arrays: Array of Integer;
      Begin
        Filenum := Openfile(Path, True);//not sure about true/false thing
        If(Filenum >= 0)Then
          Begin
            If(ReadFileString(Filenum, Thestuff, FileSize(Filenum)))Then
              Begin
                Arrays:= StringToArray(Thestuff, Split);
                Writeln('Array Read: '+ArrayToString(Arrays));
                Result:= Arrays;
              End else
                Begin
                  Writeln('Cannot read array');
                  Result:= Arrays;
                End;
          CloseFile(Filenum);
          End;
      End;

    Function WriteArrayToFile(Path: String; Arrays: Array of Integer):Boolean;
    Var
      Filenum: Integer;
      Begin
        Filenum:=RewriteFile(Path, True);//not sure about true/false thing
        if(Filenum >= 0)Then
          Begin
            Result:= WriteFileString(Filenum, ArrayToString(ABadColor));
            Writeln('Array Wrote: ' + ArrayToString(ABadColor));
            CloseFile(filenum);
          End;
      End;

    //End of Read/Write Arrays to File

    //Read/Write Array Color Sets

    Function ReadBadColors:Array of Integer;
      Begin
        Result:= ReadArrayFromFile(AppPath+'BadOldRoadColors.txt', ',');
      End;

    Function WriteBadColors(Addition: Integer):Boolean;//Addition is a number you want to add to the array
    Var
      OldStuff: Array of Integer;
      ALength: integer;
      Begin
        OldStuff:= ReadBadColors;
        ALength:= GetArrayLength(OldStuff);
        SetArrayLength(OldStuff, ALength + 1);
        OldStuff[ALength]:= Addition;//edit? //GetArrayLenght counts doesn't count 0
        Result:= WriteArrayToFile(AppPath+'BadOldRoadColors.txt', OldStuff);
      End;

    Function ReadGoodColors:Array of Integer;
      Begin
        Result:= ReadArrayFromFile(AppPath+'GoodOldRoadColors.txt', ',');
      End;

    Function WriteGoodColors(Addition: Integer):Boolean;//Addition is a number you want to add to the array
    Var
      OldStuff: Array of Integer;
      ALength: Integer;
      Begin
        OldStuff:= ReadGoodColors;
        ALength:= GetArrayLength(OldStuff);
        SetArrayLength(OldStuff, ALength + 1);
        OldStuff[ALength]:= Addition; //edit
        Result:= WriteArrayToFile(AppPath+'GoodOldRoadColors.txt', OldStuff);
      End;

    Function CheckGoodOldRoadColors:integer;
    var
      Filenum, c:Integer;
      OldColors:Array of Integer;
      Begin
        Filenum:= OpenFile(AppPath+'GoodOldRoadColors.txt', true);
        If(Filenum >= 0)Then
          Begin
            OldColors:= ReadArrayFromFile(AppPath+'GoodOldRoadColors.txt', ',');
            For c:=0 to (GetArrayLength(OldColors) - 1) Do
              Begin
                 If(CountColor(OldColors[c], MMX1, MMY1, MMX2, MMY2) > 0)Then
                   Begin
                     Writeln('Old Color Found: '+IntToStr(OldColors[c]));
                     Result:=OldColors[c];
                   End;
              End;
          CloseFile(Filenum);
          End;
      End;
    //End of read/write array color sets

    //Start of FindRoadColor Functions
    Function CreateCircleBitmap(X1, Y1, X2, Y2: Integer; DebugWindow:Boolean):Integer;//Leeched from masquerader
    var
      Debug,Temp: TCanvas;
      H, W, ScreenBmp, TempBmp: Integer;
    begin
      W := Max(X1, X2) - Min(X1, X2);
      H := Max(Y1, Y2) - Min(Y1, Y2);
      TempBmp := BitmapFromString(W, H, '');
      Temp := GetBitmapCanvas(TempBmp);
      ScreenBmp := BitmapFromString(W, H, '');

      FastDrawClear(TempBmp, -1);
      CopyClientToBitmap(ScreenBmp, X1, Y1, X2, Y2);

      CopyCanvas(GetBitmapCanvas(TempBmp), Temp, 0, 0, W, H, 0, 0, W, H);
      Temp.Ellipse(0, 0, W, H);
      CopyCanvas(Temp, GetBitmapCanvas(TempBmp), 0, 0, W, H, 0, 0, W, H);
      SetTransparentColor(TempBmp, 16777215);
      FastDrawTransparent(0, 0, TempBmp, ScreenBmp);
      If(DebugWindow)Then
        displaydebugimgwindow(w,h);
      debug:=getdebugcanvas;
      copycanvas(getbitmapcanvas(screenbmp),debug,0,0,w,h,0,0,w,h);
      SaveBitmap(ScreenBmp, AppPath+'CircleBitmap.bmp');
      Result:= LoadBitmap(AppPath+'CircleBitmap.bmp');
      FreeBitmap(TempBmp);
      FreeBitmap(ScreenBmp);
    end;

    Function RoadMaskBitMap:integer;
    var
      a, q, z, ClientHandle, stuff:integer;
    Begin
      ClientHandle:= GetClientWindowHandle;
      FindWindow('Debug Image');
      a := BitmapFromString(4, 3, 'z78DA7373A30E0000CEFE13B1');
      If(FindBitMapMaskTolerance(a, q, z, 20, 29, 124, 106, 1, 1))Then
      //If(FindBitmapInCircleTol(a, q, z, 73, 67, 67, 0))Then //Doesnt work?
        Begin
          stuff:= GetColor(q, z);
          If(stuff >= 0)Then
            Writeln('Coord: ('+IntToStr(q)+', '+IntToStr(z)+') - '+IntToStr(stuff));
          Result:=stuff;
        End;
      FreeBitMap(a);
      SetClientWindowHandle(ClientHandle);
    End;

    Function FindTheRoadColor(CheckOldColors: Boolean):Integer;
    Var TheColor, c, OldColor,
        a, CameraMoves,
        MiniMap, MaxRoadColor, MinRoadColor:integer;
        DebugCanvas: TCanvas;
        TheKey: Boolean;
    begin
      If(CheckOldColors)Then
        Begin
          OldColor:= CheckGoodOldRoadColors;
          If((OldColor > 0) and (Not(InArray(OldColor, ABadColor))))Then
            Result:= OldColor
        End;
      MaxRoadColor:= 8000000;//Change the road color limitations here
      MinRoadColor:= 4000000;// Default are 4000000 and 8000000
      DebugCanvas:= GetDebugCanvas;
      CameraMoves:= 0;
      a := BitmapFromString(4, 3, 'z78DA7373A30E0000CEFE13B1');
      MiniMap:= BitmapFromString(165, 161, '');
      TheColor:=0;
      If(Random(10) > Random(5))Then
        Begin
          TheKey:= true;
        End
      Else
        Begin
          TheKey:= false;
        End;
      MiniMap:= CreateCircleBitmap(575, 9, 720, 143, true);
      Repeat
      Writeln('Searching for road...');
      c:= 0;
      If((TheColor < MinRoadColor) or (TheColor > MaxRoadColor))Then
        Begin
          CameraMoves:= CameraMoves + 1;
          ActivateClient;
          If(TheKey)Then
            Begin
              KeyDown(VK_Right);
            End
          Else
            Begin
              KeyDown(VK_Left);
            End;
          Wait(400 + Random(1000));
          If(TheKey)Then
            Begin
            KeyUp(VK_Right);
            End
          Else
            Begin
              KeyUp(VK_Left);
            End;
        End;
        Repeat
          TheColor:= RoadMaskBitMap;
          MiniMap:= RotateBitmap(MiniMap, (5*(Pi/180)));
          SafeCopyCanvas(GetBitmapCanvas(MiniMap), DebugCanvas, 0, 0, 165, 161, 0, 0, 165, 161);//165,161
          c:= c + 1;
        Until((c > 72) or ((TheColor > MinRoadColor) and (TheColor < MaxRoadColor) and (Not (InArray(TheColor, ABadColor))) ) );
      Until(((TheColor > MinRoadColor) and (TheColor < MaxRoadColor) and (Not (InArray(TheColor, ABadColor)))) or (CameraMoves > 500));
    FreeBitMap(a);
    FreeBitMap(MiniMap);
    If(RememberRoadColors)Then
      WriteGoodColors(TheColor);
    Result:= TheColor;
    end;
    //End of RoadColors

    begin
    SetupSRL;
    RememberRoadColors:= true;//True to have it save road colors to files
    FindTheRoadColor(true);
    end.
    [I]Copied this from a script, and made sure

    One bug I've found....
    Code:
    [Runtime Error] : Exception: Access violation at address 7C918FEA in module 'ntdll.dll'. Write of address 00000098 in line 263 in script
    Not sure how to fix this. Happens rarely, might only happen when i haven't set the client. Any help is appreciated.

    Also has bugs with the writing/reading of arrays in it, but that can be edited out (I'll fix it once i find time).

    Also, it doesn't have a time limit to when its searching really... Well it does but if you want to edit that feel free.

  2. #2
    Join Date
    Mar 2006
    Posts
    3,051
    Mentioned
    1 Post(s)
    Quoted
    0 Post(s)

    Default

    I have a flawless roadcolor function ready.

    Good job, but that thing is a BEAST. I think mine is about 45 lines total and you don't need any files or arrays or anything.

  3. #3
    Join Date
    Oct 2006
    Posts
    119
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    You don't necessarly NEED files or arrays, but I choose to do what i can to make things work the best. You could easily do it without files and arrays.

  4. #4
    Join Date
    Sep 2006
    Posts
    5,219
    Mentioned
    4 Post(s)
    Quoted
    1 Post(s)

    Default

    Don't worry, I use arrays and repeats too much.

  5. #5
    Join Date
    Mar 2006
    Posts
    3,051
    Mentioned
    1 Post(s)
    Quoted
    0 Post(s)

    Default

    Quote Originally Posted by CamHart View Post
    You don't necessarly NEED files or arrays, but I choose to do what i can to make things work the best. You could easily do it without files and arrays.
    You did a good job. Fakawi did a similar thing himself, where you could save all the roadcolors to an array, and then when the roadcolor changed you could do a simple check against the array of known good colors.

    This makes sense given the fact that when the roadcolors change, they don't change by much, so you have a pretty good chance of getting a match.

    Anyway, I'll go ahead and post my function here and you can test it out.

    Code:
    function FindRoadColor:integer;  // By Tarajunky
    var red,green,blue:integer;
    var TestColor,a,b,GenericRoadColor:integer;
    begin
      GenericRoadColor:=6842479;
      Flag;
      a:=MMX1;
      b:=MMY1;
      repeat
        b:=b+1;
        repeat;
          a:=a+1;
          if FindColorTolerance(x,y,GenericRoadColor,a,b,MMX2,MMY2,80) then
          begin
            a:=x;
            b:=y;
            TestColor:=GetColor(x,y);
            red:=(TestColor mod 256);
            green:=((TestColor/256) mod 256);
            blue:=((TestColor/256) / 256);
            if Red-Green>=5 then if Red-Green<=10 then
            if Red-Blue>=5 then if Red-Blue<=10 then
            begin
              if GetColor(a+5,b+5)=TestColor then
              if GetColor(a+3,b+3)=TestColor then
              if GetColor(a,b+5)=TestColor then
              if GetColor(a+5,b)=TestColor then
              if GetColor(a,b+3)=TestColor then
              if GetColor(a+3,b)=TestColor then
              if GetColor(a+5,b+3)=TestColor then
              if GetColor(a+3,b+5)=TestColor then
              begin
                result:=TestColor;
                RoadColor:=TestColor;
                Writeln('RoadColor = '+IntToStr(TestColor));
                exit;
              end;
            end;
          end else a:=MMX2;
        until a>=MMX2;
        a:=MMX1;
      until b>=MMY2;
      Writeln('Could not find Road Color!');
      result:=0;
    end;

  6. #6
    Join Date
    Oct 2006
    Posts
    119
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    You just dominated all over me lol... Any idea on how long till the next SRL update?

  7. #7
    Join Date
    Oct 2006
    Posts
    119
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    It worked great, but then it had problems with some colors. One of them was 5131604. Would it work if you made the generic color an array then get some more "generic" road colors for it to look from?

  8. #8
    Join Date
    Mar 2006
    Posts
    3,051
    Mentioned
    1 Post(s)
    Quoted
    0 Post(s)

    Default

    The original search has a tolerance of 80, so it will pick up pretty much ANYTHING that is anywhere close to a road color. If it misses one, it is far more likely that it missed the exclusion criteria. Thanks for posting that color, it will help me refine the exclusion criteria.

    This does not work for Falador road colors, by the way. I wrote a different function to find those. They look grey, but they are really completely different. Can you tell me where you were testing when you found that color? Thanks!

  9. #9
    Join Date
    Oct 2006
    Posts
    119
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Fally lol. I suggest you check out barbarian village too (if you havn't already), those road colors are messy.

    Edit: I never went to barb village when testing yours, i just know it doesn't work with my method.

  10. #10
    Join Date
    Mar 2006
    Posts
    3,051
    Mentioned
    1 Post(s)
    Quoted
    0 Post(s)

    Default

    Yeah, I have a FindRoadColor (most everywhere), FindFallyRoadColor (Falador obviously) and FindDirtRoadColor (barb village and between Lumby and Draynor). That takes care of most of the roads in f2p.

    Also FindLadderColor, FindRockColor, FindWaterColor, and FindBridgeColor. They are all based on the RGB search strategy. These colors all remain the same once you pick them, even after logging out and back in, so they are very useful for navigation.

    I think they will all be added to the next SRL release.

  11. #11
    Join Date
    Oct 2006
    Posts
    412
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Quote Originally Posted by tarajunky View Post

    I think they will all be added to the next SRL release.
    YAY! <- That pretty much sums it up. Wouldn't mind learning how the RGB searching actually works though, but I can accept just a function that does it for me

  12. #12
    Join Date
    Sep 2006
    Posts
    5,219
    Mentioned
    4 Post(s)
    Quoted
    1 Post(s)

    Default

    Excerpt from understanding scar color code in SRL FAQ, become a member to read the rest (I'm sure you can, you've already got the bear).

    So I've been working on this color stuff today and here's what I came up with.

    I found as canada said, you can convert a color into hex and get a 6 character hex string. The first 2 characters are the hex value of the blue component, last 2 red, middle green. So I made a script to demonstrate this. The script converted SCAR color to hex, split into 3, and converted back to decimal, and did the reverse. I went into paint, made a custom color, took note of the red, green, and blue values, and used the scar color picker to get the color. Armed with this infomation I was able to convert from RGB to SCAR and check if it was correct. Then I noticed a problem, when any of the RGB values were low, the hex string was less than 6 characters. This is how hex values work:

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
    0 1 2 3 4 5 6 7 8 9 A B C D E F

    As you can see the first few are only 1 character, theres really a 0 before each one (0F etc) which would up hold the 6 character length, but these 0's get lost in the process. So the hex values were less than 6 chars, which meant that finding the red section gave an error, because strget was looking for the 6th, and even if there was no error, there others were inaccurate because you dont know if 5FFFB is 5 FF FB(yellow) or 5F FF B(green).

    So I found a new way to convert that doesn't use hex, in fact it does almost the same thing that hex does but skips over the hex part. Here are the functions I wrote:
    Code:
    type rgbcolor =record
    red,green,blue:integer;
    end;
     
    function color2rgb(color:integer):rgbcolor;
    begin
    result.red:=(color mod 256);
    result.green:=((color/256) mod 256);
    result.blue:=((color/256) / 256);
    end;
     
    function rgb2color(rgb:rgbcolor):integer;
    begin
    result:=(((rgb.blue*256)+rgb.green)*256)+rgb.red
    end;

    As you can see it works by using 256 because the rbg values are 0-255.


    Code:
    program New;
    type rgbcolor =record
    red,green,blue:integer;
    end; var
    color:integer;
    color2:rgbcolor;
    //---------Setup-------- const
    color=5200980;
     
     
     
    function color2rgb(color:integer):rgbcolor;
    begin
    result.red:=(color mod 256);
    result.green:=((color/256) mod 256);
    result.blue:=((color/256) / 256);
    end;
     
    function rgb2color(rgb:rgbcolor):integer;
    begin
    result:=(((rgb.blue*256)+rgb.green)*256)+rgb.red
    end;
     
     
    begin
    writeln('----------------');
    writeln(inttostr(color));
     writeln('  ');
     
    color2:=color2rgb(color)
    writeln(inttostr(color2.red));
    writeln(inttostr(color2.green));
    writeln(inttostr(color2.blue));
    end.
    I wrote this to try and find the pattern (or at least range) in the color changes of a certain rock after switching worlds. You put in a color, say 5200980 and it outputs
    ----------------
    5200980

    84
    92
    79

    I did this a few times to get a range for the grey rocks RGB values. I then put these ranges into the following script that uses Yakman's color displaying code. Notice how the colors are similiar when you change the RGB values in this script, but range when you change the SCAR value, like in Yakman's.
    Code:
    program New;
     type rgbcolor =record
    red,green,blue:integer;
    end; var
    color,x,y,z,{x1,y1,z1,x2,y2,z2,}square,buffer:integer;
    {waitforme:boolean; }
    color1:rgbcolor;
    //---------SETUP------------ const //should I wait for you to press ctrl //after showing the number of colors //before displaying them?
    waitformetotal=true;
    //Should I wait for you to press ctrl //before displaying each color?
    waitforme=false;
    x1=63;{red min}   x2=97;{red max}
    y1=75;{green min} y2=92;{green max}
    z1=61;{blue min}  z2=83;{blue max}
     
     
     
     
     
     
     
    function rgb2color(rgb:rgbcolor):integer;
    begin
    result:=(((rgb.blue*256)+rgb.green)*256)+rgb.red
    end;
     
    begin
     
    {waitforme:=false;
     
    x1:=63;        //red start
    y1:=75;        //green start
    z1:=61;        //blue start
    x2:=97;        //red end
    y2:=81;        //green end
    z2:=83;        //blue end
    }
    x:=x1-1;
    y:=y1-1;
    z:=z1-1;
    writeln('there will be '+inttostr((x2-x1)*(y2-y1)*(z2-z1))+' colors');
    if waitformetotal then begin repeat
    wait(10);
    until isfunctionkeydown(1);
    end;
    cleardebug;
    square:=bitmapfromstring(50,50,'');
     
    displaydebugimgwindow(100,100);
    buffer:=bitmapfromstring(100,100,'') ;
    repeat
    x:=x+1;
    y:=y1;
    repeat
    y:=y+1;
    z:=z1;
    repeat
    z:=z+1;
    //writeln(inttostr(x)+'  '+inttostr(y)+'  '+inttostr(z));
    color1.red:=x;
    color1.green:=y;
    color1.blue:=z;
    color:=rgb2color(color1);
    writeln(inttostr(color)+'  '+inttostr(x)+'  '+inttostr(y)+'  '+inttostr(z));
    fastdrawclear(square,color)
    fastdrawclear(buffer,0)
    fastdrawtransparent(25,25,square,buffer)
    safedrawbitmap(buffer,getdebugcanvas,0,0)
    status('Color = '+inttostr(color)) if waitforme then begin repeat
    wait(10);
    until isfunctionkeydown(1);
    end; until z=z2;
    until y=y2;
    until x=x2;
    end.
    So, if you want to find similar colors, you need to change the RGB values.

    So far, my experiments with finding a pattern in the color of a certain rock (to see which rock go to srl member scripts>fighters> WT Fakawi's Guard fighter> look at his zoomed in screen shot) show that there is no pattern in the SCAR color nor the RGB colors (that I can see with my small sample size) but there is a range. It took the lowest and highest RGB values, found the RGB ranges, multiplied those 3, and found that the range of greys so far is over 12 thousand, and that's from only 4 colors. The range of SCAR colors for these 4 is about 1.2mil, and includes all sorts of colors.

    I started this because I wanted to make a procedure to auto color the color of the rock, and shape recognition didn't work because it changed and there were similiar shapes, neither did find a color that appeared a certain number (or within a range) of times. So I thought what I knew the range of colors it could be, and have the script go through them til it found 1. However, that's looking less likely with 12 thousand creeping up. It's interesting to investigate anyway though.

    Congrats for reading this far.

  13. #13
    Join Date
    Oct 2006
    Posts
    119
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Boreas - I'll have to read through that tomorrow... its kinda late and i needa hit the hay. Looks interesting though. Looks like it explains RGB coloring n crap very well...

    tarajunky - How long is inbetween each SRL release normally? Until all the known bugs are fixed or what? After a given period of time? Once Devs feel like typing the new release up?

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Finding colors
    By cycrosism in forum OSR Help
    Replies: 8
    Last Post: 11-05-2008, 09:42 AM
  2. Need help with finding goblin colors!!!
    By synchyas in forum OSR Help
    Replies: 5
    Last Post: 04-05-2008, 04:15 PM
  3. Finding Multiple Tree Colors
    By tigerskall in forum OSR Help
    Replies: 11
    Last Post: 11-18-2007, 07:04 AM
  4. Finding monster colors...
    By supersayian2224 in forum OSR Help
    Replies: 6
    Last Post: 11-17-2007, 08:58 PM
  5. Replies: 8
    Last Post: 06-30-2007, 01:15 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •