euphemism

Object DTM Include

Dec 13th, 2011
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 66.71 KB | None | 0 0
  1. {$IFDEF SMART}
  2. {$IFNDEF PAINT}
  3. {$DEFINE PAINT}
  4. {$i SRL\SRL\MISC\Paintsmart.scar}
  5. {$ENDIF}
  6. {$ENDIF}
  7. {-------------------------------------------------------------------------------
  8.  
  9.                              Object DTM Include
  10.                                 By: euphemism
  11.  
  12. -This include contains procedures and functions to use and create Object DTMs.
  13.  
  14. -TO DO: Implement more generating features to ease creation of Object DTMs.
  15.  
  16. -Version 8: bug fix in finding function.  Overall speed improvements.  Added
  17.         'Multi-Object DTMs' which allow for multiple Object DTMs to be
  18.         defined in a string array, to use in the same way as single
  19.         Object DTMs, but if one fails, the code will try the next.  Path-
  20.         walking function.  All of these additions are untested.  Will
  21.         try to get testing done soon.  So this update is mostly for
  22.         the bug fix/speed improvement.  But feel free to try the new stuff.
  23.         Haven't added comments, code is messy, real sorry about all of
  24.         this.  Will be resolved in Rev 8.1.
  25.  
  26.         Added:
  27.         ObjDTM_MultiWalk;
  28.         ObjDTM_InMultiArea;
  29.         ObjDTM_PathWalk;
  30.         ObjDTM_InAreaEx;
  31.  
  32. -Version 7.8: Changed the single use of SplitTPAEx to SplitTPAExWrap, as
  33.         I heard that it can cause memory leaks?
  34.  
  35. -Version 7.7: Changed a few things with how updates work.  Now has the
  36.         ability to force a roll-back in case I broke something.
  37.  
  38. -Version 7.4/5/6: Changing naming convention for ease-of-updating purposes.
  39.  
  40. --------------------------------------------------------------------------------
  41.  
  42.  
  43. -Rev7c: Updated minimap object record for boulders (MM_BOULDER), it never
  44.         got updated with the rest of the records in Rev 5.  Fixed a small
  45.         issue with the minimap object record for ladders (MM_LADDER), causing
  46.         ladder finding to fail on rare occasions.  Realized that main-point
  47.         tracking in the walking function was never implemented- now actually
  48.         functional.
  49.  
  50. -Rev7b: Fixed a bug in the 'ObjDTMToString' and 'ObjDTMFromString' functions
  51.         that resulted in an out-of-range error.
  52.  
  53. -Rev7a: Added maple trees, and rocks to list of useable minimap objects
  54.         (MM_MAPLE), (MM_ROCK).
  55.  
  56. -Rev 7: Added cacti to list of useable minimap objects (MM_CACTUS).
  57.         Fixed a rather grievous oversight on my part, and made sure that
  58.         SMART related code isn't actually compiled if SMART isn't defined
  59.         in the script.  Added the rather verbosely-named
  60.         'PrintObjDTMRecFromString' This allows you to pass an Object DTM
  61.         in string-form, and have the record form print out in the debug.
  62.         This makes it easy to change the contents of string-form Object DTMs
  63.         during the writing of your scripts.
  64.  
  65. -Rev 6: Added the henge object (stone circle columns) to list of useable
  66.         minimap objects (MM_HENGE).  Implemented polygonal areas.
  67.         Convex/Concave polygons can now be defined for Object DTM areas,
  68.         allowing for very specific area boundaries.
  69.  
  70. -Rev 5: I think color-finding has been improved in this revision, meaning
  71.         from now on the finding of objects is less likely to break.
  72.  
  73. -Rev4a: Improved accuracy of 'PointInPolygon' base code for polygon areas
  74.         added.  Updated minimap object record for ladder.
  75.  
  76. -Rev 4: Added the function 'PointInPolygon' which now allows for accurate
  77.         implementation of the 'InObjDTMArea' function.
  78.  
  79. -Rev 3: Added the functions 'ObjDTMFromString' and 'ObjDTMToString' these
  80.         supplement the new, more compact string-form of Object DTMs.  Updated
  81.         minimap object records for trees, ladders, and plants.
  82.  
  83. -Rev 2: Fixed minimap object record for dead trees.  Added first version of
  84.         the Object DTM generator.
  85.  
  86. -Rev 1: Basic functionality to assist in the creation of Object DTMs, can find
  87.         Object DTMs at any angle, and includes a simple walking function, and
  88.         location check.
  89.  
  90.         -Notes: Since the graphical update, the colors have been having a few
  91.         issues.  Because of some bugs in PascalScript, the InObjDTMArea
  92.         function does not work; my apologies.  On another note, if you attempt
  93.         to find an Object DTM, and it exists on screen, it will find it every
  94.         other time.  Again, on account of some issues with PascalScript.  If
  95.         you use this, there will also be a memory leak.  Again: PascalScript.
  96.  
  97. -------------------------------------------------------------------------------}
  98.  
  99. type
  100.   MMObj       = record
  101.                   Center: TPoint;
  102.                   ObjType: Integer;
  103.                 end;
  104.  
  105.   ObjDTMSP    = record
  106.                   Base: Integer;
  107.                   Drift: Integer;
  108.                   Point: TPoint;
  109.                 end;
  110.  
  111.   ObjDTM      = record
  112.                   MainPoint: TPoint;
  113.                   NumOfPoints: Integer;
  114.                   SubPoints: Array of ObjDTMSP;
  115.                   NumOfAreaPoints: Integer;
  116.                   Area: TPointArray;
  117.                 end;
  118.  
  119.   MMObjRec    = record
  120.                   Base: String; Color: Integer; CTS: Integer; Tol: Integer;
  121.                   SplitSizeX, SplitSizeY: Integer;
  122.                   SatMod, HueMod: Extended;
  123.                   AvgNumOfPoints, AvgTol: Integer;
  124.                 end;
  125.  
  126.   TLine       = record
  127.                   A, B: TPoint;
  128.                 end;
  129.  
  130.   T2DStringArray = Array of TStringArray;
  131.  
  132.  
  133. const
  134.  
  135.   MM_LADDER   = 0;
  136.   MM_TREE     = 1;
  137.   MM_DEADTREE = 2;
  138.   MM_PLANT    = 3;
  139.   MM_FLAX     = 4;
  140.   MM_BOULDER  = 5;
  141.   MM_HENGE    = 6;
  142.   MM_CACTUS   = 7;
  143.   MM_MAPLE    = 8;
  144.   MM_ROCK     = 9;
  145.  
  146. var
  147.   MMObjRecords: Array of MMObjRec;
  148.  
  149. procedure ObjectDTMUpdater;
  150. (*******************************************************************************
  151. procedure ObjectDTMUpdater;
  152. By: euphemism
  153. Last Edit: 17 Dec 2011 -- euphemism
  154. Description: Handles the auto-updating of the include.  If a newer revision
  155.              is available, or a force update is activated, this will update
  156.              the include.  A restart of the script using the include is
  157.              required.
  158. *******************************************************************************)
  159. var
  160.   IncludeNumber, LocalVersion, RemoteVersion: Integer;
  161.   Overwrite, Reason, Remote: String;
  162.   Force: Boolean;
  163. begin
  164.  
  165.   LocalVersion := 84;
  166.  
  167.   Remote := GetPage('http://alt-f4.co.cc/objdtm/ObjDTMIncludeRemote.txt');
  168.  
  169.   RemoteVersion := StrToIntDef(Between('<v>', '</v>', Remote), LocalVersion);
  170.  
  171.   Reason := Between('<ur>', '</ur>', Remote);
  172.  
  173.   Force := StrToBoolDef(Between('<f>', '</f>', Remote), False);
  174.  
  175.   if ((RemoteVersion = LocalVersion) and (not Force)) then
  176.     Exit;
  177.  
  178.   if ((Force) or (RemoteVersion > LocalVersion)) then
  179.   begin
  180.  
  181.     WriteLn('--------------------------------------');
  182.  
  183.     if (not Force) then
  184.       WriteLn('Local Version: ' + IntToStr(LocalVersion) + ' | ' + 'Remote Version: ' + IntToStr(RemoteVersion))
  185.     else
  186.       WriteLn('Object DTM Include: euphemism is forcing to version ' + IntToStr(RemoteVersion));
  187.  
  188.     WriteLn('');
  189.     WriteLn('Object DTM Include: Update reason:');
  190.  
  191.     WriteLn(Reason);
  192.     WriteLn('');
  193.  
  194.     WriteLn('Object DTM Include: Downloading.');
  195.  
  196.     Overwrite := GetPage('http://alt-f4.co.cc/objdtm/ObjDTMInclude.simba');
  197.  
  198.     WriteLn('Object DTM Include: Download complete.');
  199.  
  200.     IncludeNumber := ReWriteFile(IncludePath + 'ObjectDTM\ObjDTMInclude.simba', False);
  201.  
  202.     WriteLn('');
  203.     WriteLn('Object DTM Include: Overwriting file.');
  204.  
  205.     WriteFileString(IncludeNumber, Overwrite);
  206.     CloseFile(IncludeNumber);
  207.  
  208.     WriteLn('Object DTM Include: Updated Object DTM Include to version ' + IntToStr(RemoteVersion) + '.');
  209.     WriteLn('');
  210.     WriteLn('Object DTM Include: Please restart script.');
  211.     WriteLn('--------------------------------------');
  212.     TerminateScript;
  213.   end;
  214. end;
  215.  
  216. procedure ObjDTM_Setup;
  217. (*******************************************************************************
  218. procedure ObjDTM_Setup;
  219. By: euphemism
  220. Last Edit: 13 Dec 2011 -- euphemism
  221. Description: Loads the records for all valid objects to look for on minimap.
  222.              This procedure needs to be called at the setup of the script.
  223. *******************************************************************************)
  224. var
  225.   Ladder, Tree, DeadTree, Plant, Flax, Boulder, Henge, Cactus, Maple,
  226.    Rock: MMObjRec;
  227. begin
  228.  
  229.   ObjectDTMUpdater;
  230.  
  231.   with Ladder do
  232.   begin
  233.     Color := 602202; CTS := 1; Tol := 7;
  234.     SplitSizeX := 2; SplitSizeY := 2;
  235.     AvgNumOfPoints := 32; AvgTol := 14;
  236.   end;
  237.  
  238.   with Tree do
  239.   begin
  240.     Color := 1133343; CTS := 1; Tol := 19;
  241.     SplitSizeX := 1; SplitSizeY := 1;
  242.     AvgNumOfPoints := 18; AvgTol := 12;
  243.   end;
  244.  
  245.   with DeadTree do
  246.   begin
  247.     Color := 797238; CTS := 1; Tol := 7;
  248.     SplitSizeX := 2; SplitSizeY := 2;
  249.     AvgNumOfPoints := 13 AvgTol := 4;
  250.   end;
  251.  
  252.   with Plant do
  253.   begin
  254.     Color := 3633484; CTS := 1; Tol := 7;
  255.     SplitSizeX := 1; SplitSizeY := 1;
  256.     AvgNumOfPoints := 22 AvgTol := 10;
  257.   end;
  258.  
  259.   with Flax do
  260.   begin
  261.     Color := 11560292; CTS := 2; Tol := 0;
  262.     SplitSizeX := 2; SplitSizeY := 2;
  263.     HueMod := 1.01; SatMod := 2.87;
  264.     AvgNumOfPoints := 6; AvgTol := 3;
  265.   end;
  266.  
  267.   with Boulder do
  268.   begin
  269.     Color := 5855833; CTS := 1; Tol := 7;
  270.     SplitSizeX := 1; SplitSizeY := 1;
  271.     AvgNumOfPoints := 25; AvgTol := 7;
  272.   end;
  273.  
  274.   with Henge do
  275.   begin
  276.     Color := 4473666; CTS := 1; Tol := 6;
  277.     SplitSizeX := 1; SplitSizeY := 1;
  278.     AvgNumOfPoints := 9; AvgTol := 6;
  279.   end;
  280.  
  281.   with Cactus do
  282.   begin
  283.     Color := 1859906; CTS := 1; Tol := 6;
  284.     SplitSizeX := 1; SplitSizeY := 1;
  285.     AvgNumOfPoints := 3; AvgTol := 1;
  286.   end;
  287.  
  288.   with Maple do
  289.   begin
  290.     Color := 1130602; CTS := 1; Tol := 7;
  291.     SplitSizeX := 1; SplitSizeY := 1;
  292.     AvgNumOfPoints := 17; AvgTol := 5;
  293.   end;
  294.  
  295.   with Rock do
  296.   begin
  297.     Color := 2969473; CTS := 1; Tol := 14;
  298.     SplitSizeX := 1; SplitSizeY := 1;
  299.     AvgNumOfPoints := 25; AvgTol := 12;
  300.   end;
  301.  
  302.   MMObjRecords := [Ladder, Tree, DeadTree, Plant, Flax, Boulder, Henge, Cactus,
  303.    Maple, Rock];
  304. end;
  305.  
  306. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  307.  
  308. procedure LoadObjects;
  309. begin
  310.  
  311.   ObjDTM_Setup;
  312. end;
  313. procedure SetupODTMI;
  314. begin
  315.  
  316.   ObjDTM_Setup;
  317. end;
  318.  
  319. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  320.  
  321. function LinesIntersect(const Line1, Line2: TLine):Boolean;
  322. (*******************************************************************************
  323. function LinesIntersect(const Line1, Line2: TLine):Boolean;
  324. By: euphemism
  325. Last Edit: 27 Nov 2011 -- euphemism
  326. Description: Checks to see if the two given line segments, 'Line1' and 'Line2'
  327.              intersect.
  328. *******************************************************************************)
  329. var
  330.   Ax, Ay, Bx, By, Cx, Cy, D, E, F, LX, LY, UX, UY : Extended;
  331. begin
  332.  
  333.   Result := false;
  334.  
  335.   Ax := Line1.B.x - Line1.A.x;
  336.   Bx := Line2.A.x - Line2.B.x;
  337.  
  338.   if Ax < 0 then
  339.   begin
  340.  
  341.     LX := Line1.B.x;
  342.     UX := Line1.A.x;
  343.   end
  344.   else
  345.   begin
  346.  
  347.     UX := Line1.B.x;
  348.     LX := Line1.A.x;
  349.   end;
  350.  
  351.   if Bx > 0 then
  352.   begin
  353.  
  354.     if (UX < Line2.B.x) or (Line2.A.x < LX) then
  355.       Exit;
  356.   end else
  357.     if (UX < Line2.A.x) or (Line2.B.x < LX) then
  358.       Exit;
  359.  
  360.   Ay := Line1.B.y - Line1.A.y;
  361.   By := Line2.A.y - Line2.B.y;
  362.  
  363.   if Ay < 0 then
  364.   begin
  365.  
  366.     LY := Line1.B.y;
  367.     UY := Line1.A.y;
  368.   end else
  369.   begin
  370.  
  371.     UY := Line1.B.y;
  372.     LY := Line1.A.y;
  373.   end;
  374.  
  375.   if By > 0 then
  376.   begin
  377.  
  378.     if (UY < Line2.B.y) or (Line2.A.y < LY) then
  379.       Exit;
  380.   end else
  381.     if (UY < Line2.A.y) or (Line2.B.y < LY) then
  382.       Exit;
  383.  
  384.   Cx := Line1.A.x - Line2.A.x;
  385.   Cy := Line1.A.y - Line2.A.y;
  386.   D  := (By * Cx) - (Bx * Cy);
  387.   F  := (Ay * Bx) - (Ax * By);
  388.  
  389.   if F > 0 then
  390.   begin
  391.  
  392.     if (D < 0) or (D > F) then
  393.      Exit;
  394.   end else
  395.     if (D > 0) or  (D < F) then
  396.       Exit;
  397.  
  398.   E := (Ax * Cy) - (Ay * Cx);
  399.  
  400.   if F > 0 then
  401.   begin
  402.  
  403.     if (E < 0) or (E > F) then
  404.       Exit;
  405.   end else
  406.     if(E > 0) or (E < F) then
  407.       Exit;
  408.  
  409.   Result := true;
  410. end;
  411.  
  412. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  413.  
  414. function PointInPolygon(X, Y: Integer; Polygon: TPointArray): Boolean;
  415. (*******************************************************************************
  416. function PointInPolygon(X, Y: Integer; Polygon: TPointArray): Boolean;
  417. By: euphemism
  418. Last Edit: 1 Dec 2011 -- euphemism
  419. Description: Checks to see if the given point, defined by 'X', and 'Y', lies
  420.              within the given concave/convex polygon, 'Polygon'.  Each
  421.              consecutive vertex must be adjacent to the previous one.
  422. *******************************************************************************)
  423. var
  424.   I, Len, MaxX, MinX, MaxY, MinY: Integer;
  425.   Crossed0, Crossed1, Crossed2: Extended;
  426.   TestRay0, TestRay1, TestRay2: TLine;
  427.   Sides: Array of TLine;
  428. begin
  429.  
  430.   Crossed0 := 0;
  431.   Crossed1 := 0;
  432.   Crossed2 := 0;
  433.  
  434.   Result := False;
  435.  
  436.   Len := Length(Polygon);
  437.   SetLength(Sides, Len);
  438.  
  439.   MaxX := Polygon[1].x;
  440.   MinX := Polygon[0].x;
  441.  
  442.   MaxY := Polygon[1].y;
  443.   MinY := Polygon[0].y;
  444.  
  445.   for I := 0 to (Len - 2) do                                                    //This loop creates an array of the sides of the polygon.
  446.   begin
  447.  
  448.     Sides[i].A := Polygon[i];
  449.     Sides[i].B := Polygon[i + 1];
  450.   end;
  451.  
  452.   Sides[Len - 1].A := Polygon[Len - 1];                                         //These two lines set the last side of the polygon.
  453.   Sides[Len - 1].B := Polygon[0];
  454.  
  455.  
  456.   for I := 0 to (Len - 1) do                                                    //This loop finds the minimum X and Y values from the
  457.   begin                                                                         //passed vertices.  This is so we know where to shoot our test ray.
  458.  
  459.     MaxX := Max(Polygon[i].x, MaxX);
  460.     MinX := Min(Polygon[i].x, MinX);
  461.  
  462.     MaxY := Max(Polygon[i].y, MaxY);
  463.     MinY := Min(Polygon[i].y, MinY);
  464.   end;
  465.  
  466.   TestRay0.A := IntToPoint(X, Y);                                                //This sets the test rays to useable segments.
  467.   TestRay0.B := IntToPoint(MinX - 10, MinY - 10);
  468.  
  469.   TestRay1.A := IntToPoint(X, Y);
  470.   TestRay1.B := IntToPoint(MaxX + 10, MinY - 10);
  471.  
  472.   TestRay2.A := IntToPoint(X, Y);
  473.   TestRay2.B := IntToPoint(MaxX + 10, MaxY + 10);
  474.  
  475.   for I := 0 to (Len - 1) do                                                    //This loop runs through all sides of the polygon and sees if the
  476.   begin                                                                         //test rays intersect each side.  If so, then we increase the 'CrossedX' values
  477.                                                                                 //Using multiple test rays ensures accuracy.
  478.     if LinesIntersect(TestRay0, Sides[i]) then
  479.       Crossed0 := Crossed0 + 1;
  480.  
  481.     if LinesIntersect(TestRay1, Sides[i]) then
  482.       Crossed1 := Crossed1 + 1;
  483.  
  484.     if LinesIntersect(TestRay2, Sides[i]) then
  485.       Crossed2 := Crossed2 + 1;
  486.   end;
  487.  
  488.   if Crossed1 <= Crossed0 then
  489.     Crossed0 := Crossed1;
  490.  
  491.   if Crossed2 <= Crossed0 then                                                  //If the test rays crossed an odd number of sides, then the point is within
  492.     Crossed0 := Crossed2;                                                       //the polygon, if they crossed an even number of sides, or no sides, the point is outside.
  493.  
  494.   Result := ((Crossed0 / 2) <> (Ceil(Crossed0 / 2)));                           //This line checks to see if the test rays crossed an even or odd
  495. end;                                                                            //number of sides, and sets the result accordingly.
  496.  
  497. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  498.  
  499. function MakeCircleTPA(NumOfPoints, cX, cY, Radius: Integer): TPointArray;
  500. (*******************************************************************************
  501. function MakeCircleTPA(NumOfPoints, cX, cY, Radius: Integer): TPointArray;
  502. By: kanah
  503. Last Edit: 22 Nov 2011 -- euphemism
  504. Description: Creates a TPA with x number of points, where x is 'NumOfPoints'
  505.              around a center point specified by 'cX' and 'cY', with a
  506.              radius of 'Radius'.
  507. *******************************************************************************)
  508. var
  509.   I: Integer;
  510. begin
  511.   SetLength(Result, NumOfPoints);
  512.   for I := 0 to (NumOfPoints - 1) do
  513.   begin
  514.   Result[I] := Point(Round(cX + Sin(2 * pi * I / NumOfPoints) * Radius),
  515.    Round(cY - Cos(2 * pi * I / NumOfPoints) * Radius));
  516.   end;
  517. end;
  518.  
  519. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  520.  
  521. function GroundLevelCheck: Boolean;
  522. (*******************************************************************************
  523. function GroundLevelCheck: Boolean;
  524. By: euphemism
  525. Last Edit: 22 Nov 2011 -- euphemism
  526. Description: Creates a circular slice out of the minimap, and checks to see
  527.              if the dominant color is black.
  528. *******************************************************************************)
  529. var
  530.   Half, I, TempColor, TPALength, Valid: Integer;
  531.   Lum, Hue, Sat: Extended;
  532.   TPA: TPointArray;
  533. begin
  534.   TPA := MakeCircleTPA(500, MMCX, MMCY, 73);
  535.   TPALength := Length(TPA) - 1;
  536.   Half := Floor(TPALength / 2);
  537.  
  538.   for I := 0 to TPALength do
  539.   begin
  540.  
  541.     TempColor := GetColor(TPA[I].X, TPA[I].Y)
  542.     ColorToHSL(TempColor, Hue, Sat, Lum);
  543.     if Lum < 5 then
  544.     Inc(Valid);
  545.   end;
  546.  
  547.   Result := (Valid < Half);
  548. end;
  549.  
  550. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  551.  
  552. function FindMiniMapObj(WhatObject: MMObjRec): TPointArray;
  553. (*******************************************************************************
  554. function FindMiniMapObj(WhatObject: MMObjRec): TPointArray;
  555. By: euphemism
  556. Last Edit: 17 Dec 2011 -- euphemism
  557. Description: Finds all instances of the specified object, 'WhatObject'
  558.              on the minimap, and returns a TPA of the centers.
  559. *******************************************************************************)
  560. var
  561.   CTS, GoodAvg, H, I, Match, Tolerance: Integer;
  562.   Added: Boolean;
  563.   CoordinatesTPA, CoordinatesTempTPA, TempTPA: TPointArray;
  564.   CoordinatesATPA, CoordinatesTempATPA: T2DPointArray;
  565.   TempTp: TPoint;
  566. begin
  567.  
  568.   CTS := GetColorToleranceSpeed;
  569.   SetColorToleranceSpeed(WhatObject.CTS);
  570.  
  571.   if WhatObject.CTS > 1 then
  572.     SetColorSpeed2Modifiers(WhatObject.HueMod, WhatObject.SatMod);
  573.  
  574.   Tolerance := WhatObject.Tol;
  575.  
  576.   SetLength(CoordinatesTPA, 1);
  577.   SetLength(TempTPA, 1);
  578.  
  579.   while Tolerance < 255 do
  580.   begin
  581.  
  582.     if FindColorsTolerance(CoordinatesTempTPA, WhatObject.Color, MMX1, MMY1,    //Finds the main color of the specified minimap object.
  583.      MMX2, MMY2, Tolerance) then
  584.       Break;
  585.  
  586.     IncEx(Tolerance, 5);
  587.   end;
  588.  
  589.   for H := 0 to High(CoordinatesTempTPA) do                                     //Makes sure the colors are actually on the minimap.
  590.   begin
  591.  
  592.     TempTPA[0] := CoordinatesTempTPA[H];
  593.  
  594.     if InCircle(TempTPA[0].x, TempTPA[0].y, MMCX, MMCY, 75) then
  595.     begin
  596.  
  597.       CoordinatesTPA[Match] := TempTPA[0];
  598.       SetLength(CoordinatesTPA, Length(CoordinatesTPA) + 1);
  599.       Inc(Match);
  600.     end;
  601.   end;
  602.  
  603.   if WhatObject.CTS > 1 then
  604.     SetColorSpeed2Modifiers(0.2, 0.2);                                          //Sets color speed modifiers to defaults.
  605.   SetColorToleranceSpeed(CTS);                                                  //Sets color speed to what it was before the function was called.
  606.  
  607. //---------------------------------------------------------------------------//
  608.  
  609.   if Length(CoordinatesTPA) = 0 then                                            //If no colors are found, then the function exits.
  610.     Exit;
  611.  
  612.   SplitTPAExWrap(CoordinatesTPA, WhatObject.SplitSizeX, WhatObject.SplitSizeY,  //Uses SplitTPA based on the MMObjRec's specified sizes in order to group the
  613.    CoordinatesTempATPA);                                                        //found points into potential objects.
  614.  
  615.   SetLength(CoordinatesATPA, Length(CoordinatesTempATPA));
  616.  
  617.   for I := 0 to High(CoordinatesTempATPA) do                                    //Runs through all the groups to perform the crude algorithm to
  618.   begin                                                                         //determine if we have found an object.
  619.     Match := 0;
  620.     Added := False;
  621.  
  622.     TempTP := MiddleTPA(CoordinatesTempATPA[I]);                                //Gets the middle of the current group.
  623.  
  624.     if InRange(Length(CoordinatesTempATPA[i]),                                  //Checks to see if the number of points in the current group falls
  625.      WhatObject.AvgNumOfPoints - WhatObject.AvgTol,                             //within the MMObjRec's specified ranges.
  626.       WhatObject.AvgNumOfPoints + WhatObject.AvgTol) then
  627.     begin
  628.  
  629.       CoordinatesATPA[I] := CoordinatesTempATPA[I];
  630.       Added := True;
  631.       Inc(GoodAvg);
  632.     end else                                                                    //If the group didn't pass the first check, then we will try to
  633.     begin                                                                       //determine if it is the object another way.
  634.  
  635.       if (((Distance(MMCX, MMCY, TempTP.X, TempTP.Y) < 78)                      //If the objects is near the edge of the minimap, then we assume
  636.        and (Distance(MMCX, MMCY, TempTP.X, TempTP.Y) > 73))                     //that not all of the object will be visible.
  637.         and not Added) then
  638.       begin
  639.  
  640.         if (InRange(Length(CoordinatesTempATPA[i]),                             //So, we lower the amount of points needed to make a match, based
  641.          ((WhatObject.AvgNumOfPoints / 2) - ((WhatObject.AvgTol / 3) * 2)),     //on the original values in the MMObjRec.
  642.           ((WhatObject.AvgNumOfPoints / 2) + ((WhatObject.AvgTol / 3) * 2)))) then
  643.         begin
  644.  
  645.           CoordinatesATPA[i] := CoordinatesTempATPA[i];
  646.           Inc(GoodAvg);
  647.         end;
  648.       end;
  649.     end;
  650.   end;
  651.  
  652.  
  653.   SortATPASize(CoordinatesATPA, True);
  654.  
  655.   SetLength(CoordinatesATPA, GoodAvg);                                          //Truncates all groups that didn't pass off the array.
  656.   SetLength(Result, Length(CoordinatesATPA));
  657.  
  658.   for I := 0 to High(CoordinatesATPA) do                                        //Loops through the remaining groups, and adds their centers to the
  659.     Result[i] := MiddleTPA(CoordinatesATPA[i]);                                 //result TPA.
  660.  
  661. (* Comment the line below to paint boxes over objects as they are found.      *)//This bit of code will draw boxes around the centers of all found objects.
  662. (*-------------------------------------------------------------------------------
  663.   {$IFDEF SMART}
  664.   SMART_DrawBoxEx(True, IntToBox(0, 0, 1, 1), clGreen);
  665.   {$ENDIF}
  666.  
  667.   for I := 0 to High(TPA) do
  668.   begin
  669.     {$IFDEF SMART}
  670.     SMART_DrawBoxEx(False, IntToBox(TPA[i].x - 3, TPA[i].y - 3, TPA[i].x + 3,
  671.      TPA[i].y + 3), clBlue);
  672.     {$ENDIF}
  673.   end;
  674. //----------------------------------------------------------------------------*)
  675. end;
  676.  
  677. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  678.  
  679. function ObjDTMFromString(ObjDTMString: String): ObjDTM;
  680. (*******************************************************************************
  681. function ObjDTMFromString(ObjDTMString: String): ObjDTM;
  682. By: euphemism
  683. Last Edit: 6 Dec 2011 -- euphemism
  684. Description: Converts a string into an Object DTM record.
  685. *******************************************************************************)
  686. var
  687.   AB, I, Len, SP: Integer;
  688.   ExIntArray: TIntegerArray;
  689.   ExStrArray: TStringArray;
  690. begin
  691.  
  692.   ExStrArray := Explode(':', ObjDTMString);                                     //Explodes the string into an array based on the delimiter ':'
  693.   Len := Length(ExStrArray);
  694.   SetLength(ExIntArray, Len);
  695.  
  696.   for I := 0 to (Len - 1) do
  697.     ExIntArray[i] := StrToInt(ExStrArray[i]);                                   //Converts the string array into an integer array.
  698.  
  699.   Result.MainPoint.x := ExIntArray[0];                                          //Sets the x and y of the main-point.
  700.   Result.MainPoint.y := ExIntArray[1];
  701.  
  702.   Result.NumOfPoints := ExIntArray[2];                                          //Sets the number of points in the Object DTM.
  703.   SetLength(Result.SubPoints, Result.NumOfPoints);
  704.  
  705.   for I := 1 to Result.NumOfPoints do                                           //Loops through and sets the sub-points' values for
  706.   begin                                                                         //base type, drift, and point location.
  707.  
  708.     SP := ((i * 3) + (i - 1));
  709.  
  710.     Result.SubPoints[i - 1].Base    := ExIntArray[SP];
  711.     Result.SubPoints[i - 1].Drift   := ExIntArray[SP + 1];
  712.     Result.SubPoints[i - 1].Point.x := ExIntArray[SP + 2];
  713.     Result.SubPoints[i - 1].Point.y := ExIntArray[SP + 3];
  714.   end;
  715.  
  716.   if ((Len > (SP + 4)) and (ExIntArray[SP + 4] > 0)) then                       //loops through and sets the area box corners.
  717.   begin
  718.  
  719.     Result.NumOfAreaPoints := ExIntArray[SP + 4];
  720.     SetLength(Result.Area, Result.NumOfAreaPoints);
  721.  
  722.     AB := SP + 4;
  723.  
  724.     Len := ExIntArray[SP + 4];
  725.  
  726.     for I := 1 to Len do
  727.     begin
  728.  
  729.       IncEx(AB, 2);
  730.  
  731.       Result.Area[i - 1].x := ExIntArray[AB - 1];
  732.       Result.Area[i - 1].y := ExIntArray[AB];
  733.     end;
  734.   end else
  735.   begin
  736.  
  737.     Result.NumOfAreaPoints := 0;
  738.     SetLength(Result.Area, 0);
  739.   end;
  740. end;
  741.  
  742. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  743.  
  744. function ObjDTMToString(ObjectDTM: ObjDTM): String;
  745. (*******************************************************************************
  746. function ObjDTMToString(ObjectDTM: ObjDTM): String;
  747. By: euphemism
  748. Last Edit: 6 Dec 2011 -- euphemism
  749. Description: Converts an Object DTM record into a string.
  750. *******************************************************************************)
  751. var
  752.   I, Len: Integer;
  753. begin
  754.  
  755.   SetLength(Result, 0);
  756.  
  757.   Result := IntToStr(ObjectDTM.MainPoint.x) + ':';
  758.   Result := Result + IntToStr(ObjectDTM.MainPoint.y) + ':';
  759.   Result := Result + IntToStr(ObjectDTM.NumOfPoints);
  760.  
  761.   for I := 0 to (ObjectDTM.NumOfPoints - 1) do                                  //Loops through and just adds all the values into
  762.   begin                                                                         //a single string with the delimiter ':' between values.
  763.  
  764.     Result := Result + ':' + IntToStr(ObjectDTM.SubPoints[i].Base);
  765.     Result := Result + ':' + IntToStr(ObjectDTM.SubPoints[i].Drift);
  766.     Result := Result + ':' + IntToStr(ObjectDTM.SubPoints[i].Point.x);
  767.     Result := Result + ':' + IntToStr(ObjectDTM.SubPoints[i].Point.y);
  768.   end;
  769.  
  770.   if not ObjectDTM.NumOfAreaPoints = 0 then                                     //Checks to see if an area box is defined, and if so,
  771.   begin                                                                         //adds it to the end of the string.
  772.  
  773.     Result := Result + ':' + IntToStr(ObjectDTM.NumOfAreaPoints);
  774.     Len := ObjectDTM.NumOfAreaPoints;
  775.  
  776.     for I := 0 to (Len - 1) do
  777.     begin
  778.  
  779.       if Len = 0 then
  780.         Break;
  781.  
  782.       Result := Result + ':' + IntToStr(ObjectDTM.Area[i].x);
  783.       Result := Result + ':' + IntToStr(ObjectDTM.Area[i].y);
  784.     end;
  785.   end;
  786. end;
  787.  
  788. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  789.  
  790. function ExtractBasesFromObjDTM(ObjectDTM: String): TIntegerArray;
  791. (*******************************************************************************
  792. function ExtractBasesFromObjDTM(ObjectDTM: String): TIntegerArray;
  793. By: euphemism
  794. Last Edit: 17 Dec 2011 -- euphemism
  795. Description: Takes an Object DTM, and extracts unique sub-point bases.
  796.              i.e. if an Object DTM has three sub-points, two if which
  797.              are trees, and one is a ladder, the function's output
  798.              would be [1, 0]
  799. *******************************************************************************)
  800. var
  801.   H, I: Integer;
  802.   ObjDTMCopy: ObjDTM;
  803. begin
  804.  
  805.   H := 0;
  806.   SetLength(Result, 0);
  807.   ObjDTMCopy := ObjDTMFromString(ObjectDTM);                                    //Takes the Object DTM in string-form, and converts it to
  808.                                                                                 //an ObjDTM type.
  809.   for I := 0 to (ObjDTMCopy.NumOfPoints - 1) do                                 //Loops through the sub-points
  810.   begin
  811.  
  812.     if not InIntArray(Result, ObjDTMCopy.SubPoints[i].Base) then                //If the sub-point base isn't already existant in the result,
  813.     begin                                                                       //then we add it.
  814.  
  815.       Inc(H);
  816.       SetLength(Result, H);
  817.       Result[H - 1] := ObjDTMCopy.SubPoints[i].Base;
  818.     end;
  819.   end;
  820. end;
  821.  
  822. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  823.  
  824. function ExtractBasesFromMultiObjDTM(ObjectDTM: TStringArray): TIntegerArray;
  825. (*******************************************************************************
  826. function ExtractBasesFromObjDTMs(ObjectDTM: TStringArray): TIntegerArray;
  827. By: euphemism
  828. Last Edit: 17 Dec 2011 -- euphemism
  829. Description: Takes a list of Object DTMs, and extracts unique
  830.              sub-point bases. i.e. if out of all the Object DTMs,
  831.              four sub-points have trees as bases, one is a ladder,
  832.              and another is a plant, the function's output
  833.              would be [1, 0, 3]
  834. *******************************************************************************)
  835. var
  836.   H, I, Len, Z: Integer;
  837.   BasesArray: TIntegerArray;
  838. begin
  839.  
  840.   SetLength(Result, 0);
  841.   Z := 0;
  842.   Len := Length(ObjectDTM);
  843.  
  844.   for I := 0 to (Len - 1) do                                                    //Loops through each Object DTM within the Multi
  845.   begin                                                                         //Object DTM
  846.  
  847.     BasesArray := ExtractBasesFromObjDTM(ObjectDTM[i]);                         //Extracts bases from the Object DTM being looped through
  848.  
  849.     for H := 0 to High(BasesArray) do                                           //Goes through each base to see if it has been added to
  850.       if not InIntArray(Result, BasesArray[H]) then                             //the result, if not, then it is added.
  851.       begin
  852.  
  853.         Inc(Z);
  854.         SetLength(Result, Z);
  855.         Result[Z - 1] := BasesArray[H];
  856.       end;
  857.   end;
  858. end;
  859.  
  860. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  861.  
  862. function ExtractBasesFromPath(Path: T2DStringArray): TIntegerArray;
  863. (*******************************************************************************
  864. function ExtractBasesFromPath(Path: T2DStringArray): TIntegerArray;
  865. By: euphemism
  866. Last Edit: 17 Dec 2011 -- euphemism
  867. Description: Takes a given path, and extracts unique sub-point bases
  868.              from the Object DTMs within.  i.e. if out of all of the
  869.              Object DTMs, four sub-points have trees as bases, one is
  870.              a ladder, and another is a plant, the function's output
  871.              would be [1, 0, 3]
  872. *******************************************************************************)
  873. var
  874.   H, I, Z: Integer;
  875.   BasesArray: TIntegerArray;
  876. begin
  877.  
  878.   SetLength(Result, 0);
  879.  
  880.   for I := 0 to High(Path) do                                                   //Loops through each Multi Object DTM within
  881.   begin                                                                         //the path
  882.  
  883.     BasesArray := ExtractBasesFromMultiObjDTM(Path[i]);                         //Extracts the bases from the Multi Object DTM.
  884.  
  885.     for H := 0 to High(BasesArray) do                                           //Loops through the extracted bases.
  886.     begin
  887.  
  888.       if not InIntArray(Result, BasesArray[h]) then                             //If the base isn't in the result, then it is added.
  889.       begin
  890.  
  891.         Inc(Z);
  892.         SetLength(Result, Z);
  893.         Result[Z - 1] := BasesArray[h];
  894.       end;
  895.     end;
  896.   end;
  897. end;
  898.  
  899. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  900.  
  901. function GatherMiniMapObjects(ObjectsToFind: TIntegerArray): Array of MMObj;
  902. (*******************************************************************************
  903. function GatherMiniMapObjects(ObjectsToFind: TIntegerArray): Array of MMObj;
  904. By: euphemism
  905. Last Edit: 17 Dec 2011 -- euphemism
  906. Description: Takes a list of minimap objects, and locates them on the
  907.              minimap.  The result is an array of the coordinate locations
  908.              and types of the objects.
  909. *******************************************************************************)
  910. var
  911.   H, I, J, NewRangeEnd, NewRangeStart, NumOfBase: Integer;
  912.   BaseTPA: TPointArray;
  913.  
  914. begin
  915.  
  916.   SetLength(Result, 0);
  917.   Freeze;
  918.  
  919.   for I := 0 to High(ObjectsToFind) do                                          //This loop runs through all the objects in the array,
  920.   begin                                                                         //finds them, and adds them to a new array that keeps track
  921.                                                                                 //of where each object is, and what type of object it is.
  922.     BaseTPA := FindMiniMapObj(MMObjRecords[ObjectsToFind[i]]);
  923.     NumOfBase := Length(BaseTPA);
  924.  
  925.     NewRangeStart := Length(Result);
  926.     NewRangeEnd := Length(Result) + NumOfBase;
  927.  
  928.     SetLength(Result, NewRangeEnd);
  929.  
  930.     for J := 0 to (NumOfBase - 1) do
  931.     begin
  932.  
  933.       Result[J + NewRangeStart].Center :=  BaseTPA[J];
  934.     end;
  935.  
  936.     for H := NewRangeStart to (NewRangeEnd - 1) do
  937.     begin
  938.  
  939.       Result[H].ObjType := ObjectsToFind[i];
  940.     end;
  941.   end;
  942.  
  943.   UnFreeze;
  944. end;
  945.  
  946. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  947.  
  948. function FindObjDTMEx(DTMToFind: String; out cx, cy: Integer;
  949.  GroundLevel: Boolean; BaseObjects: Array of MMObj): Boolean;
  950. (*******************************************************************************
  951. function FindObjDTMEx(DTMToFind: String; out cx, cy: Integer;
  952.  GroundLevel: Boolean; BaseObjects: Array of MMObj): Boolean;
  953. By: euphemism
  954. Last Edit: 19 Dec 2011 -- euphemism
  955. Description: Finds the specified Object DTM, 'DTMToFind' on the minimap.
  956.              Results true if found, and the main point is passed via
  957.              reference through 'cx, and 'cy'.
  958. *******************************************************************************)
  959. var
  960.   BaseHigh, DeltaX, DeltaY, H, I, J, K, Match, NumOfSP: Integer;
  961.   ScreenRotationR: Extended;
  962.   Found: Boolean;
  963.   TempCenter, TempCenter2, TempCenter3, ResultPoint: TPoint;
  964.   ObjDTMCopy: ObjDTM;
  965.   BaseTPA, ResultsTPA: TPointArray;
  966. begin
  967.  
  968.   Found := False;
  969.   Result := Found;
  970.  
  971.   if not GroundLevel = GroundLevelCheck then                                    //Checks to see if the player is currently at ground level,
  972.     Exit;
  973.  
  974.   cx := 0;
  975.   cy := 0;
  976.  
  977.   Match := 0;
  978.   ObjDTMCopy := ObjDTMFromString(DTMToFind);
  979.  
  980.   NumOfSP := ObjDTMCopy.NumOfPoints - 1;
  981.  
  982.   for H := 0 to NumOfSP do                                                      //This makes the sub-points relative to the main-point.
  983.   begin
  984.  
  985.     ObjDTMCopy.SubPoints[H].Point.x := ObjDTMCopy.MainPoint.x - ObjDTMCopy.SubPoints[H].Point.x;
  986.     ObjDTMCopy.SubPoints[H].Point.y := ObjDTMCopy.MainPoint.y - ObjDTMCopy.SubPoints[H].Point.y;
  987.   end;
  988.  
  989.   BaseHigh := Length(BaseObjects) - 1;
  990.  
  991.   SetLength(ResultsTPA, NumOfSP + 1);
  992.   SetLength(BaseTPA, BaseHigh + 1);
  993.  
  994.   ScreenRotationR := rs_GetCompassAngleRadians;                                 //Gets the Runescape compass's direction.
  995.  
  996.   for I := 0 to BaseHigh do                                                     //This line rotates the found points based on the compass direction.
  997.     BaseObjects[i].Center := RotatePoint(BaseObjects[i].Center, ScreenRotationR, MMCX, MMCY);
  998.  
  999.   for H := 0 to NumOfSP do                                                      //This large nest of loops is what finds the Object DTM.
  1000.   begin                                                                         //The first loop runs through all the sub-points.
  1001.  
  1002.     if Found then
  1003.       Break;
  1004.  
  1005.     for I := 0 to BaseHigh do                                                   //This second loop runs through all the found objects.
  1006.     begin
  1007.  
  1008.       Match := 0;
  1009.  
  1010.       if not (BaseObjects[i].ObjType = ObjDTMCopy.SubPoints[H].Base) then       //If the current object the code is looking at doesn't match the
  1011.         Continue;                                                               //sub-point we are looping through, then we continue through the loop.
  1012.  
  1013.       TempCenter := BaseObjects[i].Center;                                      //This group of lines creates a temporary main-point based off this
  1014.       TempCenter.x := TempCenter.x + ObjDTMCopy.SubPoints[H].Point.x;           //object's position that should be very near to the actual main-point if this is in fact the correct
  1015.       TempCenter.y := TempCenter.y + ObjDTMCopy.SubPoints[H].Point.y;           //object at the correct position.
  1016.  
  1017.       for J := 0 to NumOfSP do                                                  //This loop runs through all the sub-points, to see if they exist where they should
  1018.       begin                                                                     //from the new, temporary main-point created off of the object we are looping through.
  1019.  
  1020.         DeltaX := TempCenter.x - ObjDTMCopy.SubPoints[J].Point.x;               //These two lines move the sub-point we are looping through to its position relative to
  1021.         DeltaY := TempCenter.y - ObjDTMCopy.SubPoints[J].Point.y;               //the new, temporary main-point.
  1022.  
  1023.         TempCenter2 := IntToPoint(DeltaX, DeltaY);
  1024.  
  1025.         for K := 0 to BaseHigh do                                               //This loops through all the found objects again.
  1026.         begin
  1027.  
  1028.           if (InCircle(BaseObjects[K].Center.x, BaseObjects[K].Center.y,        //This if then statement checks to see if an object of the right type exists
  1029.            TempCenter2.x, TempCenter2.y, ObjDTMCopy.SubPoints[J].Drift)         //within a circle, specified by the drift in the Object DTM record, around the newly positioned
  1030.             and (BaseObjects[K].ObjType = ObjDTMCopy.SubPoints[J].Base)) then   //sub-point.
  1031.           begin
  1032.  
  1033.             DeltaX := BaseObjects[K].Center.x + ObjDTMCopy.SubPoints[J].Point.x;//If so, the loop adds the new, temporary main-point to an array, and
  1034.             DeltaY := BaseObjects[K].Center.y + ObjDTMCopy.SubPoints[J].Point.y;//increases the match variable.
  1035.             TempCenter3 := IntToPoint(DeltaX, DeltaY);
  1036.  
  1037.             if Match > NumOfSP then
  1038.               Break;
  1039.  
  1040.             ResultsTPA[Match] := TempCenter3;
  1041.             Inc(Match);
  1042.           end;
  1043.         end;
  1044.       end;
  1045.  
  1046.       if Match = ObjDTMCopy.NumOfPoints then                                    //If, after looping through all the objects from the new, temporary main-point
  1047.       begin                                                                     //we just created, and we have matched sub-points that equal the number of
  1048.                                                                                 //sub-points in the Object DTM, then we know we have a match.
  1049.         Found := True;
  1050.  
  1051.         ResultPoint := RotatePoint(MiddleTPA(ResultsTPA),                       //We get the middle of all the temporary main-points to ensure that the returned
  1052.          (ScreenRotationR * -1), MMCX, MMCY);                                   //point is as accurate as possible, and we rotate it back to the current compass
  1053.                                                                                 //direction.
  1054.         cx := ResultPoint.x;
  1055.         cy := ResultPoint.y;
  1056.       end;
  1057.  
  1058.       if Found then                                                             //This line just makes sure we don't do any un-necessary looping.
  1059.       Break;
  1060.     end;
  1061.   end;
  1062.  
  1063.   Result := Found;
  1064. end;
  1065.  
  1066. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  1067.  
  1068. function FindObjDTM(DTMToFind: String; out cx, cy: Integer;
  1069.  GroundLevel: Boolean): Boolean;
  1070. (*******************************************************************************
  1071. function FindObjDTM(DTMToFind: String; var cx, cy: Integer;
  1072.  GroundLevel: Boolean): Boolean;
  1073. By: euphemism
  1074. Last Edit: 19 Dec 2011 -- euphemism
  1075. Description: Calls 'FindObjDTMEx'.
  1076. *******************************************************************************)
  1077. var
  1078.   BasesToCheck: TIntegerArray;
  1079.   BaseObjects: Array of MMObj;
  1080. begin
  1081.   Result := False;
  1082.  
  1083.   if not GroundLevel = GroundLevelCheck then                                    //Checks to see if the player is currently at ground level,
  1084.     Exit;                                                                       //it then sees if the result is equal to the 'GroundLevel' parameter.
  1085.                                                                                 //Otherwise, it exits.
  1086.  
  1087.   BasesToCheck := ExtractBasesFromObjDTM(DTMToFind);
  1088.   BaseObjects := GatherMiniMapObjects(BasesToCheck);
  1089.  
  1090.     Result := FindObjDTMEx(DTMToFind, cx, cy, GroundLevel, BaseObjects);
  1091.  
  1092. end;
  1093.  
  1094. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  1095.  
  1096. function FindMultiObjDTM(DTMToFind: TStringArray; out cx, cy: Integer;
  1097.  GroundLevel: Boolean): Boolean;
  1098. (*******************************************************************************
  1099. function FindMultiObjDTM(DTMToFind: TStringArray; out cx, cy: Integer;
  1100.  GroundLevel: Boolean): Boolean;
  1101. By: euphemism
  1102. Last Edit: 19 Dec 2011 -- euphemism
  1103. Description: Loops through each Object DTM in the Multi Object DTM
  1104.              and calls 'FindObjDTMEx'.
  1105. *******************************************************************************)
  1106. var
  1107.   I: Integer;
  1108.   BasesToCheck: TIntegerArray;
  1109.   BaseObjects: Array of MMObj;
  1110. begin
  1111.   Result := False;
  1112.  
  1113.   if not GroundLevel = GroundLevelCheck then                                    //Checks to see if the player is currently at ground level,
  1114.     Exit;                                                                       //it then sees if the result is equal to the 'GroundLevel' parameter.
  1115.                                                                                 //Otherwise, it exits.
  1116.  
  1117.   BasesToCheck := ExtractBasesFromMultiObjDTM(DTMToFind);
  1118.   BaseObjects := GatherMiniMapObjects(BasesToCheck);
  1119.  
  1120.   for I := 0 to High(DTMToFind) do
  1121.   begin
  1122.  
  1123.     Result := FindObjDTMEx(DTMToFind[i], cx, cy, GroundLevel, BaseObjects);
  1124.  
  1125.     if Result then
  1126.       Break;
  1127.   end;
  1128. end;
  1129.  
  1130. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  1131.  
  1132. function ObjDTM_InAreaEx(DTMToCheck: String; cX, cY: Integer; GroundLevel: Boolean): Boolean;
  1133. (*******************************************************************************
  1134. function InObjDTMArea(DTMToCheck: String; GroundLevel: Boolean): Boolean;
  1135. By: euphemism
  1136. Last Edit: 19 Dec 2011 -- euphemism
  1137. Description: Calls 'FindObjDTM' to find the Object DTM 'DTMToCheck'.  If
  1138.              found, Uses the area box of 'DTMToCheck' to see if the player
  1139.              is within.  Because the box is specified by four coordinates,
  1140.              it can be tailored to fit a very specific area.  Returns true
  1141.              if the player is within the box.
  1142. *******************************************************************************)
  1143. var
  1144.   I, X, Y: Integer;
  1145.   ScreenRotationD: Extended;
  1146.   Area: TPointArray;
  1147.   ObjCopy: ObjDTM;
  1148. begin
  1149.  
  1150.   Result := False;
  1151.  
  1152.   ObjCopy := ObjDTMFromString(DTMToCheck);
  1153.   ScreenRotationD := rs_GetCompassAngleDegrees;                                 //Gets the current compass direction in order to
  1154.                                                                                 //properly rotate the box.
  1155.   if FindObjDTM(DTMToCheck, X, Y, GroundLevel) then
  1156.   begin
  1157.  
  1158.     SetLength(Area, ObjCopy.NumOfAreaPoints);
  1159.  
  1160.     for I := 0 to (ObjCopy.NumOfAreaPoints - 1) do                              //Makes the box corners relative to the found main-point,
  1161.     begin                                                                       //and rotates the box according to the compass direction.
  1162.  
  1163.       ObjCopy.Area[i].x := ObjCopy.Area[i].x - ObjCopy.MainPoint.x;
  1164.       ObjCopy.Area[i].y := ObjCopy.Area[i].y - ObjCopy.MainPoint.y;
  1165.  
  1166.       ObjCopy.Area[i].x := X + ObjCopy.Area[i].x;
  1167.       ObjCopy.Area[i].y := Y + ObjCopy.Area[i].y;
  1168.  
  1169.       Area[i] := RotatePoint(ObjCopy.Area[i], Radians(ScreenRotationD) * -1,
  1170.        X, Y);
  1171.     end;
  1172.  
  1173.     Result := PointInPolygon(cX, cY, Area);                                 //Checks to see if the player is inside the area box.
  1174.   end else                                                                      //If so, the function results true.
  1175.   begin
  1176.  
  1177.     Result := False;
  1178.   end;
  1179. end;
  1180.  
  1181. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  1182.  
  1183. function ObjDTM_InArea(DTMToCheck: String; GroundLevel: Boolean): Boolean;
  1184. (*******************************************************************************
  1185. function ObjDTM_InArea(DTMToCheck: String; GroundLevel: Boolean): Boolean;
  1186. By: euphemism
  1187. Last Edit: 19 Dec 2011 -- euphemism
  1188. Description: Calls 'FindObjDTM' to find the Object DTM 'DTMToCheck'.  If
  1189.              found, Uses the area box of 'DTMToCheck' to see if the player
  1190.              is within.  Because the box is specified by four coordinates,
  1191.              it can be tailored to fit a very specific area.  Returns true
  1192.              if the player is within the box.
  1193. *******************************************************************************)
  1194. begin
  1195.  
  1196.   Result := ObjDTM_InAreaEx(DTMToCheck, MMCX, MMCY, GroundLevel);
  1197. end;
  1198.  
  1199. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  1200.  
  1201. function InObjDTMArea(DTMToCheck: String; GroundLevel: Boolean): Boolean;
  1202. begin
  1203.   Result := ObjDTM_InArea(DTMToCheck, GroundLevel);
  1204. end;
  1205.  
  1206. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  1207.  
  1208. function ObjDTM_InMultiArea(DTMToCheck: TStringArray; GroundLevel: Boolean): Boolean;
  1209. (*******************************************************************************
  1210. function InMultiObjDTMArea(DTMToCheck: TStringArray; GroundLevel: Boolean): Boolean;
  1211. By: euphemism
  1212. Last Edit: 26 Nov 2011 -- euphemism
  1213. Description: Calls 'ObjDTM_InArea' for each Object DTM within the
  1214.              Multi Object DTM.  If the the function results true for one
  1215.              of the Object DTMs, this function breaks out of the loop
  1216.              and results true.
  1217. *******************************************************************************)
  1218. var
  1219.   H: Integer;
  1220. begin
  1221.  
  1222.   Result := False;
  1223.  
  1224.   for H := 0 to High(DTMToCheck) do
  1225.   begin
  1226.  
  1227.     Result := ObjDTM_InArea(DTMToCheck[h], GroundLevel);
  1228.  
  1229.     if Result then
  1230.       Break;
  1231.   end;
  1232. end;
  1233.  
  1234. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  1235.  
  1236. function ObjDTM_WalkEx(ObjDTMToWalk: String; FlagDistance, PollRate,
  1237.  Tries: Integer; GroundLevel: Boolean; BaseObjects: Array of MMObj): Boolean;
  1238. (*******************************************************************************
  1239. function ObjDTM_WalkEx(ObjDTMToWalk: String; FlagDistance, PollRate,
  1240.  Tries: Integer; GroundLevel: Boolean; BaseObjects: Array of MMObj): Boolean;
  1241. By: euphemism
  1242. Last Edit: 07 Dec 2011 -- euphemism
  1243. Description: Calls 'FindObjDTMEx' every x milliseconds specified by 'PollRate'
  1244.              a maximum of x tries, specified by 'Tries' to find the
  1245.              Object DTM 'ObjDTMToWalk'.  If found, Waits for the flag to
  1246.              be a distance x from the player, where x is 'FlagDistance'.
  1247.              If the Object DTM is found, and the function has maxed out
  1248.              the tries, but the main-point is off the minimap, the
  1249.              function will click the closest available point.  Returns true
  1250.              if the Object DTM was found, and it clicked to walk.
  1251. *******************************************************************************)
  1252. var
  1253.   Attempts, X, XOfQ, Y, YOfQ: Integer;
  1254.   Theta: Extended;
  1255.   Found, Tracking: Boolean;
  1256.   TrackP: TPoint;
  1257. begin
  1258.   Attempts := 0;
  1259.   Found := False;
  1260.   Result := False;
  1261.   Tracking := False;
  1262.  
  1263.  
  1264.   while Attempts < Tries do                                                     //If the function fails, it will loop through as many times as there are tries.
  1265.   begin
  1266.  
  1267.     Inc(Attempts);
  1268.  
  1269.     if FindObjDTMEx(ObjDTMToWalk, X, Y, GroundLevel, BaseObjects) then
  1270.     begin
  1271.  
  1272.       Found := True;
  1273.       if InCircle(X, Y, MMCX, MMCY, 75) then                                    //This checks to see if the main-point is actually clickable.
  1274.       begin
  1275.  
  1276.         WriteLn('Found Object DTM, walking.');
  1277.         Mouse(X, Y, 0, 0, True);                                                //Clicks.
  1278.         Wait(500);
  1279.         FFlag(FlagDistance);                                                    //Waits until the specified distance is reached.
  1280.         WriteLn('Flag distance reached.');
  1281.         Result := True;
  1282.         Break;
  1283.       end else
  1284.       begin                                                                     //If the Object DTM is found, but the main-point is off-screen,
  1285.                                                                                 //then we make note of the current position, but don't click.
  1286.         TrackP.x := X;
  1287.         TrackP.y := Y;
  1288.  
  1289.         if not Tracking then
  1290.         begin
  1291.  
  1292.           WriteLn('Found Object DTM, but can' + #39 + 't reach main point.  ' +
  1293.            'Tracking Object DTM.');
  1294.           Tracking := True;
  1295.         end;
  1296.  
  1297.         if ((Attempts = Tries) and Found) then                                  //If we have reached the maximum number of tries, and the Object DTM
  1298.         begin                                                                   //has been found, but still isn't clickable, then we find the closest
  1299.                                                                                 //available point and click it.
  1300.           Theta := arctan2((abs(TrackP.y - MMCY)), (abs(TrackP.x - MMCX)));
  1301.  
  1302.           if ((TrackP.y - MMCY) < 0) then
  1303.             YOfQ := (((Floor(74 * sin(Theta))) * -1) + MMCY)
  1304.           else
  1305.             YOfQ := ((Floor(74 * sin(Theta))) + MMCY);
  1306.  
  1307.           if ((TrackP.x - MMCX) < 0) then
  1308.             XOfQ := (((Floor(74 * cos(Theta))) * -1) + MMCX)
  1309.           else
  1310.             XOfQ := ((Floor(74 * cos(Theta))) + MMCX);
  1311.  
  1312.           Mouse(XOfQ, YOfQ, 0, 0, True);
  1313.           Wait(500);
  1314.           WriteLn('Found DTM, but couldn' + #39 +
  1315.            't reach main point, getting as close as possible.');
  1316.  
  1317.           FFlag(FlagDistance);                                                  //Waits until the specified distance is reached.
  1318.           Result := True;
  1319.         end;
  1320.       end;
  1321.  
  1322.     end else
  1323.     begin
  1324.  
  1325.       WriteLn('Did not find Object DTM.');
  1326.       Found := False;
  1327.       Result := False;
  1328.       Wait(PollRate);                                                           //If the Object DTM isn't found, then we wait for the specified amount
  1329.     end;                                                                        //of time before trying to find it again.
  1330.   end;
  1331. end;
  1332.  
  1333. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  1334.  
  1335. function ObjDTM_Walk(ObjDTMToWalk: String; FlagDistance, PollRate,
  1336.  Tries: Integer; GroundLevel: Boolean): Boolean;
  1337.  (*******************************************************************************
  1338. function ObjDTM_Walk(ObjDTMToWalk: String; FlagDistance, PollRate,
  1339.  Tries: Integer; GroundLevel: Boolean): Boolean;
  1340. By: euphemism
  1341. Last Edit: 19 Dec 2011 -- euphemism
  1342. Description: Calls 'ObjDTM_WalkEx'.
  1343. *******************************************************************************)
  1344. var
  1345.   BasesToCheck: TIntegerArray;
  1346.   BaseObjects: Array of MMObj;
  1347. begin
  1348.  
  1349.   BasesToCheck := ExtractBasesFromObjDTM(ObjDTMToWalk);
  1350.   BaseObjects := GatherMiniMapObjects(BasesToCheck);
  1351.  
  1352.   Result := ObjDTM_WalkEx(ObjDTMToWalk, FlagDistance, PollRate, Tries, GroundLevel, BaseObjects);
  1353. end;
  1354.  
  1355. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  1356.  
  1357. function ObjDTM_MultiWalkEx(ObjDTMToWalk: TStringArray; FlagDistance, PollRate,
  1358.  Tries: Integer; GroundLevel: Boolean; BaseObjects: Array of MMObj): Boolean;
  1359. (*******************************************************************************
  1360. function ObjDTM_MultiWalkEx(ObjDTMToWalk: TStringArray; FlagDistance, PollRate,
  1361.  Tries: Integer; GroundLevel: Boolean; BaseObjects: Array of MMObj): Boolean;
  1362. By: euphemism
  1363. Last Edit: 19 Dec 2011 -- euphemism
  1364. Description: Takes the given Multi Object DTM 'ObjDTMToWalk' and attempts to
  1365.              find it 'Tries' amount of times.  If not found, it will wait
  1366.              'PollRate' milliseconds before trying again.  If found, the
  1367.              function will click the main-point of the found Object DTM, and
  1368.              will wait until the player is within 'FlagDistance' before
  1369.              resulting true.  Otherwise, the function will result false.
  1370. *******************************************************************************)
  1371. var
  1372.   I, X, Y: Integer;
  1373. begin
  1374.  
  1375.   for I := 0 to High(ObjDTMToWalk) do
  1376.   begin
  1377.  
  1378.     if FindObjDTMEx(ObjDTMToWalk[i], X, Y, GroundLevel, BaseObjects) then
  1379.     begin
  1380.  
  1381.       Result := ObjDTM_WalkEx(ObjDTMToWalk[i], FlagDistance, PollRate, Tries, GroundLevel, BaseObjects);
  1382.       Break;
  1383.     end;
  1384.   end;
  1385. end;
  1386.  
  1387. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  1388.  
  1389. function ObjDTM_MultiWalk(ObjDTMToWalk: TStringArray; FlagDistance, PollRate,
  1390.  Tries: Integer; GroundLevel: Boolean): Boolean;
  1391. (*******************************************************************************
  1392. function ObjDTM_MultiWalk(ObjDTMToWalk: TStringArray; FlagDistance, PollRate,
  1393.  Tries: Integer; GroundLevel: Boolean): Boolean;
  1394. By: euphemism
  1395. Last Edit: 19 Dec 2011 -- euphemism
  1396. Description: Calls 'ObjDTM_MultiWalkEx'
  1397. *******************************************************************************)
  1398. var
  1399.   BasesToCheck: TIntegerArray;
  1400.   BaseObjects: Array of MMObj;
  1401. begin
  1402.  
  1403.   BasesToCheck := ExtractBasesFromMultiObjDTM(ObjDTMToWalk);
  1404.   BaseObjects := GatherMiniMapObjects(BasesToCheck);
  1405.  
  1406.   Result := ObjDTM_MultiWalkEx(ObjDTMToWalk, FlagDistance, PollRate, Tries, GroundLevel, BaseObjects);
  1407. end;
  1408.  
  1409. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  1410.  
  1411. function ObjDTMWalk(ObjDTMToWalk: String; FlagDistance, PollRate,
  1412.  Tries: Integer; GroundLevel: Boolean): Boolean;
  1413. (*******************************************************************************
  1414. function ObjDTMWalk(ObjDTMToWalk: String; FlagDistance, PollRate,
  1415.  Tries: Integer; GroundLevel: Boolean): Boolean;
  1416. By: euphemism
  1417. Last Edit: 19 Dec 2011 -- euphemism
  1418. Description: Calls 'ObjDTM_Walk'
  1419. *******************************************************************************)
  1420. begin
  1421.   Result := ObjDTM_Walk(ObjDTMToWalk, FlagDistance, PollRate, Tries, GroundLevel);
  1422. end;
  1423.  
  1424. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  1425.  
  1426. function ObjDTM_PathWalk(Path: T2DStringArray; FlagDistance, PollRate,
  1427.  Tries: Integer; GroundLevel: Boolean): Boolean;
  1428. (*******************************************************************************
  1429. function ObjDTM_PathWalk(Path: T2DStringArray; FlagDistance, PollRate,
  1430.  Tries: Integer; GroundLevel: Boolean): Boolean;
  1431. By: euphemism
  1432. Last Edit: 19 Dec 2011 -- euphemism
  1433. Description: Allegedly walks an Object DTM path, which is a two-dimensional
  1434.              string array comprised of Multi Object DTMs.
  1435. *******************************************************************************)
  1436. var
  1437.   H, I, Len, X, Y: Integer;
  1438.   Found: Boolean;
  1439.   BasesToCheck: TIntegerArray;
  1440.   BaseObjects: Array of MMObj;
  1441. begin
  1442.  
  1443.   Found := False;
  1444.   Result := True;
  1445.  
  1446.   BasesToCheck := ExtractBasesFromPath(Path);
  1447.   BaseObjects := GatherMiniMapObjects(BasesToCheck);
  1448.  
  1449.   Len := Length(Path);
  1450.  
  1451.   for H := (Len - 1) downto 0 do
  1452.   begin
  1453.  
  1454.     for I := 0 to High(Path[h]) do
  1455.     begin
  1456.  
  1457.       if (not FindObjDTMEx(Path[h][i], X, Y, GroundLevel, BaseObjects)) then
  1458.         Continue;
  1459.  
  1460.       Found := True;
  1461.       Break;
  1462.     end;
  1463.  
  1464.     if Found then
  1465.       Break;
  1466.   end;
  1467.  
  1468.   if (not Found) then
  1469.     Exit;
  1470.  
  1471.   Mouse(X, Y, 0, 0, True);
  1472.   FFlag(FlagDistance);
  1473.  
  1474.   for I := (H + 1) to (Len - 1) do
  1475.     if (not ObjDTM_MultiWalkEx(Path[h], FlagDistance, PollRate, Tries, GroundLevel, BaseObjects)) then
  1476.       Exit;
  1477.  
  1478.  
  1479.   Result := True;
  1480. end;
  1481.  
  1482. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  1483.  
  1484. procedure ObjectDebug(ObjectToDebug: Integer);
  1485. (*******************************************************************************
  1486. procedure ObjectDebug(ObjectToDebug: Integer);
  1487. By: euphemism
  1488. Last Edit: 2 Dec 2011 -- euphemism
  1489. Description: Locates all instances of the object 'ObjectToDebug', and paints
  1490.              numbered boxes over all instances of the object.  In the debug,
  1491.              the function prints out the information needed to use each
  1492.              found object as a sub-point of an Object DTM.
  1493. *******************************************************************************)
  1494. var
  1495.   I: Integer;
  1496.   BaseString: String;
  1497.   Colors: TIntegerArray;
  1498.   TPA: TPointArray;
  1499.  
  1500. begin
  1501.  
  1502.   case ObjectToDebug of
  1503.  
  1504.     0: BaseString := 'MM_LADDER';
  1505.     1: BaseString := 'MM_TREE';
  1506.     2: BaseString := 'MM_DEADTREE';
  1507.     3: BaseString := 'MM_PLANT';
  1508.     4: BaseString := 'MM_FLAX';
  1509.     5: BaseString := 'MM_BOULDER';
  1510.     6: BaseString := 'MM_HENGE';
  1511.     7: BaseString := 'MM_CACTUS';
  1512.     8: BaseString := 'MM_MAPLE';
  1513.     9: BaseString := 'MM_ROCK';
  1514.   else
  1515.       BaseString := 'MM_OBJECT';
  1516.   end;
  1517.  
  1518.  
  1519.   Colors := [clBlue, clLime, clRed, clYellow]
  1520.  
  1521.   TPA := FindMiniMapObj(MMObjRecords[ObjectToDebug]);
  1522.  
  1523.   {$IFDEF SMART}
  1524.   SMART_DrawBoxEx(True, IntToBox(0, 0, 1, 1), clBlue);
  1525.   {$ENDIF}
  1526.  
  1527.   for I := 0 to High(TPA) do
  1528.   begin
  1529.  
  1530.     {$IFDEF SMART}
  1531.     SMART_DrawBoxEx(False, (IntToBox(TPA[i].x - 3, TPA[i].y - 3, TPA[i].x + 3,
  1532.      TPA[i].y + 3)), Colors[RandomRange(0, 3)]);
  1533.  
  1534.     SMART_DrawTextEx(False, (TPA[I].X - 11), (TPA[I].Y - 3),
  1535.      'SmallChars', IntToStr(I), ClBlue);
  1536.  
  1537.     SMART_DrawTextEx(False, (TPA[I].X - 12), (TPA[I].Y - 4),
  1538.      'SmallChars', IntToStr(I), ClWhite);
  1539.     {$ENDIF}
  1540.  
  1541.     WriteLn('//////////////////////////////////////////////////////');
  1542.     WriteLn('');
  1543.     WriteLn('Minimap object ' + ToStr(I));
  1544.     WriteLn('-----------------------');
  1545.     WriteLn('Skeleton Record:');
  1546.     WriteLn('');
  1547.     WriteLn('  SubPoints[].Base := ' + BaseString + ';');
  1548.     WriteLn('  SubPoints[].Drift := 5;');
  1549.     WriteLn('  SubPoints[].Point.x := ' + IntToStr(TPA[i].x) + ';');
  1550.     WriteLn('  SubPoints[].Point.y := ' + IntToStr(TPA[i].y) + ';');
  1551.     WriteLn('');
  1552.   end;
  1553.     WriteLn('+++++++++++++++++++++++++++++++++++++++++++++++++++++');
  1554.   //end;
  1555. end;
  1556.  
  1557. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  1558.  
  1559. procedure GenerateObjDTMSkeleton(NumberOfSubPoints: Integer; AreaBox: Boolean);
  1560. (*******************************************************************************
  1561. procedure GenerateObjDTMSkeleton(NumberOfSubPoints: Integer; AreaBox: Boolean);
  1562. By: euphemism
  1563. Last Edit: 22 Nov 2011 -- euphemism
  1564. Description: Prints out a skeleton record for an Object DTM with x number of
  1565.              sub-points, where x is 'NumberOfSubPoints', it will also print
  1566.              out the area box code to fill in, if you set 'AreaBox' to true.
  1567. *******************************************************************************)
  1568. var
  1569.   I: Integer;
  1570. begin
  1571.  
  1572.   WriteLn('with DefaultDTM do');
  1573.   WriteLn('begin');
  1574.   WriteLn('');
  1575.   WriteLn('  MainPoint.x := 627;');
  1576.   WriteLn('  MainPoint.y := 85;');
  1577.   WriteLn('');
  1578.   WriteLn('  NumOfPoints := ' + IntToStr(NumberOfSubPoints) + ';');
  1579.   WriteLn('  SetLength(SubPoints, NumOfPoints);');
  1580.   WriteLn('');
  1581.  
  1582.   for I := 0 to (NumberOfSubPoints - 1) do
  1583.   begin
  1584.     WriteLn('  SubPoints[' + IntToStr(i) + '].Base := MM_OBJECT;');
  1585.     WriteLn('  SubPoints[' + IntToStr(i) + '].Drift := 5;');
  1586.     WriteLn('  SubPoints[' + IntToStr(i) + '].Point.x := 0;');
  1587.     WriteLn('  SubPoints[' + IntToStr(i) + '].Point.y := 0;');
  1588.  
  1589.     if I < (NumberOfSubPoints - 1) then
  1590.       WriteLn('');
  1591.   end;
  1592.  
  1593.   if AreaBox then
  1594.   begin
  1595.     WriteLn('');
  1596.     WriteLn('  AreaBox[0].x := 0;');
  1597.     WriteLn('  AreaBox[0].y := 0;');
  1598.     WriteLn('');
  1599.     WriteLn('  AreaBox[1].x :=1;');
  1600.     WriteLn('  AreaBox[1].y :=0;');
  1601.     WriteLn('');
  1602.     WriteLn('  AreaBox[2].x := 0;');
  1603.     WriteLn('  AreaBox[2].y := 1;');
  1604.     WriteLn('');
  1605.     WriteLn('  AreaBox[3].x := 1;');
  1606.     WriteLn('  AreaBox[3].y := 1;');
  1607.   end;
  1608.  
  1609.   WriteLn('end;');
  1610. end;
  1611.  
  1612. {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||}
  1613.  
  1614. function GenerateObjDTM(Objects: TIntegerArray; MainX, MainY: Integer;
  1615.  PrintRecord, SortByMainPoint: Boolean): String;
  1616. (*******************************************************************************
  1617. function GenerateObjDTM(Objects: TIntegerArray; MainX, MainY: Integer;
  1618.  PrintRecord, SortByMainPoint: Boolean): String;
  1619. By: euphemism
  1620. Last Edit: 2 Dec 2011 -- euphemism
  1621. Description: Prints out a useable Object DTM record based on the parameters
  1622.              passed by the user.  Technically, it can make an Object DTM
  1623.              on-the-fly in its current form, but is limited.  Am currently
  1624.              working on a version that is more automated.
  1625. *******************************************************************************)
  1626. var
  1627.   H, I, Used, X, Y: Integer;
  1628.   BaseString: String;
  1629.   Ground: Boolean;
  1630.   Bases, BaseTPA: TPointArray;
  1631.   TestObjDTM: ObjDTM;
  1632. begin
  1633.  
  1634.   {$IFDEF SMART}
  1635.   SMART_DrawBoxEx(True, IntToBox(0, 0, 1, 1), clWhite);
  1636.   {$ENDIF}
  1637.  
  1638.   Used := 0;
  1639.   SetLength(Bases, 1);
  1640.  
  1641.   TestObjDTM.NumOfPoints := Length(Objects);
  1642.   TestObjDTM.NumOfAreaPoints := 0;
  1643.   TestObjDTM.MainPoint := IntToPoint(MainX, MainY);
  1644.   SetLength(TestObjDTM.Area, TestObjDTM.NumOfAreaPoints);
  1645.   SetLength(TestObjDTM.SubPoints, TestObjDTM.NumOfPoints);
  1646.  
  1647.   Ground := GroundLevelCheck;
  1648.  
  1649.   if PrintRecord then
  1650.   begin
  1651.  
  1652.     WriteLn('with ObjectDTM do');
  1653.     WriteLn('begin');
  1654.     WriteLn('');
  1655.     WriteLn('  MainPoint.x := ' + IntToStr(MainX) + ';');
  1656.     WriteLn('  MainPoint.y := ' + IntToStr(MainY) + ';');
  1657.     WriteLn('');
  1658.     WriteLn('  NumOfPoints := ' + IntToStr(Length(Objects)) + ';');
  1659.     WriteLn('  SetLength(SubPoints, NumOfPoints);');
  1660.     WriteLn('');
  1661.   end;
  1662.  
  1663.   for I := 0 to High(Objects) do
  1664.   begin
  1665.  
  1666.     case Objects[i] of
  1667.  
  1668.       0: BaseString := 'MM_LADDER';
  1669.       1: BaseString := 'MM_TREE';
  1670.       2: BaseString := 'MM_DEADTREE';
  1671.       3: BaseString := 'MM_PLANT';
  1672.       4: BaseString := 'MM_FLAX';
  1673.       5: BaseString := 'MM_BOULDER';
  1674.       6: BaseString := 'MM_HENGE';
  1675.       7: BaseString := 'MM_CACTUS';
  1676.       8: BaseString := 'MM_MAPLE';
  1677.       9: BaseString := 'MM_ROCK';
  1678.     end;
  1679.  
  1680.     BaseTPA := FindMiniMapObj(MMObjRecords[Objects[i]]);
  1681.  
  1682.     if SortByMainPoint then
  1683.       SortTPAFrom(BaseTPA, IntToPoint(MainX, MainY))
  1684.     else
  1685.       SortTPAFrom(BaseTPA, IntToPoint(MMCX, MMCY));
  1686.  
  1687.     if Length(BaseTPA) = 0 then
  1688.     begin
  1689.       WriteLn('No instances of ' + BaseString + ' were found on the minimap!' +
  1690.        '  Please specify visible objects.');
  1691.       Exit;
  1692.     end;
  1693.  
  1694.     for H := 0 to High(BaseTPA) do
  1695.     begin
  1696.  
  1697.       if not PointInTPA(BaseTPA[h], Bases) then
  1698.       begin
  1699.         Bases[Used] := BaseTPA[h];
  1700.         SetLength(Bases, Length(Bases) + 1);
  1701.         Inc(Used);
  1702.         Break;
  1703.       end;
  1704.     end;
  1705.  
  1706.     TestObjDTM.SubPoints[i].Point := BaseTPA[h];
  1707.     TestObjDTM.SubPoints[i].Drift := 7;
  1708.     TestObjDTM.SubPoints[i].Base := Objects[i];
  1709.  
  1710.     if PrintRecord then
  1711.     begin
  1712.  
  1713.       WriteLn('  SubPoints[' + IntToStr(i) + '].Base := ' + BaseString + ';');
  1714.       WriteLn('  SubPoints[' + IntToStr(i) + '].Drift := 7;');
  1715.       WriteLn('  SubPoints[' + IntToStr(i) + '].Point.x := ' +
  1716.        IntToStr(BaseTPA[h].x) + ';');
  1717.       WriteLn('  SubPoints[' + IntToStr(i) + '].Point.y := ' +
  1718.        IntToStr(BaseTPA[h].y) + ';');
  1719.     end;
  1720.  
  1721.     {$IFDEF SMART}
  1722.     SMART_DrawBoxEx(False, IntToBox(BaseTPA[h].x - 5, BaseTPA[h].y - 5,
  1723.      BaseTPA[h].x + 5, BaseTPA[h].y + 5), clWhite);
  1724.     {$ENDIF}
  1725.  
  1726.     if i < (Length(Objects) - 1) then
  1727.       WriteLn('');
  1728.   end;
  1729.  
  1730.   if PrintRecord then
  1731.     WriteLn('end;');
  1732.   if PrintRecord then
  1733.     WriteLn('');
  1734.  
  1735.   Result := ObjDTMToString(TestObjDTM);
  1736.   WriteLn(#39 + Result + #39);
  1737.  
  1738.   if PrintRecord then
  1739.     WriteLn('');
  1740.  
  1741.   if FindObjDTM(Result, X, Y, Ground) then
  1742.   begin
  1743.  
  1744.     MMouse(X, Y, 0, 0);
  1745.     WriteLn('Object DTM Include: This is a working object DTM.');
  1746.   end else
  1747.     WriteLn('ObjectDTM Include: This object DTM failed.');
  1748. end;
  1749.  
  1750. procedure PrintObjDTMRecFromString(ObjectDTMString: String);
  1751. (*******************************************************************************
  1752. function GenerateObjDTM(Objects: TIntegerArray; MainX, MainY: Integer;
  1753.  PrintRecord, SortByMainPoint: Boolean): String;
  1754. By: euphemism
  1755. Last Edit: 2 Dec 2011 -- euphemism
  1756. Description: Prints out a useable Object DTM record based on the parameters
  1757.              passed by the user.  Technically, it can make an Object DTM
  1758.              on-the-fly in its current form, but is limited.  Am currently
  1759.              working on a version that is more automated.
  1760. *******************************************************************************)
  1761. var
  1762.   I: Integer;
  1763.   BaseString: String;
  1764.   TestObjDTM: ObjDTM;
  1765. begin
  1766.  
  1767.   TestObjDTM := ObjDTMFromString(ObjectDTMString);
  1768.  
  1769.   WriteLn('Object DTM string converted to record form:');
  1770.   WriteLn('');
  1771.   WriteLn('-------------------------------------------');
  1772.   WriteLn('');
  1773.  
  1774.   WriteLn('with ObjectDTM do');
  1775.   WriteLn('begin');
  1776.   WriteLn('');
  1777.   WriteLn('  MainPoint.x := ' + IntToStr(TestObjDTM.MainPoint.x) + ';');
  1778.   WriteLn('  MainPoint.y := ' + IntToStr(TestObjDTM.MainPoint.y) + ';');
  1779.   WriteLn('');
  1780.   WriteLn('  NumOfPoints := ' + IntToStr(TestObjDTM.NumOfPoints) + ';');
  1781.   WriteLn('  SetLength(SubPoints, NumOfPoints);');
  1782.   WriteLn('');
  1783.  
  1784.   for I := 0 to (TestObjDTM.NumOfPoints - 1) do
  1785.   begin
  1786.  
  1787.   case TestObjDTM.SubPoints[i].Base of
  1788.  
  1789.     0: BaseString := 'MM_LADDER';
  1790.     1: BaseString := 'MM_TREE';
  1791.     2: BaseString := 'MM_DEADTREE';
  1792.     3: BaseString := 'MM_PLANT';
  1793.     4: BaseString := 'MM_FLAX';
  1794.     5: BaseString := 'MM_BOULDER';
  1795.     6: BaseString := 'MM_HENGE';
  1796.     7: BaseString := 'MM_CACTUS';
  1797.     8: BaseString := 'MM_MAPLE';
  1798.     9: BaseString := 'MM_ROCK';
  1799.   end;
  1800.  
  1801.   WriteLn('  SubPoints[' + IntToStr(i) + '].Base := ' +
  1802.   BaseString + ';');
  1803.  
  1804.   WriteLn('  SubPoints[' + IntToStr(i) + '].Drift :=' +
  1805.   IntToStr(TestObjDTM.SubPoints[i].Drift) + ';');
  1806.  
  1807.   WriteLn('  SubPoints[' + IntToStr(i) + '].Point.x := ' +
  1808.   IntToStr(TestObjDTM.SubPoints[i].Point.x) + ';');
  1809.  
  1810.   WriteLn('  SubPoints[' + IntToStr(i) + '].Point.y := ' +
  1811.   IntToStr(TestObjDTM.SubPoints[i].Point.y) + ';');
  1812.  
  1813.   WriteLn('');
  1814.   end;
  1815.  
  1816.   WriteLn('  NumOfAreaPoints := ' + IntToStr(TestObjDTM.NumOfAreaPoints) + ';');
  1817.   WriteLn('  SetLength(Area, NumOfAreaPoints);');
  1818.   WriteLn('');
  1819.  
  1820.   for I := 0 to (TestObjDTM.NumOfAreaPoints - 1) do
  1821.   begin
  1822.  
  1823.     WriteLn('  Area[' + IntToStr(i) + '].x := ' + IntToStr(TestObjDTM.Area[i].x)
  1824.      + ';');
  1825.     WriteLn('  Area[' + IntToStr(i) + '].y := ' + IntToStr(TestObjDTM.Area[i].y)
  1826.      + ';');
  1827.  
  1828.     if ( I <> (TestObjDTM.NumOfAreaPoints - 1)) then
  1829.       WriteLn('');
  1830.   end;
  1831.  
  1832.   WriteLn('end;');
  1833. end;
Advertisement
Add Comment
Please, Sign In to add comment