Results 1 to 22 of 22

Thread: Where to get CTWB.simba

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

    Default Where to get CTWB.simba

    Brief Overview
    CTWB is a set of functions that generate screenshots of the minimap to be uploaded to a community collection of bitmaps.

    Users: how to get CTWB
    Save this as CTWB.simba file in your includes folder. If would like to contribute, see next section.
    Simba Code:
    {CTWB}

    const
      CTWBOn = false; //Make true to help out CTWB
      CTWBPath = AppPath + 'CTWB\';

    //lordsaturn
    function CollectDots: TPointArray;
    var
      SearchColors: T2DIntegerArray;
      TPA, TotalTPA: TPointArray;
      i, j: Integer;
    begin
      SetLength(SearchColors, 3);
      SearchColors[0] := [3553023,  789758,  2105598,  395004, 237, 206, 65536, 217, 188];  //red
      SearchColors[1] := [16711422, 15527148, 13816530, 14869218, 12961221]; //white
      SearchColors[2] := [1179390, 195836, 62965, 56797, 60909, 52428]; //yellow
      for i := 0 to 2 do
      begin
        for j := 0 to High(SearchColors[i]) do
          if FindColors(TPA, SearchColors[i][j], MMX1, MMY1, MMX2, MMY2) then
            TotalTPA := CombineTPA(TotalTPA, TPA);
      end;

      Result := TotalTPA;
    end;

    //lordsaturn
    function CollectSymbols: TPointArray;
    var
      SearchTPA, InsideTPA, OutlineTPA: TPointArray;
      ATPA, SymbolATPA, PossiblesATPA, SearchATPA: T2DPointArray;
      i, j, k, Hi, Hi2, Hi3, lowX, highX, x, y, L, L2, highCount, counter: Integer;
      mid, aPt: TPoint;
      SearchBox: TBox;
      BadColors: TIntegerArray;
    begin
      //tpa of symbol outline, length = 40, midpoint = 7,7, bounds 14x14
      SearchTPA := [Point(5, 0), Point(6, 0), Point(7, 0), Point(8, 0), Point(9, 0),
               {5}  Point(3, 1), Point(4, 1), Point(10, 1), Point(11, 1),
               {9}  Point(2, 2), Point(12, 2),
               {11} Point(1, 3), Point(13, 3),
               {13} Point(1, 4), Point(13, 4),
               {15} Point(0, 5), Point(14, 5),
               {17} Point(0, 6), Point(14, 6),
               {19} Point(0, 7), Point(14, 7),
               {21} Point(0, 8), Point(14, 8),
               {23} Point(0, 9), Point(14, 9),
               {25} Point(1, 10), Point(13, 10),
               {27} Point(1, 11), Point(13, 11),
               {29} Point(2, 12), Point(12, 12),
               {31} Point(3, 13), Point(4, 13), Point(10, 13), Point(11, 13),
               {35} Point(5, 14), Point(6, 14), Point(7, 14), Point(8, 14), Point(9, 14)];
      BadColors := [789758, 217, 188, 206, 16711422, 14869218, 12961221, 13816530, 195836, 56797, 52428, 52428];
      FindColors(InsideTPA, 12632256, MMX1, MMY1, MMX2, MMY2);
      ATPA := TPAtoATPAEx(InsideTPA, 15, 15);
      InsideTPA := []; //run faster
      Hi := High(ATPA);
      Hi3 := 39; //High(SearchTPA);
      SetLength(SymbolATPA, Hi+1);
      for i := 0 to Hi do
      begin
        //find top left, bottom right
        SearchBox := GetTPABounds(ATPA[i]);
        //get symbol outline
        FindColors(OutlineTPA, 65536, SearchBox.x1-1, SearchBox.y1-1, SearchBox.x2+1, SearchBox.y2+1);

        //build midpoint possibilities
        Hi2 := High(OutlineTPA);
        L2 := 0;
        SetLength(PossiblesATPA, Hi2+1);
        for j := 0 to Hi2 do
        begin
          if not (InIntArray(BadColors, GetColor(OutlineTPA[j].x, OutlineTPA[j].y-1))) then
          begin
            SetLength(PossiblesATPA[L2], Hi3+1);
            for k := 0 to Hi3 do
            begin
              PossiblesATPA[L2][k].x := SearchTPA[k].x + OutlineTPA[j].x - 7;
              PossiblesATPA[L2][k].y := SearchTPA[k].y + OutlineTPA[j].y - 7;
            end;
            Inc(L2);
          end;
        end;
        OutlineTPA := []; //run faster
        SetLength(PossiblesATPA, L2);

        //find common midpoint
        Hi2 := L2-1; //because it changed
        highCount := 0;
        for k := 0 to Hi3 do
        begin
          aPt := PossiblesATPA[0][k];
          counter := 0;
          for j := 1 to Hi2 do
            if PointInTPA(aPt, PossiblesATPA[j]) then
              Inc(counter);
          if counter > highCount then
          begin
            mid := aPt;
            highCount := counter;
          end;
        end;
        PossiblesATPA := []; //run faster

        //filler up
        SetLength(SymbolATPA[i], 177);
        if L = 0 then
          SearchATPA := TPAtoATPAEx(SearchTPA, 15, 0); //go faster
        L := 0;
        Hi2 := 14; //High(SearchATPA);
        for j := 0 to Hi2 do
        begin
          lowX := mid.x + SearchATPA[j][0].x - 7;
          highX := mid.x + SearchATPA[j][High(SearchATPA[j])].x - 7;
          y := mid.y + SearchATPA[j][0].y - 7;
          for x := lowX to highX do
          begin
            SymbolATPA[i][L] := Point(x, y);
            Inc(L);
          end;
        end;

      end;
      Result := MergeATPA(SymbolATPA);
    end;

    //lordsaturn
    function StuffOnMM: TPointArray;
    var
      timer: Integer;
    begin
      Freeze;
      timer := GetSystemTime;
      Result := CombineTPA(CollectDots, CollectSymbols);
      //Writeln('StuffOnMM took '+tostr(GetSystemTime-timer)+' msec.');
      Unfreeze;
    end;

    procedure CTWBMakeClean(MyTile: TPoint);
    var
      CAB: TBox; //CurrentAreaBox
      Chunks, Corners, Corners2, CopiedChunks, DotsTPA: TPointArray;
      il, jl, t,i, i2, counter, MainBitmap, ChunkBitmap, FragmentBitmap, NewTarget, OldTarget: integer;
      TmpString: String;
      Skip: Boolean;
      ChunksTiles, FragmentsTiles, FragmentsPixels, FragmentsPos: TBoxArray;
    begin
      t := getsystemtime;
      //Get tile bounds of CurrentAreaBox
      CAB := IntToBox(MyTile.x - 12, MyTile.y + 12, MyTile.x + 12, MyTile.y - 12);//Make sure this does not normalize

      //CurrentAreaBox is spread over 1, 2, or 4 chunks, so these arrays are set to 4
      //In these arrays, [0] corresponds to the chunk that the top left corner of CAB is in,
      //[1] is top right, [2] is bottom left, [3] is bottom right. This defined in Corners
      Corners := [Point(CAB.x1, CAB.y1), Point(CAB.x2, CAB.y1), Point(CAB.x1, CAB.y2), Point(CAB.x2, CAB.y2)];
      SetArrayLength(Chunks, 4);
      SetArrayLength(ChunksTiles, 4);
      SetArrayLength(FragmentsTiles, 4);
      SetArrayLength(FragmentsPixels, 4);
      SetArrayLength(FragmentsPos, 4);

      //Using these conventions when working with tiles and pixels
      //Pixels have 0,0 in the top left
      //Tiles have 0,0 in the bottom left
      //Chunks have 0,0 in the bottom left (the are 100x100 pixels, but they deliberately start and end on tiles so that no tile
      //is spread over multiple chunks (25x25 tiles), therefore, they follow the tile convention)
      //X1,Y1 is always top left, X2,Y2 is always bottom right
      //For pixels, Y1 is lower than Y2. For tiles and chunks, Y2 is lower than Y1

      for i:= 0 to 3 do
      begin
        //Find the Chunk that the corresponding corner of CAB is in
        Chunks[i] := Point(((Corners[i].x-2044) div 25),((Corners[i].y-861) div 25));
        //Find the tile bounds of that chunk
        ChunksTiles[i] := IntToBox(2044+Chunks[i].x*25, 885+Chunks[i].y*25, 2068+Chunks[i].x*25, 861+Chunks[i].y*25);//No normalize
        //These are the opposite corners of Corners
        Corners2 := [Point(ChunksTiles[i].x2, ChunksTiles[i].y2), Point(ChunksTiles[i].x1, ChunksTiles[i].y2), Point(ChunksTiles
          [i].x2, ChunksTiles[i].y1), Point(ChunksTiles[i].x1, ChunksTiles[i].y1)]; //yes normalize
        //Find the intersection of the corresponding Corner of CAB and the opposite corner of the Chunk
        //that contains the Corner of CAB. Also make X1 lower than X2, and Y1 higher than Y2 (tiles start from the bottom left)
        FragmentsTiles[i] := IntToBox(Min(Corners[i].x,Corners2[i].x), Max(Corners[i].y,Corners2[i].y), Max(Corners[i].x,Corners2
          [i].x), Min(Corners[i].y, Corners2[i].y));
        //Find the pixel bounds (on MainBitmap) of thoses tiles
        FragmentsPixels[i] := IntToBox(14+(FragmentsTiles[i].x1-(MyTile.x-12))*4, 14+((MyTile.y+12)-FragmentsTiles[i].y1)*4, 112-
          ((MyTile.x+12)-FragmentsTiles[i].x2)*4, 112-(FragmentsTiles[i].y2-(MyTile.y-12))*4);
        //Find the pixel box in Chunk that fragment will be copied to
        FragmentsPos[i] := IntToBox((FragmentsTiles[i].x1-ChunksTiles[i].x1)*4, (ChunksTiles[i].y1-FragmentsTiles[i].y1)*4,
          (FragmentsTiles[i].x1-ChunksTiles[i].x1)*4 + (FragmentsPixels[i].x2 - FragmentsPixels[i].x1),
          (ChunksTiles[i].y1-FragmentsTiles[i].y1)*4 + (FragmentsPixels[i].y2 - FragmentsPixels[i].y1));
      end;

      DotsTPA :=StuffOnMM;

      MainBitmap := BitmapFromClient(564, 21, 691, 148);
      OldTarget := GetImageTarget;
      SetTargetBitmap(MainBitmap);
      NewTarget := GetImageTarget;

      for i := 0 to High(DotsTPA) do
      begin
        il:=DotsTPA[i].x-564;
        jl:=DotsTPA[i].y-21;
        if (il > -1) and (il < 128) and (jl > -1) and (jl < 128) then
          FastSetPixel(MainBitmap, il, jl, 0);
      end;

      for il:= mmcx-1 to mmcx+1 do
      for jl:= mmcy-1 to mmcy +1 do
        FastSetPixel(MainBitmap, il-564, jl-21, 0);

      SetLength(CopiedChunks,1);
      Counter := 0;
      CopiedChunks[0] := Point(-1,-1);
      for i:= 0 to 3 do
      begin
        Skip := false;
        TmpString := 'CleanChunk'+ Padz(IntToStr(Chunks[i].x),2)+'-'+Padz(IntToStr(Chunks[i].y),2);
        for i2 := 0 to High(CopiedChunks) do
        begin
          if ReadINI('CleanChunksDone', TmpString, CTWBPath + 'CTWBSVN\SVNCleanChunks.INI')='DONE' then
          begin
            Skip := true;
            break;
          end;
          if ReadINI('CleanChunksDone', TmpString, CTWBPath + 'UserCleanChunks.INI')='DONE' then
          begin
            Skip := true;
            break;
          end;
          if (Chunks[i].x = CopiedChunks[i2].x) and (Chunks[i].y = CopiedChunks[i2].y) then
          begin
            Skip := true;
            break;
          end;
        end;
        if not Skip then
        begin
          SetArrayLength(CopiedChunks, counter+1);
          CopiedChunks[Counter] := Chunks[i];
          Inc(Counter);
          TmpString := CTWBPath + TmpString +'.bmp';
          if FileExists(TmpString) then
            ChunkBitmap := LoadBitmap(TmpString)
          else
            ChunkBitmap := CreateBitmap(100,100);
          FragmentBitmap := BitmapFromClient(FragmentsPixels[i].x1, FragmentsPixels[i].y1,
                                             FragmentsPixels[i].x2, FragmentsPixels[i].y2);
          SetTransparentColor(FragmentBitmap, 0);
          FastDrawTransparent(FragmentsPos[i].x1, FragmentsPos[i].y1, FragmentBitmap, ChunkBitmap);
          FreeBitmap(FragmentBitmap);
          SaveBitmap(ChunkBitmap, TmpString);

          FreeBitmap(ChunkBitmap);
        end;
      end;

      SetImageTarget(OldTarget);
      FreeTarget(NewTarget);
      FreeBitmap(MainBitmap);
    end;




    {*******************************************************************************
    function CTWBGetMyPos: TTile;
    By: BenLand100
    Description: Returns the global tile position of your player.
    *******************************************************************************}

    function CTWBGetMyPos: TPoint;
    var
      me: Integer;
    begin
      me := SmartGetFieldObject(0, hook_static_MyPlayer);
      Result.x := SmartGetFieldInt(0, hook_static_BaseX) + SmartGetFieldInt(me, hook_animable_PixelX) / 512;
      Result.y := SmartGetFieldInt(0, hook_static_BaseY) + SmartGetFieldInt(me, hook_animable_PixelY) / 512;
      SmartFreeObject(me);
      if CTWBOn then
        if R_MakeCompass('n') then
          if not R_FlagExists then
            CTWBMakeClean(Result);
    end;

    {*******************************************************************************
    function TileToMM(tile: TTile): TPoint;
    By: BenLand100
    Description: Converts the global tile position to a screen location on the
                 minimap, taking map rotation into account.
    *******************************************************************************}

    function CTWBTileToMM(tile: TTile): TPoint;
    var
      angle, x, y: extended;
      temp: TPoint;
    begin
       angle:= -GetMinimapAngleRad;
       temp := CTWBGetMyPos();
       x:= (tile.x - temp.x) * 4 - 2;
       y:= (temp.y - tile.y) * 4 - 2;
       result.x:= round(x*cos(angle) + y*sin(angle)) + 628;
       result.y:= round(y*cos(angle) - x*sin(angle)) + 87;
    end;

    {*******************************************************************************
    function TileOnMM(Tile: TTile): boolean;
    By: Drags111
    Description: Checks if the Tile is on the MM.
    *******************************************************************************}

    function CTWBTileOnMM(Tile: TTile): boolean;
    var
      P: TPoint;
    begin
      P := CTWBTileToMM(Tile);
      Result := rs_OnMinimap(P.x, P.y);
    end;

    {*******************************************************************************
    Function WalkToTile(Tile: TPoint; Randomness, FlagD: Integer): Boolean;
    By: Wizzup, TheGuyWhoGotOn, and Drags111
    Description: Walks to the tile using minimap.
    *******************************************************************************}

    function CTWBWalkToTile(TheTile: TTile; Randomness, FlagD: Integer): Boolean;
    var
       wTile: TPoint;
       t: Integer;
    begin
      Result := False;
      TheTile := RandomizeTile(TheTile, Randomness, Randomness);
      wTile := CTWBTileToMM(TheTile);
      if not rs_OnMiniMap(wTile.X, wTile.Y) then
        Exit;
      Mouse(wTile.x, wTile.y, 1, 1, true);
      Wait(RandomRange(80, 100));
      t := getsystemtime;
      if (FlagD = 0)then
      begin
        R_Flag;
      end else
        R_FFlag(FlagD);
      Result := (GetSystemTime - t) < 60000;
    end;

    {*******************************************************************************
    function WalkPath(Tiles: TTileArray): boolean;
    By: Drags111
    Description: Walks the tile path. Looks like an ugly function, but it works
                 Beautifully.
    *******************************************************************************}

    function CTWBWalkPath(Tiles: TTileArray): boolean;
    var
      i, t, attempts: integer;
      P: TPoint;
      next: boolean;
    label
      ProcStart;
    begin
      Inc(attempts);
      ProcStart:
      i := -1;
      Result := false;
      if(DistanceFrom(Tiles[High(Tiles)]) < 6)then
      begin
        Result := true;
        Exit;
      end;

      //Getting the starting index.
      for i := High(Tiles) downto 0 do
        if(CTWBTileOnMM(Tiles[i]))then
        begin
          i := i;
          Break;
        end;
      if(i = -1)then
        Exit;

      //Walk remainder of the path.
      for i := i to High(Tiles) do
      begin
        next := false;
        if not(TileOnMM(Tiles[i]))then
        begin
          Writeln('Tile not on MM.');
          break;
        end;
        P := CTWBTileToMM(Tiles[i]);
        Mouse(P.x, P.y, 1, 1, true);
        while(DistanceFromFlag <> 0)do
        begin
          if not WaitToMove(3000)then
          begin
            MarkTime(t);
            while(TimeFromMark(t) < 7000)do
              if(WaitToMove(1000))then break;
            if(TimeFromMark(t) >= 7000)then
            begin
              Writeln('***Didn''t move for 10 seconds. Exiting***');
              next := false;
              break;
            end;
          end;
          if(i < High(Tiles))then
          begin
            if(TileOnMM(Tiles[i+1]))then
            begin
              next := true;
              break;
            end;
          end;
        end;
        if(i < High(Tiles))then
          if(TileOnMM(Tiles[i+1]))then
            next := true;
        if not next then
          break;
      end;
      Result := DistanceFrom(Tiles[High(Tiles)]) <= 5;
      if not Result then
      begin
        if(attempts > 7)then
        begin
          Writeln('Failed more than ten attempts.');
          Exit;
        end;
        While(GetSpeed > 0)do wait(100+Random(100));
        goto ProcStart;
      end;
      While(GetSpeed > 0)do wait(100+Random(100));
    end;

    {*******************************************************************************
    Function WebWalk(T: TTile): Boolean;
    By: JuKKa
    Description: Walks blindly using WindPath!
    *******************************************************************************}

    Function CTWBr_WebWalk(T: TTile): Boolean;
    Var
      I: Integer;
      M, P: TPoint;
      CTRLPoints: TPointArray;
    Begin
      P := TileToPoint(T);
      Repeat
        M := GetMyPos;
        CtrlPoints := r_WindPath(M.x, M.y, P.X, P.Y, 5.0, 2.5, 0.0, 0.0, 4.5, 2.5);
        For I:= High(CtrlPoints) DownTo 0 Do
          if CTWBWalkToTile(Tile(CtrlPoints[i].x, CtrlPoints[i].y),0, 10) Then
          Begin
            Result := I = High(CtrlPoints);
            Break;
          End;
      Until( Result );
    End;

    Users: how to enable CTWB
    In CTWB.simba change 'CTWB = false;' to 'CTWB = true;'. You can also change CTWBPath if you would like. Now that CTWB is enabled, when you are running scripts that are CTWB Ready (they will have {$i CTWB.smba} at the top), bitmaps will be generated and saved to that path. Thanks for contributing!

    Users: how to upload bitmaps
    Once a week/month, or whenever you want, run this script.
    <need to write a script that:
    Downloads latest version of CommunityCompletedChunks.INI and StaticNPCTiles.INI,
    SetPixel static NPC tiles yellow
    Finds chunks with no remaining black, adds to UserCompletedChunks.INI, and uploads them to ???>

    Scripters: how to make a script CTWB Ready
    If your script uses reflection for walking, you can make it CTWB Ready (users still have to actually turn it on for it to do anything, see above). Add {$i CTWB.simba} after you include reflection. Wherever you call GetMyPos/WalkToTile/WalkPath, if making the compass north and an extra 250-1000ms won't hurt GetMyPos, replace them with CTWBGetMyPos/CTWBWalkToTile/CTWBWalkPath. On your script thread or in the instructions, link to this page so that users can get CTWB.simba. Thanks for contributing!

    Extra information
    CTWBGetMyPos takes screenshots of the minimap, and saves them to bitmaps. These bitmaps are named according to your current tile (hence the need for reflection). Dots and symbols are not included in these bitmaps, they are replaced with black. On the following runs, pixels that were black are updated (so the dots and symbols automagically disappear).
    Last edited by Boreas; 12-30-2010 at 02:59 PM.

  2. #2
    Join Date
    Feb 2009
    Location
    Irvine, CA
    Posts
    2,873
    Mentioned
    8 Post(s)
    Quoted
    138 Post(s)

    Default

    question: what does CTWB stand for?

  3. #3
    Join Date
    Feb 2008
    Posts
    748
    Mentioned
    1 Post(s)
    Quoted
    14 Post(s)

    Default

    Assuming a reflection hook is incorrect and you get some funny tiles for the screenshots, there is a way to revert right?

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

    Default

    TomTuff: Color Tile Walking Base

    pyroryan: nope, each bitmap is overwritten each time. So hopefully if the hooks are wrong they will be really wrong, so that it will be somewhere in the ocean or something.

  5. #5
    Join Date
    Sep 2006
    Location
    Canada
    Posts
    1,124
    Mentioned
    0 Post(s)
    Quoted
    5 Post(s)

    Default

    Is this to make a map so we can make easy paths? If so maybe 10 of us should just load it up, and walk around Runescape.

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

    Default

    The PathMaker tool is for making paths. This will create a map that people can apply autocoloring type functions to, resulting in a color version of GetMyPos to walk those paths. So yea, we need lots of people to run reflection scripts walking around with this enabled.

  7. #7
    Join Date
    Dec 2006
    Location
    Sweden
    Posts
    10,812
    Mentioned
    3 Post(s)
    Quoted
    16 Post(s)

    Default

    It could/should be ported to work with the MainScreen too, i.e. object finding?

    How would the community backend work? Could probably use gd+perl for a simple database of the minimap images.

    Pretty interesting.


    Send SMS messages using Simba
    Please do not send me a PM asking for help; I will not be able to help you! Post in a relevant thread or make your own! And always remember to search first!

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

    Default

    Quote Originally Posted by Harry View Post
    It could/should be ported to work with the MainScreen too, i.e. object finding?.
    You mean like knowing that a tree is at TileA and using a TileToMS that uses color_GetMyPos?

    Quote Originally Posted by Harry View Post
    How would the community backend work? Could probably use gd+perl for a simple database of the minimap images.

    Pretty interesting.
    What do you mean? I was just thinking of making an SVN.

  9. #9
    Join Date
    Nov 2007
    Location
    46696E6C616E64
    Posts
    3,069
    Mentioned
    44 Post(s)
    Quoted
    302 Post(s)

    Default

    I have PHP functions that can convert BitmapString from Simba to bitmap image on the server-side. They use GD ofcourse, I can find them and post here if you like?
    There used to be something meaningful here.

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

    Default

    Ah so instead of uploading bmp files, doing an HTTPPost thingy with the string?

  11. #11
    Join Date
    Dec 2006
    Location
    Sweden
    Posts
    10,812
    Mentioned
    3 Post(s)
    Quoted
    16 Post(s)

    Default

    Quote Originally Posted by Boreas View Post
    You mean like knowing that a tree is at TileA and using a TileToMS that uses color_GetMyPos?



    What do you mean? I was just thinking of making an SVN.
    1) Yeah sure.

    2) Well I don't really know what its intended uses are for, but "to be uploaded to a community collection of bitmaps" - I assumed there would be some online backend that would collect automatically all the bitmaps?


    Send SMS messages using Simba
    Please do not send me a PM asking for help; I will not be able to help you! Post in a relevant thread or make your own! And always remember to search first!

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

    Default

    I was just gonna make a script that puts the completed bmps into another folder and says 'please zip it up and upload, then post the link', but if you guys know a way to send from a script to a webserver automatically that would be awesome.

  13. #13
    Join Date
    Jan 2007
    Posts
    8,876
    Mentioned
    123 Post(s)
    Quoted
    327 Post(s)

    Default

    Just use some simple php functions

    @Boreas: Check the other thread

  14. #14
    Join Date
    Mar 2006
    Location
    Behind you
    Posts
    3,193
    Mentioned
    61 Post(s)
    Quoted
    63 Post(s)

    Default

    Stickied cause I love the Idea. New users this is probably a good start to color based world walker of the future.

    ~BraK

    "Sometimes User's don't need the Answer spelled out with Code. Sometimes all they need is guidance and explanation of the logic to get where they are going."

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

    Default

    Thanks for that Brak.

    Harry/Frement/Zyt3x: I don't know PHP/Perl/GD, but according to phpinfo() my basic shared hosting plan comes with "GD Version: bundled (2.0.34 compatible)" which doesn't support BMPs, but it comes with "ImageMagick version: ImageMagick 6.6.0-2" which does. Do you have a way to send BMPs from Simba to a webserver?

  16. #16
    Join Date
    Nov 2007
    Location
    46696E6C616E64
    Posts
    3,069
    Mentioned
    44 Post(s)
    Quoted
    302 Post(s)

    Default

    Heres something I had in mind:
    PHP Code:
    <?php

    function gzuncompress_crc32($data) {
        
    $f tempnam('/tmp''gz_fix');
        
    file_put_contents($f"\x1f\x8b\x08\x00\x00\x00\x00\x00" $data);
        return 
    file_get_contents('compress.zlib://' $f);
    }

    function 
    BMPStringToByteArray($string$width$height) {
        if (
    substr($string01) == "m") {
            
    $data_array str_split(gzuncompress_crc32(base64_decode(substr($string1strlen($string) - 1))));
            
    $o 1$mode R$result = array();
            
    $result["W"] = $width;
            
    $result["H"] = $height;
            foreach (
    $data_array as $bit) {
                switch (
    $mode) {
                    case 
    R$r $bit$mode G; break;
                    case 
    G$g $bit$mode B; break;
                    case 
    B$b $bit$mode R$result[$o] = array(ord($r), ord($g), ord($b)); $o++; break;
                }
            }
            return 
    $result;
        } else {
            return 
    false;
        }
    }

    function 
    ByteArrayToPNG($bytearray$bmp_name) {
        
    $width $bytearray["W"];
        
    $height $bytearray["H"];
        unset(
    $bytearray["W"], $bytearray["H"]);
        
    $img imagecreatetruecolor($width$height);
        
    $sx 0;
        
    $sy 0;
        foreach (
    $bytearray as $bits) {
            
    $color imagecolorallocate($img$bits[0], $bits[1], $bits[2]);
            
    imagesetpixel($img$sx$sy$color);
            
    $sx++;
            if (
    $sx == $width) {
                
    $sy++;
                
    $sx 0;
            }
        }
        
    imagepng($img$bmp_name);
        
    imagedestroy($img);
    }

    $bitmap["name"] = $_POST["bitmap_name"];
    $bitmap["data"] = $_POST["bitmap_data"];
    $bitmap["width"] = $_POST["bitmap_width"];
    $bitmap["height"] = $_POST["bitmap_height"];

    $bitmap_path "bitmaps/";

    $bytearray BMPStringToByteArray($bitmap["data"], $bitmap["width"], $bitmap["height"]);

    ByteArrayToPNG($bytearray$bitmap_path.$bitmap["name"].".png");

    ?>
    There used to be something meaningful here.

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

    Default

    Ah cool. What would be the Simba side for that?

    Also, would this convert it to a bmp without losing anything?

    PHP Code:
    try
    {
            
    /*** the image file ***/
            
    $image $bitmap_path.$bitmap["name"].".png";

            
    /*** a new imagick object ***/
            
    $im = new Imagick();

            
    /*** ping the image ***/
            
    $im->pingImage($image);

            
    /*** read the image into the object ***/
            
    $im->readImage$image );

            
    /**** convert to png ***/
            
    $im->setImageFormat"bmp" );

            
    /*** write image to disk ***/
            
    $im->writeImage'$bitmap_path.$bitmap["name"].".bmp"' );

            echo 
    'Image Converted';
    }
    catch(
    Exception $e)
    {
            echo 
    $e->getMessage();


  18. #18
    Join Date
    Nov 2007
    Location
    46696E6C616E64
    Posts
    3,069
    Mentioned
    44 Post(s)
    Quoted
    302 Post(s)

    Default

    Something like this:
    Simba Code:
    program new;

    const ServerURL = 'http://www.frement.net/srl/ctwb/submit.php';

    function SendBitmap(Bmp: Integer; Name: String): Boolean;
    var Client, W, H: Integer;
        Return: String;
    begin
      Result := False;
      Client := InitializeHTTPClient(False);
      ClearPostData(Client);
      GetBitmapSize(Bmp, W, H);
      AddPostVariable(Client, 'bitmap_name', Name);
      AddPostVariable(Client, 'bitmap_data', CreateBitmapString(Bmp));
      AddPostVariable(Client, 'bitmap_width', ToStr(W));
      AddPostVariable(Client, 'bitmap_height', ToStr(H));
      Return := PostHTTPPageEx(Client, ServerURL);
      if (Pos('Success', Return) <> 0) then
        Result := True;
    end;

    begin
      if (SendBitmap(BitmapFromClient(0, 0, 50, 50), 'TestBitmap')) then
        Writeln('Bitmap uploaded!');
    end.
    There used to be something meaningful here.

  19. #19
    Join Date
    Feb 2007
    Location
    Alberta, Canada
    Posts
    4,615
    Mentioned
    50 Post(s)
    Quoted
    429 Post(s)

    Default

    Has there been any development to the server side for this? If the Simba side works I'd be willing to make a script which simply walks around like crazy all over RS and then we could encourage a lot of people to use it, etc = win.

    Scripts: Edgeville Chop & Bank, GE Merchanting Aid
    Tutorials: How to Dominate the Grand Exchange

    Quote Originally Posted by YoHoJo View Post
    I like hentai.

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

    Default

    When I get a chance I will implement Frement's code into the uploader. Also needed for the uploader is a list of tiles of static NPCs.

    However using CTWB with reflection scripts or an all over RS walker to collect bitmaps works now without the uploader script or server side, which would be win

  21. #21
    Join Date
    Feb 2007
    Location
    Alberta, Canada
    Posts
    4,615
    Mentioned
    50 Post(s)
    Quoted
    429 Post(s)

    Default

    Quote Originally Posted by Boreas View Post
    When I get a chance I will implement Frement's code into the uploader. Also needed for the uploader is a list of tiles of static NPCs.

    However using CTWB with reflection scripts or an all over RS walker to collect bitmaps works now without the uploader script or server side, which would be win
    Yes, it would be more win if it auto updated/uploaded though

    Scripts: Edgeville Chop & Bank, GE Merchanting Aid
    Tutorials: How to Dominate the Grand Exchange

    Quote Originally Posted by YoHoJo View Post
    I like hentai.

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

    Default

    The thing is a bitmap isn't ready to be uploaded on the first pass. It takes several passes to be complete, so checking whether it is complete, and uploading it if it is, is done once a day/week or whenever the user wants via a separate uploader script. Also, the uploader script will color in yellow dots for static NPCs (which stay black normally and never trigger the IsComplete check), and I don't want to add too much real time processing to GetMyPos.

Thread Information

Users Browsing this Thread

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

Posting Permissions

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