Simba Code:
(*
Drill Demon
===========
Stores all the routines to solve the Drill Demon random. None of these routines
should be used throughout scripts. They only need to be called in SRL's random
detection methods.
This solver uses BMPs and DTMs to locate the signs
to solve the Drill Demon (Sergeant Damien) random.
Original Author : DannyRS
Edits Made By :
*)
procedure DD_Message(Message: string);
begin
addToSRLLog('[DemonDrill Random] ' + Message);
end;
function DD_Detect(): boolean;
begin
if (not TabExists(TAB_OPTIONS)) and (not TabExists(TAB_EMOTES)) then
Result := (GetMusic = 'CorPoral Punisbment');
end;
(**
* Author: Coh3n
* Description: Returns a TBox of the exercise area on the minimap. It finds the
* distance from the player to each side of the exercise area. Saves the
* distance and points in arrays. It then uses those arrays to calculate the
* top left and bottom right corners of the exercise area.
*)
function DD_GetExerciseArea(var exerciseArea: TBox): boolean;
var
i, c, t, w, h, distFound: integer;
dist: array[0..3] of integer;
area: array[0..3] of TBox;
tpa: array[0..3] of TPoint;
begin
if (not loggedIn()) then
exit;
t := (getSystemTime + 15000);
repeat
inc(c);
// search areas for each direction (only one pixel at a time)
area[0] := intToBox(MMCX, MMCY - 1 - c, MMCX, MMCY - 1 - c); // north
area[1] := intToBox(MMCX + 1 + c, MMCY, MMCX + 1 + c, MMCY); // east
area[2] := intToBox(MMCX, MMCY + 1 + c, MMCX, MMCY + 1 + c); // south
area[3] := intToBox(MMCX - 1 - c, MMCY, MMCX - 1 - c, MMCY); // west
//Above is buggy as hell atm :/ - Danny
if ((MMCY - 1 - c) > MMY1) or ((MMCX - 1 - c) > MMX1) or
((MMCY + 1 + c) > MMY2) or ((MMCX + 1 + c) > MMX2) then
Exit;
// loop through each area (i.e. direction) to get the distance from the player to the fence on the MM
for i := 0 to high(area) do
if (dist[i] = 0) then
// the white color of the fence
if (findColorTolerance(tpa[i].x, tpa[i].y, 15068652, area[i].x1, area[i].y1, area[i].x2, area[i].y2, 25)) then
begin
dist[i] := distance(tpa[i].x, tpa[i].y, MMCX, MMCY);
inc(distFound);
end;
// if all 4 distances are found
if (distFound = 4) then
begin
// calculate the top left and bottom right of the exercise box
exerciseArea.x1 := tpa[3].x;
exerciseArea.y1 := tpa[3].y - dist[0];
exerciseArea.x2 := tpa[1].x;
exerciseArea.y2 := tpa[1].y + dist[2];
//SMART_DrawBox(exerciseArea);
w := (exerciseArea.x2 - exerciseArea.x1);
h := (exerciseArea.y2 - exerciseArea.y1);
//writeln('w: '+toStr(w)+', h: '+toStr(h));
// sometimes the Drill Demon is standing right inline with the player, causing the next white line to be found on the edge of the MM
result := (inRange(35, w - 7, w + 7) and inRange(20, h - 5, h + 5));
end;
until(result or (getSystemTime > t));
end;
function DD_ResetPosition: boolean;
var
exerciseArea: TBox;
p: TPoint;
begin
if (not loggedIn()) then
exit;
if (DD_GetExerciseArea(exerciseArea)) then
begin
p := middleBox(exerciseArea);
mouse(p.x, p.y + 5, 2, 2, mouse_Left);
Result := True;
end;
end;
function DD_TalkingToDemon: Boolean;
begin
Result := (Trim(GetNPCChatName) = 'SergeantDamien');
end;
function DD_TalkDemon: Boolean;
var
DemonTPA: TPointArray;
DemonATPA: T2DPointArray;
x, y, i: Integer;
begin
Result := False;
if (DD_TalkingToDemon) then
begin
Result := True;
Exit;
end;
SetColorToleranceSpeed(2);
SetToleranceSpeed2Modifiers(0.15, 1.61);
FindColorsTolerance(DemonTPA, 994406, MSX1, MSY1, MSX2, MSY2, 16);
SplitTPAExWrap(DemonTPA, 50, 100, DemonATPA);
SortATPASize(DemonATPA, True);
if (Length(DemonATPA) < 1) then Exit;
for i := 0 to High(DemonATPA) do
begin
if (Length(DemonATPA[i]) < 50) then Continue;
MiddleTPAEx(DemonATPA[i], x, y);
MMouse(RandomRange(x - 5, x + 5), RandomRange(y - 5, y + 5), 0, 0);
ClickMouse2(mouse_right);
if (ChooseOptionMulti(['Talk','alk-to'])) then
begin
if (WaitFunc(@DD_TalkingToDemon, 50, 25000)) then
begin
DD_Message('[DD_TalkDemon] Talked to demon');
Result := True;
Exit;
end else
DD_Message('[DD_TalkDemon] Failed to Talked to demon');
end;
end;
end;
function DD_GetSigns: TBoxArray;
var
ESignsTPA: TPointArray;
ESignsATPA: T2DPointArray;
SignsSorted: Boolean;
i: Integer;
begin
SetColorToleranceSpeed(1);
FindColors(ESignsTPA, 4553552, MSX1, MSY1, MSX2, MSY2);
SplitTPAExWrap(ESignsTPA, 20, 30, ESignsATPA);
repeat
SignsSorted := True;
for i := 0 to High(ESignsATPA) do
begin
if (Length(ESignsATPA[i]) < 5) then
begin
DeleteValueInATPA(ESignsATPA,i);
SignsSorted := False;
Break;
end;
end;
until (SignsSorted);
SetLength(Result, Length(ESignsATPA));
for i := 0 to high(ESignsATPA) do
begin
Result[i] := GetTPABounds(ESignsATPA[i]);
end;
end;
function DD_FindSign(WhichSign: String): TPoint;
var
SB: TBoxArray;
x, y, i, SBMP: Integer;
Saccuracy: Extended;
begin
Result := Point(-1, -1);
SB := DD_GetSigns;
SetColorToleranceSpeed(1);
SetToleranceSpeed2Modifiers(0.02, 0.02);
case LowerCase(WhichSign) of
'jog': SBMP := BitmapFromString(29, 10, 'meJxzrQ5wJRrF9ZUSr3gwGItsMh' +
'qXbJQ5qxGI4EZRxViImRBjIaZRbizcTGR3UmgsmpnUCltcxlIrVKl' +
'rLNxk4tUDAIc3Qs8=');
'starjumps': SBMP := BitmapFromString(37, 16, 'meJxzrQ5wJR3F9ZXCERnacaHs+S' +
'34raOiXXAbIYjqJhNjKfGIPjbSx5t0C1U6RyI97Ro21tEtNdLHOuR' +
'iCtN8qtuIXDBiNZlGHgQiXMbSIgbh1uGJUyKrJAA7N7QN');
'situps': SBMP := BitmapFromString(37, 16, 'meJxzrQ5wHRwoe34LENHTLgqtI1' +
'473DqybSReL7Jd5FlHkl4060i1kSSNmHaRZB2pepGVkWojmnqCGtE' +
'MpyRYiLcOf8ASg4hJMJiyZFsX11cKRMhcuJkQKbgswWRDpF3I1mHa' +
'BZElJpUSaRcEkZSDyLCRVPOHEwIAf3vRcQ==');
'pushups': SBMP := BitmapFromString(43, 16, 'meJxzrQ5wBaO4vlI4coUJ0hMhO2' +
'Cg3ICJsue3ANHA2o6MBtZ2OjuGoANo6hhMk+npBjxm0scNBE2jaWg' +
'QbwiNkgcZuqiSVuEFICUBOLAZh57phFqOoacb0OJ6AK3GtB0AjuAl' +
'9Q==');
end;
for i := 0 to High(SB) do
begin
if FindDeformedBitmapToleranceIn(SBMP, x, y, SB[i].X1-5, SB[i].Y1-5,
SB[i].X2+5, SB[i].Y2+5, 2, 4, False, Saccuracy) then
begin
if (SB[i].X1 > SB[i].X2) or (SB[i].Y1 > SB[i].Y2) then Break;
Result := Point(x + 20, y + 7);
Break;
end;
end;
FreeBitmap(SBMP);
end;
function DD_Solve(): boolean;
var
p: TPoint;
t, tmpCTS, MMoves: Integer;
tmpHM, tmpSM: Extended;
MatName: String;
ClickedMat: Boolean;
begin
Result := False;
if (not LoggedIn) then Exit;
t := GetSystemTime;
tmpCTS := GetColorToleranceSpeed;
GetToleranceSpeed2Modifiers(tmpHM, tmpSM);
SetAngle(SRL_ANGLE_LOW);
MakeCompass('N');
repeat
Result := TabExists(TAB_MAGIC);
if (Result) then Exit;
if (not DD_TalkDemon) then
begin
DD_ResetPosition;
Continue;
end;
Wait(RandomRange(1200, 1600));
case CountColor(0, MCX1, MCY1, MCX2, MCY2) of
687,988 : MatName := 'jog';
707 : MatName := 'starjumps';
569 : MatName := 'situps';
637,938 : MatName := 'pushups';
else
begin
ClickToContinue;
Continue;
end;
end;
DD_Message('[DD_Solve] Walking to center');
if (not DD_ResetPosition) then
begin
DD_Message('[ERROR] Failed to walk to center');
Continue;
end;
DD_Message('[DD_Solve] Searching for sign : ' + MatName);
p := DD_FindSign(MatName);
if (p.x < 0) or (p.y < 0) then
begin
DD_Message('[ERROR] Failed to find sign : ' + MatName);
Continue;
end;
ClickedMat:= False;
MMoves := 0;
DD_Message('[DD_Solve] Searching for matt : ' + MatName);
repeat
MMouse(p.x, p.y + 64, 40, 20);
MMoves := MMoves + 1;
Wait(RandomRange(90, 340));
if (IsUpTextMultiCustom(['Use','xercise','mat'])) then
begin
ClickMouse2(mouse_right);
if (ChooseOptionMulti(['Use'])) then
begin
Wait(RandomRange(1200, 1500));
if (WaitFunc(@DD_TalkingToDemon, 50, 15000)) then
begin
DD_Message('[DD_Solve] Used Matt');
ClickedMat := True;
Break;
end else
begin
DD_Message('[DD_Solve] Failed to Use Matt');
Continue;
end;
end;
end;
until (ClickedMat) or (MMoves > 10);
Result := TabExists(TAB_MAGIC);
until (Result) or (GetSystemTime - t > 240000);
if (not Result) then
begin
if (GetSystemTime - t > 240000) then
DD_Message('[ERROR] DrillDemon solver timed out');
end else
Wait(RandomRange(1200, 1600));
end;