Flight
07-27-2013, 04:55 AM
I've had these up and running for a while but because they're only seen in Monkfishies & Al-Kharid Cooker not many people have been utilizing them. So here's a set of modifications I've made to our current anti-randoms as well as a few new ones that scripters might find handy.
[Note] All modifications are done in 'antirandoms.simba' (Includes > SRL-OSR > SRL > core > antirandoms > antirandoms.simba)
-Solving the Frog random-
First you'll want to define this DTM as a global variable:
Var
DTM_Royal_Frog: Integer;
Create a procedure we'll use later on to free this DTM:
Procedure FreeCRGlobals;
begin
FreeDTM(DTM_Royal_Frog);
end;
Create a procedure to define the DTM:
Procedure SetupCustomRandoms;
begin
DTM_Royal_Frog := DTMFromString('mbQAAAHicY2VgYLgDxLeB+CYQ34OyeRgZGD gZIbQAEPMD8cpOYYbfZ1QZDs4RYziuKcbw+5wxgxxQLTpmxoLB AAB7VQzf');
AddOnTerminate('FreeCRGlobals');
end;
That's so the DTM is only defined one time and is also freed when the script stops.
And the actual frog-solving function:
(**
* Author: Flight
* Description: Handles solving the random event.
*)
function Frog_Solve2: Boolean;
var
cRan: Boolean;
t,i,F,X,Y: Integer;
responses: TStringArray;
label
Start;
begin
Start:
cRan := false;
responses := ['lrigh','Okay','kay.','I supp','pose so','yeah','Yeah','Sure','ure'];
for i:=1 to 5 do
if FindDTM(DTM_Royal_Frog, X, Y, MSx1, MSy1, MSx2, MSy2) then
begin
MMouse(X, Y, 0, 0);
if WaitUpTextMulti(['Frog','to Fr'], 300) then
begin
Writeln('Frog_Solve2: Found royal frog');
ClickMouse2(mouse_right);
Wait(randomRange(100,250));
cRan := waitOptionMulti(['Talk-to Frog','to Fr','Frog'], 500);
if cRan then
break
else
MouseBox(MCx1, MCy1, MCx2, MCy2, mouse_move);
end;
end;
if not cRan then
begin
Writeln('Frog_Solve2: Failed to locate the royal frog, exiting');
Exit;
end;
Writeln('Frog_Solve2: Talking to royal frog...');
if not waitFunc(@areTalking, 10, 6000) then
begin
Inc(F);
if (F > 4) then
begin
Writeln('Frog_Solve2: Failed to talk to the royal frog, exiting');
Exit;
end;
GoTo Start;
end;
MarkTime(t)
repeat
if DoConversationEx(responses) then
begin
Writeln('Frog_Solve2: Reached response');
for i:=0 to High(responses) do
if findTextTPA(0, 5, MCx1, MCy1, MCx2, MCy2, responses[i], CharsNPC07, ClickLeft) then
begin
Writeln('Frog_Solve2: Chose correct option');
ClickToContinue;
break;
end;
end;
until(timeFromMark(t) > 15000)
MarkTime(t)
repeat
if ClickContinueEx(True, True) then
break;
until(timeFromMark(t) > 10000)
Result := True;
Writeln('Frog_Solve2: Successfully solved the Frog random!');
end;
And for that to work you're going to need a function similar to DoConversation but one that will search for an array of text. Luckily I made one already for you to use, so define this as well:
(*
DoConversationEx
~~~~~~~~~~~~~~
.. code-block:: pascal
function DoConversationEx(resultText: TStringArray; clickresult: boolean): boolean;
Goes through the initial dialog of a random. Will keep clicking to continue
until any of the conversation's 'resultText' is found. Will click to continue when
any 'resultText' is found if 'clickresult' is set to true. Set 'resultText' to ['']
to click continue until conversation is over.
.. note::
Author: Coh3n, Flight
Last Modified: Jun. 15th, 2013 by Flight
Example:
.. code-block:: pascal
if (DoConversationEx(['thank','nk you'], true)) then
writeln('Finished conversation');
*)
function DoConversationEx(resultText: TStringArray): boolean;
var
t,i: integer;
begin
while (t < 25) do // max of 25 "click to continue's"
begin
if (length(resultText) > 0) then
for i:=0 to high(resultText) do
if (findNPCChatText(resultText[i], nothing)) then
begin
result := true;
exit;
end;
// break if there's no more conversation
if (not clickContinue(true)) then
break;
wait(100 + random(200));
inc(t);
end;
end;
For this random to be detected and handled correctly you'll need to stick it in your 'FindTalk' function so that when your player's nickname is detected on screen you'll first search for the DTM_Royal_Frog, and if it's found then FindTalk will skip the right-click "Talk-to" and instead attempt to solve the Frog random. I've made an example (which I'll post below) of how to go about doing this.
-A safer way to handle talking randoms-
A problem I found pretty quickly is when FindTalk finds a random NPC that says our name, and that same random that we need to talk to is standing in in the same tile as another NPC with the "Talk-to" option, there's a good chance we talk to the wrong NPC and fail the random event. So we should be more specific on our "Talk-to" option when handling all random events. Here's what I've done to prevent such a thing from happening:
{************************************************* ******************************
function FindTalk: Boolean;
by: Ashaman88 & Flight
Description: Searches screen for NickName and handles ALL Talking Randoms
************************************************** *****************************}
function FindTalk: Boolean;
var
ax,ay,yCount,zCount,Count2,x1,y1,x2,y2,
X,Y,Count1,bmpScreen: Integer;
RawMenuText: String;
rTalkStrings: TStringArray;
begin
Result := False;
if (GetArrayLength(Players) < 1) then Exit;
if FindColor(ax, ay, 65535, MSX1, MSY1, MSX2, MSY2) then
begin
SetArrayLength(gtalksBox, 0);
SetArrayLength(YelSkipBoxs, 0);
y1 := ay;
if ( ( ay + 5 ) > 334 ) then y2 := 334 else y2 := ay + 5;
x1 := ax; x2 := x1;
zCount := 0;
repeat
if FindColor(ax, ay, 65535, x2, y1 + 2, x2 + 3, y2 + 3) then
zCount := 0
else
zCount := zCount + 1;
if ( zCount = 4 ) then Break;
x2 := x2 + 3;
until ( x2 + 3 > 515 );
if ( x2 + 3 <= 515 ) then x2 := x2 - 12;
if (x2 - x1 >= length(Players[CurrentPlayer].Nick) * 4) then
begin
x1 := x1 - 8;
y1 := y1 - 8;
x2 := x2 + 8;
y2 := y2 + 8;
if ( x1 < 0 ) then x1 := 0;
if ( y1 < 0 ) then y1 := 0;
if ( x2 > 515 ) then x2 := 515;
if ( y2 > 334 ) then y2 := 334;
Count2 := Count2 + 1;
Count1 := Count1 + 1;
SetArrayLength(gtalksBox, Count2);
gtalksBox[Count2 - 1].x1 := x1;
gtalksBox[Count2 - 1].y1 := y1;
gtalksBox[Count2 - 1].x2 := x2;
gtalksBox[Count2 - 1].y2 := y2 + 6;
SetArrayLength(YelSkipBoxs, Count1);
YelSkipBoxs[Count1 - 1].x1 := x1;
YelSkipBoxs[Count1 - 1].y1 := y1;
YelSkipBoxs[Count1 - 1].x2 := x2;
YelSkipBoxs[Count1 - 1].y2 := y2;
end else
begin
y1 := y1 - 2;
y2 := y2 + 8;
x1 := x1 - 5;
x2 := x2 + 5;
if ( x1 < 0 ) then x1 := 0;
if ( y1 < 0 ) then y1 := 0;
if ( x2 > 515 ) then x2 := 515;
if ( y2 > 334 ) then y2 := 334;
Count1 := Count1 + 1;
SetArrayLength(YelSkipBoxs, Count1);
YelSkipBoxs[Count1 - 1].x1 := x1;
YelSkipBoxs[Count1 - 1].y1 := y1;
YelSkipBoxs[Count1 - 1].x2 := x2;
YelSkipBoxs[Count1 - 1].y2 := y2;
end;
if ( GetArrayLength(gtalksBox) <> 0 ) then
begin
for yCount := 0 to GetArrayLength(gtalksBox) - 1 do
begin
if FindBitmapMaskTolerance(NickNameBMP, ax, ay, gtalksBox[yCount].x1, gtalksBox[yCount].y1, gtalksBox[yCount].x2, gtalksBox[yCount].y2, 0, 40) then
begin
WriteLn('Found NickName');
ax := (gtalksBox[yCount].x2 + gtalksBox[yCount].x1) shr 1;
ay := gtalksBox[yCount].y2 - 2;
if gTalkSaveBitmap then
begin
bmpScreen := BitmapFromString(515, 334, '');
CopyClientToBitmap(bmpScreen, 1, 1, 515, 334);
if ( gtalksBox[yCount].x1 = 0 ) then x1 := 1 else x1 := gtalksBox[yCount].x1;
if ( gtalksBox[yCount].y1 = 0 ) then y1 := 1 else y1 := gtalksBox[yCount].y1;
gTalksCount := gTalksCount + 1;
for Count1 := -1 to 1 do
for Count2 := -1 to 1 do
FastSetPixel(bmpScreen, Count1 + x1, Count2 + y1, 255);
if ( gtalksBox[yCount].x2 = 515 ) then x1 := 515 else x1 := gtalksBox[yCount].x2;
if ( gtalksBox[yCount].y2 = 334 ) then y1 := 334 else y1 := gtalksBox[yCount].y2;
for Count1 := -1 to 1 do
for Count2 := -1 to 1 do
FastSetPixel(bmpScreen, Count1 + x1, Count2 + y1, 255);
for Count1 := -1 to 1 do
for Count2 := -1 to 1 do
FastSetPixel(bmpScreen, Count1 + ax, Count2 + ay, 255);
SaveBitmap(bmpScreen, ScriptPath + 'FTalk' + IntToStr(gTalksCount) + '.bmp');
FreeBitmap(bmpScreen);
end;
if not FindDTM(DTM_Royal_Frog, X, Y, MSx1, MSy1, MSx2, MSy2) then
begin
MMouse(ax, ay, 0, 0);
Wait(100 + Random(50));
if WaitUpTextMulti(['Talk','lk-to','uard','ard','security','ecurity','curity'], RandomRange(150,300)) then
begin
Mouse(ax, ay, 0, 0, mouse_Right);
Wait(150 + Random(100));
rTalkStrings := ['o Sec','o San','o Gen','o Mil','o Gil','o Nil','o Ric',
'o Dru','o Cap','o Mys','o Dr'];
if (ChooseOptiongetMenuText(RawMenuText, rTalkStrings, ClickLeft)) then
begin
WriteLn('******** FOUND TALKING RANDOM TEXT********: ' + RawMenuText);
Flag;
Wait(700 + Random(300))
if SolveTalkingRandom(RawMenuText) then
Result := True;
Exit;
end;
end;
end else
begin
WriteLn('******** SOLVING FROG RANDOM ********');
if Frog_Solve2 then
Result := True;
Exit;
end;
end;
end;
end;
end;
end;
The above modified function also correctly detects & handles the Frog random event, if you've already installed what I've written above.
Anyways, I'll attach a file already containing all of the modifications if you don't feel like doing them yourself. If you're just using C_AntiRandoms from this post then you'll need to know a couple things. First, download the attached file and place it in "Includes > SRL-OSR > SRL > core > antirandoms". You'll want to include it in your script like so:
{$i SRL-OSR/SRL/core/antirandoms/C_AntiRandoms.simba}
Also you'll need to call "SetupCustomRandoms;" after you've called "SetupSRL;". From now on you'll be using "FindCustomRandoms" as opposed to "FindNormalRandoms".
{$i SRL-OSR/SRL.Simba}
{$i SRL-OSR/SRL/core/antirandoms/C_AntiRandoms.simba}
Procedure declarePlayers;
begin
HowManyPlayers := 1;
NumberOfPlayers(HowManyPlayers);
CurrentPlayer := 0;
with Players[0] do
begin
Name := '';
Pass := '';
Nick := 'nick'; // DO NOT FORGET THIS!
Pin := '';
LampSkill := Skill_Herblore;
WorldInfo := [];
Member := True;
Active := True;
end;
end;
begin
declarePlayers;
SetupSRL;
SetupCustomRandoms;
Repeat
Writeln('Searching for random events...');
FindCustomRandoms;
Until(AllPlayersInactive)
end.
That's all I have so far for the core anti-randoms. I have some detection & handling for others but they're more specific to the script so it wouldn't be appropriate to post them here.
[Note] All modifications are done in 'antirandoms.simba' (Includes > SRL-OSR > SRL > core > antirandoms > antirandoms.simba)
-Solving the Frog random-
First you'll want to define this DTM as a global variable:
Var
DTM_Royal_Frog: Integer;
Create a procedure we'll use later on to free this DTM:
Procedure FreeCRGlobals;
begin
FreeDTM(DTM_Royal_Frog);
end;
Create a procedure to define the DTM:
Procedure SetupCustomRandoms;
begin
DTM_Royal_Frog := DTMFromString('mbQAAAHicY2VgYLgDxLeB+CYQ34OyeRgZGD gZIbQAEPMD8cpOYYbfZ1QZDs4RYziuKcbw+5wxgxxQLTpmxoLB AAB7VQzf');
AddOnTerminate('FreeCRGlobals');
end;
That's so the DTM is only defined one time and is also freed when the script stops.
And the actual frog-solving function:
(**
* Author: Flight
* Description: Handles solving the random event.
*)
function Frog_Solve2: Boolean;
var
cRan: Boolean;
t,i,F,X,Y: Integer;
responses: TStringArray;
label
Start;
begin
Start:
cRan := false;
responses := ['lrigh','Okay','kay.','I supp','pose so','yeah','Yeah','Sure','ure'];
for i:=1 to 5 do
if FindDTM(DTM_Royal_Frog, X, Y, MSx1, MSy1, MSx2, MSy2) then
begin
MMouse(X, Y, 0, 0);
if WaitUpTextMulti(['Frog','to Fr'], 300) then
begin
Writeln('Frog_Solve2: Found royal frog');
ClickMouse2(mouse_right);
Wait(randomRange(100,250));
cRan := waitOptionMulti(['Talk-to Frog','to Fr','Frog'], 500);
if cRan then
break
else
MouseBox(MCx1, MCy1, MCx2, MCy2, mouse_move);
end;
end;
if not cRan then
begin
Writeln('Frog_Solve2: Failed to locate the royal frog, exiting');
Exit;
end;
Writeln('Frog_Solve2: Talking to royal frog...');
if not waitFunc(@areTalking, 10, 6000) then
begin
Inc(F);
if (F > 4) then
begin
Writeln('Frog_Solve2: Failed to talk to the royal frog, exiting');
Exit;
end;
GoTo Start;
end;
MarkTime(t)
repeat
if DoConversationEx(responses) then
begin
Writeln('Frog_Solve2: Reached response');
for i:=0 to High(responses) do
if findTextTPA(0, 5, MCx1, MCy1, MCx2, MCy2, responses[i], CharsNPC07, ClickLeft) then
begin
Writeln('Frog_Solve2: Chose correct option');
ClickToContinue;
break;
end;
end;
until(timeFromMark(t) > 15000)
MarkTime(t)
repeat
if ClickContinueEx(True, True) then
break;
until(timeFromMark(t) > 10000)
Result := True;
Writeln('Frog_Solve2: Successfully solved the Frog random!');
end;
And for that to work you're going to need a function similar to DoConversation but one that will search for an array of text. Luckily I made one already for you to use, so define this as well:
(*
DoConversationEx
~~~~~~~~~~~~~~
.. code-block:: pascal
function DoConversationEx(resultText: TStringArray; clickresult: boolean): boolean;
Goes through the initial dialog of a random. Will keep clicking to continue
until any of the conversation's 'resultText' is found. Will click to continue when
any 'resultText' is found if 'clickresult' is set to true. Set 'resultText' to ['']
to click continue until conversation is over.
.. note::
Author: Coh3n, Flight
Last Modified: Jun. 15th, 2013 by Flight
Example:
.. code-block:: pascal
if (DoConversationEx(['thank','nk you'], true)) then
writeln('Finished conversation');
*)
function DoConversationEx(resultText: TStringArray): boolean;
var
t,i: integer;
begin
while (t < 25) do // max of 25 "click to continue's"
begin
if (length(resultText) > 0) then
for i:=0 to high(resultText) do
if (findNPCChatText(resultText[i], nothing)) then
begin
result := true;
exit;
end;
// break if there's no more conversation
if (not clickContinue(true)) then
break;
wait(100 + random(200));
inc(t);
end;
end;
For this random to be detected and handled correctly you'll need to stick it in your 'FindTalk' function so that when your player's nickname is detected on screen you'll first search for the DTM_Royal_Frog, and if it's found then FindTalk will skip the right-click "Talk-to" and instead attempt to solve the Frog random. I've made an example (which I'll post below) of how to go about doing this.
-A safer way to handle talking randoms-
A problem I found pretty quickly is when FindTalk finds a random NPC that says our name, and that same random that we need to talk to is standing in in the same tile as another NPC with the "Talk-to" option, there's a good chance we talk to the wrong NPC and fail the random event. So we should be more specific on our "Talk-to" option when handling all random events. Here's what I've done to prevent such a thing from happening:
{************************************************* ******************************
function FindTalk: Boolean;
by: Ashaman88 & Flight
Description: Searches screen for NickName and handles ALL Talking Randoms
************************************************** *****************************}
function FindTalk: Boolean;
var
ax,ay,yCount,zCount,Count2,x1,y1,x2,y2,
X,Y,Count1,bmpScreen: Integer;
RawMenuText: String;
rTalkStrings: TStringArray;
begin
Result := False;
if (GetArrayLength(Players) < 1) then Exit;
if FindColor(ax, ay, 65535, MSX1, MSY1, MSX2, MSY2) then
begin
SetArrayLength(gtalksBox, 0);
SetArrayLength(YelSkipBoxs, 0);
y1 := ay;
if ( ( ay + 5 ) > 334 ) then y2 := 334 else y2 := ay + 5;
x1 := ax; x2 := x1;
zCount := 0;
repeat
if FindColor(ax, ay, 65535, x2, y1 + 2, x2 + 3, y2 + 3) then
zCount := 0
else
zCount := zCount + 1;
if ( zCount = 4 ) then Break;
x2 := x2 + 3;
until ( x2 + 3 > 515 );
if ( x2 + 3 <= 515 ) then x2 := x2 - 12;
if (x2 - x1 >= length(Players[CurrentPlayer].Nick) * 4) then
begin
x1 := x1 - 8;
y1 := y1 - 8;
x2 := x2 + 8;
y2 := y2 + 8;
if ( x1 < 0 ) then x1 := 0;
if ( y1 < 0 ) then y1 := 0;
if ( x2 > 515 ) then x2 := 515;
if ( y2 > 334 ) then y2 := 334;
Count2 := Count2 + 1;
Count1 := Count1 + 1;
SetArrayLength(gtalksBox, Count2);
gtalksBox[Count2 - 1].x1 := x1;
gtalksBox[Count2 - 1].y1 := y1;
gtalksBox[Count2 - 1].x2 := x2;
gtalksBox[Count2 - 1].y2 := y2 + 6;
SetArrayLength(YelSkipBoxs, Count1);
YelSkipBoxs[Count1 - 1].x1 := x1;
YelSkipBoxs[Count1 - 1].y1 := y1;
YelSkipBoxs[Count1 - 1].x2 := x2;
YelSkipBoxs[Count1 - 1].y2 := y2;
end else
begin
y1 := y1 - 2;
y2 := y2 + 8;
x1 := x1 - 5;
x2 := x2 + 5;
if ( x1 < 0 ) then x1 := 0;
if ( y1 < 0 ) then y1 := 0;
if ( x2 > 515 ) then x2 := 515;
if ( y2 > 334 ) then y2 := 334;
Count1 := Count1 + 1;
SetArrayLength(YelSkipBoxs, Count1);
YelSkipBoxs[Count1 - 1].x1 := x1;
YelSkipBoxs[Count1 - 1].y1 := y1;
YelSkipBoxs[Count1 - 1].x2 := x2;
YelSkipBoxs[Count1 - 1].y2 := y2;
end;
if ( GetArrayLength(gtalksBox) <> 0 ) then
begin
for yCount := 0 to GetArrayLength(gtalksBox) - 1 do
begin
if FindBitmapMaskTolerance(NickNameBMP, ax, ay, gtalksBox[yCount].x1, gtalksBox[yCount].y1, gtalksBox[yCount].x2, gtalksBox[yCount].y2, 0, 40) then
begin
WriteLn('Found NickName');
ax := (gtalksBox[yCount].x2 + gtalksBox[yCount].x1) shr 1;
ay := gtalksBox[yCount].y2 - 2;
if gTalkSaveBitmap then
begin
bmpScreen := BitmapFromString(515, 334, '');
CopyClientToBitmap(bmpScreen, 1, 1, 515, 334);
if ( gtalksBox[yCount].x1 = 0 ) then x1 := 1 else x1 := gtalksBox[yCount].x1;
if ( gtalksBox[yCount].y1 = 0 ) then y1 := 1 else y1 := gtalksBox[yCount].y1;
gTalksCount := gTalksCount + 1;
for Count1 := -1 to 1 do
for Count2 := -1 to 1 do
FastSetPixel(bmpScreen, Count1 + x1, Count2 + y1, 255);
if ( gtalksBox[yCount].x2 = 515 ) then x1 := 515 else x1 := gtalksBox[yCount].x2;
if ( gtalksBox[yCount].y2 = 334 ) then y1 := 334 else y1 := gtalksBox[yCount].y2;
for Count1 := -1 to 1 do
for Count2 := -1 to 1 do
FastSetPixel(bmpScreen, Count1 + x1, Count2 + y1, 255);
for Count1 := -1 to 1 do
for Count2 := -1 to 1 do
FastSetPixel(bmpScreen, Count1 + ax, Count2 + ay, 255);
SaveBitmap(bmpScreen, ScriptPath + 'FTalk' + IntToStr(gTalksCount) + '.bmp');
FreeBitmap(bmpScreen);
end;
if not FindDTM(DTM_Royal_Frog, X, Y, MSx1, MSy1, MSx2, MSy2) then
begin
MMouse(ax, ay, 0, 0);
Wait(100 + Random(50));
if WaitUpTextMulti(['Talk','lk-to','uard','ard','security','ecurity','curity'], RandomRange(150,300)) then
begin
Mouse(ax, ay, 0, 0, mouse_Right);
Wait(150 + Random(100));
rTalkStrings := ['o Sec','o San','o Gen','o Mil','o Gil','o Nil','o Ric',
'o Dru','o Cap','o Mys','o Dr'];
if (ChooseOptiongetMenuText(RawMenuText, rTalkStrings, ClickLeft)) then
begin
WriteLn('******** FOUND TALKING RANDOM TEXT********: ' + RawMenuText);
Flag;
Wait(700 + Random(300))
if SolveTalkingRandom(RawMenuText) then
Result := True;
Exit;
end;
end;
end else
begin
WriteLn('******** SOLVING FROG RANDOM ********');
if Frog_Solve2 then
Result := True;
Exit;
end;
end;
end;
end;
end;
end;
The above modified function also correctly detects & handles the Frog random event, if you've already installed what I've written above.
Anyways, I'll attach a file already containing all of the modifications if you don't feel like doing them yourself. If you're just using C_AntiRandoms from this post then you'll need to know a couple things. First, download the attached file and place it in "Includes > SRL-OSR > SRL > core > antirandoms". You'll want to include it in your script like so:
{$i SRL-OSR/SRL/core/antirandoms/C_AntiRandoms.simba}
Also you'll need to call "SetupCustomRandoms;" after you've called "SetupSRL;". From now on you'll be using "FindCustomRandoms" as opposed to "FindNormalRandoms".
{$i SRL-OSR/SRL.Simba}
{$i SRL-OSR/SRL/core/antirandoms/C_AntiRandoms.simba}
Procedure declarePlayers;
begin
HowManyPlayers := 1;
NumberOfPlayers(HowManyPlayers);
CurrentPlayer := 0;
with Players[0] do
begin
Name := '';
Pass := '';
Nick := 'nick'; // DO NOT FORGET THIS!
Pin := '';
LampSkill := Skill_Herblore;
WorldInfo := [];
Member := True;
Active := True;
end;
end;
begin
declarePlayers;
SetupSRL;
SetupCustomRandoms;
Repeat
Writeln('Searching for random events...');
FindCustomRandoms;
Until(AllPlayersInactive)
end.
That's all I have so far for the core anti-randoms. I have some detection & handling for others but they're more specific to the script so it wouldn't be appropriate to post them here.