Macro_FTW
2009-06-20 00:51:39
Submitted for membership. Thanks everyone for your help! :D
Updated x 1
Because others have done this, I am assuming it's okay. ^^'
Does anyone have suggestions for me on my Miner, which will be used for my SRL Members application?
Script features:
- Lots of failsafes
- Autoresponding [Trades, assist requests, and what other players say
- Antiban [Random talking, mouse moving, etc.]
- Antirandoms
- ATPA rock finding
- DDTM pickaxe finding [Dynamic for finding the pick head color]
- Checks to see if you have a pickaxe in your inventory or weapon's slot. If neither, checks your bank.
- Checks to see if you can use the pickaxe you have or not.
- Better pickaxe selection (When your level is 21, 31, etc. it will search for a better pickaxe in your bank)
- RadialRoadWalk with autocolor and DDTMs at turning/stopping points
- Uses chat box and colors to determine when we start mining and stop.
- Progress reports
- Start in bank OR mine
All help/advice appreciated. I have appended the script to the bottom of this thread and attached it for your convenience. [Note: it's 1,604 lines. ;)]
Thanks for your time! :D
~Macro_FTW
{==============================================================)
MacroVarrockMiner
By: Macro_FTW
Mines any of the Iron, Tin, and Copper available in the Varrock
East mine. Banks afterwards.
Directions:
1. Set up the script
2. Place all characters at the *east* mine, or *east* bank
[Varrock, ofc.]
3. Select the RuneScape client.
4. Run the script.
5. Watch it for a minute or two to ensure it gets everything correctly.
Notes:
If you tell it to mine multiple types of ores, it will mine
what is *closest* to the player. It will not mine them
equally.
Characters you will use MUST have a pickaxe either in their
inventory, equipped, or in their bank. If we gain a level
and are able to use a better pickaxe, then the script will
search the bank for the new pickaxe that we can use.
(==============================================================}
program MacroGuildMiner;
{.include SRL\SRL.Scar}
{==================Global-level variables======================}
var
CopperColors, TinColors, IronColors: array of Integer;
CopperHST, TinHST, IronHST: array of Extended;
RockUpText, FunnyText, FunnyResponse, RandomSayings, ReqResponse: array of String;
LastRespondTime, LastInteractionTime, Trips, LMTol: Integer;
{=======================Script Constants=======================}
const
LoadsPerPlayer = 10; //Loads to do per player. -1 if you want go for a certain
//time per login. Takes prescedence over MinutesPerPlayer.
MinutesPerPlayer = 70; //Minutes to work per player. -1 if you want to do
//a certain number of loads per login.
EscapeDirection = 'D'; //The desired escape direction if we are attacked.
//'D' for dynamic [Chooses the direction with the least
// NPCs], 'N' for North, 'E' for East, 'S' for South,
// 'W' for west. MUST be UPPERCASE.
{The 'do not touchie the consts below this line line. ---------------}
Copper = 1; //Number used to represent Copper mining
Tin = 2; //Number used to represent Tin mining
Iron = 4; //Number used to represent Iron mining
AcceptableWalkingTime = 6000; //The time it should take- max- to walk to any
//given rock.
AcceptableMiningTime = 8000; //Time time it should take to mine a rock * 2.
{=====================End of constants=========================}
{=====================Set-up functions=========================}
function LoadPickaxeDDTM(PickType: String): Integer; forward;
function FindMineableRocks: T2DPointArray; forward;
function SelectRock(ATPA: T2DPointArray): TPointArray; forward;
{==============================================================)
Options for ore choice:
Copper, Tin, and Iron. Must be input as they are. If you
want to mine multiple ores, add them.
Example:
Players[0].Integers[0] := Copper+Tin; //Mines Copper and Tin
Players[1].Integers[0] := Tin+Iron; //Mines Tin and Iron
Players[2].Integers[0] := Iron; //Mines Iron only
(==============================================================}
procedure DeclarePlayers;
begin
HowManyPlayers := 1; //Number of players used
NumberOfPlayers(HowManyPlayers);
CurrentPlayer := 0; //The player whom you wish to start with
Players[0].Name := ''; //Username
Players[0].Pass := ''; //Password
Players[0].Nick := ''; //Auto-generated if left blank.
Players[0].Active := True; //Do you want them to be used?
Players[0].Integers[0] := Copper+Tin+Iron; //Ore choice. See above options.
Players[0].Strings[0] := ''; //Bank PIN. Leave blank if none.
Players[0].Strings[1] := ''; //Lamp skill
//More can be added as you wish. :)
end;
{==============================================================)
If a nickname was not input for a Player, this auto-generates
one. The exact nickname generated is char[1..4] in the string.
Ex.
Name: Macro FTW
Generated nickname: acro
(==============================================================}
procedure SetUpNicknames;
var
TotalPlayers, i: Integer;
TempStr: String;
begin
TotalPlayers := GetArrayLength(Players) - 1;
for i:=0 to TotalPlayers do
begin
//If no nickname has been declared...
if(Players[i].Nick='')then
begin
writeln(Players[i].Name+' needs a nickname.');
TempStr := Players[i].Name;
if(Length(Players[i].Name)>=5)then
begin
TempStr := Left(TempStr, 5);
TempStr := Right(TempStr, 4);
end;
Players[i].Nick := TempStr;
writeln(Players[i].Nick+' was assigned to '+Players[i].Name+'.');
end;
end;
end;
{==============================================================)
Sets up the colors based on the player entrys. Doesn't load
unnecessary colors in to memory. Uses bitwise operations.
(==============================================================}
procedure SetColorAndStringArrays;
var
i, ColorsToUse, PlayerLength: Integer;
begin
PlayerLength := GetArrayLength(Players)-1;
//Gets the colors to load in to memory.
for i:=0 to PlayerLength do
begin
ColorsToUse := ColorsToUse or Players[i].Integers[0];
//If we're using all the colors, no point in continuing the loop.
if(ColorsToUse=Copper+Tin+Iron)then
Break;
end;
//If we're loading the Copper colors...
if(ColorsToUse and Copper = 1)then
begin
CopperColors := [3099238, 2439760, 2176071, 4879521];
CopperHST := [0.03, 0.05, 13.0];
end;
//If we're loading the Tin colors...
if(ColorsToUse and Tin = 1)then
begin
TinColors := [6579308, 5592411, 7763583, 7369081, 5395289];
TinHST := [0.27, 0.06, 8.0];
end;
//If we're loading the Iron colors...
if(ColorsToUse and Iron = 1)then
begin
IronColors := [1383727, 2174023, 2305868, 1712954, 1910334];
IronHST := [0.11, 0.24, 6.0];
end;
end;
{=====================Utility Functions========================}
{==============================================================)
Gets the number of the types of rocks tht the current player is
mining.
(==============================================================}
function GetNumberOfRocksMining: Integer;
var
PlayerInt: Integer;
begin
PlayerInt := Players[CurrentPlayer].Integers[0];
Result := ((PlayerInt and Copper)/Copper) + ((PlayerInt and Tin)/Tin) +
((PlayerInt and Iron)/Iron);
end;
function AllIndeciesIdentical(StringArray: TStringArray): Boolean;
var
i, MaxIndex: Integer;
FirstString: String;
begin
MaxIndex := High(StringArray);
//Is the Length 0?
if(Length(StringArray)=0)then
begin
Result := True;
Exit;
end;
FirstString := StringArray[Low(StringArray)];
//Scan StringArray
for i:=Low(StringArray)+1 to MaxIndex do
begin
if(FirstString<>StringArray[i])then
begin
Result := False;
Exit;
end;
end;
Result := True;
end;
{==============================================================)
Returns the newest added ChatBox Game message. Returns 'NONEW'
if OldMessages remains unchanged.
(==============================================================}
function GetNewChatBoxMessage(OldChat:TStringArray): String;
var
NewChat: TStringArray;
i, MaxIndex: Integer;
begin
NewChat := ChatBoxTextArray(clBlack);
//In case one array is bigger than the other.
if(High(NewChat)>High(OldChat))then
begin
MaxIndex := High(OldChat);
end else
begin
MaxIndex := High(NewChat);
end;
//Checks to see if the chats changed at all.
for i:=MaxIndex downto 0 do
begin
//Are the strings different?
if(NewChat[i]<>OldChat[i])then
begin
//Return the newest message
Result := NewChat[High(NewChat)];
writeln(Result);
Exit;
end;
end;
//Everything was the same
Result := 'NONEW';
end;
{==============================================================)
Finds the cardinal direction with the least NPCs.
(==============================================================}
function FindEscapeDir: char;
var
n, s, e, w: Integer;
WinNS, WinEW, WinAll: Char;
begin
//Gets how many NPC dots are N/S/E/W of the character
n := Length(GetMinimapDotsIn('npc', MMx1, MMy1, MMx2, MMCy));
s := Length(GetMinimapDotsIn('npc', MMx1, MMCy, MMx2, MMy2));
e := Length(GetMinimapDotsIn('npc', MMx1, MMy1, MMCx, MMy2));
w := Length(GetMinimapDotsIn('npc', MMCx, MMy1, MMx2, MMy2));
//Figures out if n or s has less npcs
if(n<=s)then
begin
WinNS := 'N';
end else
begin
WinNS := 'S';
end;
//Figures out if e or w has less npcs
if(e<=w)then
begin
WinEW := 'E';
end else
begin
WinEW := 'W';
end;
//Figures out if WinEW or WinNS has less npcs
if(WinNS<=WinEW)then
begin
WinAll := WinNS;
end else
begin
WinAll := WinEW;
end;
//Result = the place with the least NPCs
Result := WinAll;
end;
{==============================================================)
Returns the TPA of all of the colors in Colors combined.
(==============================================================}
function FindTPAOfColorArray(Colors: TIntegerArray; HST: TExtendedArray): TPointArray;
var
ArrayLength, i: Integer;
ColoredPoints: TPointArray;
begin
ColorToleranceSpeed(2);
SetColorSpeed2Modifiers(HST[0], HST[1]);
ArrayLength := High(Colors);
for i:=0 to ArrayLength do
begin
FindColorsSpiralTolerance(MSCx, MSCy, ColoredPoints, Colors[i], MSx1, MSy1, MSx2, MSy2, Floor(HST[2]));
Result := CombineTPA(Result, ColoredPoints);
end;
end;
{==============================================================)
Gets the required level for the specified pickaxe.
(==============================================================}
function GetRequiredLevelForPickaxe(PickaxeName: String): Integer;
var
PickTypes: TStringArray;
i, Limit: Integer;
begin
PickTypes := ['Bronze', 'Iron', 'Steel', 'Mithril', 'Adamant', 'Rune'];
Limit := High(PickTypes);
for i:=0 to Limit do
begin
//If that's the type of pickaxe
if(pos(PickTypes[i], PickaxeName)<>0)then
begin
case i of
0, 1: Result := 1;
2: Result := 6;
3: Result := 21;
4: Result := 31;
5: Result := 41;
end;
Exit;
end;
end;
//If we couldn't read it, put out the worst case scenario: 41.
Result := 41;
end;
{==============================================================)
Gets the pickaxes that the bot can use, based on its mining
level.
(==============================================================}
function GetUsuablePickaxes(Level: Integer): TStringArray;
var
i, l: Integer;
begin
Result := ['Bronze', 'Iron', 'Steel', 'Mithril', 'Adamant', 'Rune'];
for i:=0 to 5 do
begin
//Sets l according to what i is
case i of
0: l:=6;
1: l:=21;
2: l:=31;
3: l:=41;
end;
//If our level is less than l
if(Level<l)then
begin
//Exclude everything afterwards and exit.
SetArrayLength(Result, i+2);
Exit;
end;
end;
end;
{==============================================================)
Searches for a usuable pickaxe for that player. Uses DDTMs and
UsuablePickaxes to find one.
(==============================================================}
function FindUsuablePickaxe(UsuablePickaxes: TStringArray): TPoint;
var
CurrentDTM, i, x, y: Integer;
SBox: TBox;
begin
//Unsuccessful result...
Result.x := -1;
Result.y := -1;
//Checks if we are in the bank...
if(not(BankScreen))then
begin
SBox.x1 := MIx1;
SBox.y1 := MIy1;
SBox.x2 := MIx2;
SBox.y2 := MIy2;
end else
begin
SBox.x1 := MSx1;
SBox.y1 := MSy1;
SBox.x2 := MSx2;
SBox.y2 := MSy2;
end;
//Last entry [supposed to be highest level] -> Lowest entry.
for i:=High(UsuablePickaxes) downto 0 do
begin
//Did we find the DTM?
CurrentDTM := LoadPickaxeDDTM(UsuablePickaxes[i]);
if(FindDTM(CurrentDTM, x, y, SBox.x1, SBox.y1, SBox.x2, SBox.y2))then
begin
Result.x := x;
Result.y := y;
FreeDTM(CurrentDTM);
Exit;
end;
FreeDTM(CurrentDTM);
end;
end;
{==============================================================)
Checks if two TPoints are equal.
(==============================================================}
function TPointEquals(t1, t2: TPoint): Boolean;
begin
Result := (t1.x=t2.x) and (t1.y=t2.y);
end;
{==============================================================)
Ensures the player has their pickaxe and the level to use it.
If not, it returns false. If so, it returns true.
Special case: We're in the bank. It searches through the
pickaxes in it for the highest level one it can use, and
chooses that one.
Note: It does NOT differentiate between bronze and iron. If
you don't want to use bronze, then only have an iron pick
in your bank.
(==============================================================}
function HasPick(Level: Integer): Boolean;
var
PickaxeUpText, UsuableUpText: TStringArray;
i: Integer;
BankBox: TBox;
DefaultTPoint, PointOf: TPoint;
begin
//Initializing the variables
PickaxeUpText := ['pickaxe', 'ickaxe', 'picka', 'ckax'];
UsuableUpText := GetUsuablePickaxes(Level);
DefaultTPoint.x := -1;
DefaultTPoint.y := -1;
writeln('In Haspick');
//Are we at the bank?
if(BankScreen or PinScreen)then
begin
if(PinScreen)then
if(not(InPin(Players[CurrentPlayer].Strings[0])))then
begin
writeln('Bad pin. Can''t open bank. Going to next player.');
Result := False;
Exit;
end;
SearchBank('pickaxe');
wait(2000);
PointOf := FindUsuablePickaxe(UsuableUpText);
if(TPointEquals(PointOf, DefaultTPoint))then
begin
//We cry here because we went through all that work for a false result.
writeln('*Cries* We couldn''t find a usuable pickaxe. Even in the bank.');
Result := False;
Exit;
end else
begin
//Withdraw it!
writeln('Found the pickaxe!');
PointOf := MSTPointToBankPoint(PointOf);
i := BankPointToBankIndex(PointOf);
BankBox := BankIndexToMSBox(i);
MouseBox(BankBox.x1, BankBox.y1, BankBox.x2, BankBox.y2, 1);
Result := True;
Exit;
end;
end;
//5 is Equipment, 4 is inventory
for i:=5 downto 4 do
begin
GameTab(i);
wait(1000+random(2000));
//If we found a usuable pickaxe...
if(not(TPointEquals(FindUsuablePickaxe(UsuableUpText), DefaultTPoint)))then
begin
writeln('Found a suitable pickaxe with the player.');
Result := True;
Exit;
end;
writeln('Couldn''t find a usuable pickaxe.');
Result := False;
end;
end;
{==============================================================)
Loads the desired Pickaxe's DTM.
(==============================================================}
function LoadPickaxeDDTM(PickType: String): Integer;
var
dtmMainPoint: TDTMPointDef;
dtmSubPoints: Array [0..5] of TDTMPointDef;
TempTDTM: TDTM;
Tol, Color, TolVal: Integer;
begin
Tol := 20; //To avoid repeating the same Tol value in all but one cases.
//Assigning the color based on the passed in string
TolVal := 20;
case LowerCase(PickType) of
'-1': Tol := 255;
'rune': Color := 7826512;
'adamant': Color := 5071181;
'mithril': Color := 7294027;
'steel': Color := 8684686;
'iron': Color := 5987170;
'bronze': Color := 2704987;
end;
dtmMainPoint.x := 111;
dtmMainPoint.y := 41;
dtmMainPoint.AreaSize := 0;
dtmMainPoint.AreaShape := 0;
dtmMainPoint.Color := Color;
dtmMainPoint.Tolerance := Tol;
dtmSubPoints[0].x := 111;
dtmSubPoints[0].y := 41;
dtmSubPoints[0].AreaSize := 0;
dtmSubPoints[0].AreaShape := 0;
dtmSubPoints[0].Color := Color;
dtmSubPoints[0].Tolerance := Tol;
dtmSubPoints[1].x := 122;
dtmSubPoints[1].y := 50;
dtmSubPoints[1].AreaSize := 0;
dtmSubPoints[1].AreaShape := 0;
dtmSubPoints[1].Color := 65536;
dtmSubPoints[1].Tolerance := TolVal;
dtmSubPoints[2].x := 94;
dtmSubPoints[2].y := 44;
dtmSubPoints[2].AreaSize := 0;
dtmSubPoints[2].AreaShape := 0;
dtmSubPoints[2].Color := 65536;
dtmSubPoints[2].Tolerance := TolVal;
dtmSubPoints[3].x := 99;
dtmSubPoints[3].y := 67;
dtmSubPoints[3].AreaSize := 0;
dtmSubPoints[3].AreaShape := 0;
dtmSubPoints[3].Color := 65536;
dtmSubPoints[3].Tolerance := TolVal;
dtmSubPoints[4].x := 97;
dtmSubPoints[4].y := 66;
dtmSubPoints[4].AreaSize := 0;
dtmSubPoints[4].AreaShape := 0;
dtmSubPoints[4].Color := 65536;
dtmSubPoints[4].Tolerance := TolVal;
dtmSubPoints[5].x := 104;
dtmSubPoints[5].y := 48;
dtmSubPoints[5].AreaSize := 0;
dtmSubPoints[5].AreaShape := 0;
dtmSubPoints[5].Color := 65536;
dtmSubPoints[5].Tolerance := TolVal;
TempTDTM.MainPoint := dtmMainPoint;
TempTDTM.SubPoints := dtmSubPoints;
Result := AddDTM(TempTDTM);
end;
{==============================================================)
Loads a defined Walking DTM. 0 is the mine, 1, 5 are transition
points. 7 is the Bank.
(==============================================================}
function LoadWalkingDDTM(num: Integer): Integer;
var
dtmMainPoint: TDTMPointDef;
dtmSubPoints: array of TDTMPointDef;
TempTDTM: TDTM;
begin
case num of
0: begin
SetArrayLength(dtmSubPoints, 4);
dtmMainPoint.x := 1908;
dtmMainPoint.y := 238;
dtmMainPoint.AreaSize := 0;
dtmMainPoint.AreaShape := 0;
dtmMainPoint.Color := 2375758;
dtmMainPoint.Tolerance := 255;
dtmSubPoints[0].x := 1908;
dtmSubPoints[0].y := 238;
dtmSubPoints[0].AreaSize := 0;
dtmSubPoints[0].AreaShape := 0;
dtmSubPoints[0].Color := 2375758;
dtmSubPoints[0].Tolerance := 255;
dtmSubPoints[1].x := 1939;
dtmSubPoints[1].y := 230;
dtmSubPoints[1].AreaSize := 0;
dtmSubPoints[1].AreaShape := 0;
dtmSubPoints[1].Color := 939290;
dtmSubPoints[1].Tolerance := LMTol;
dtmSubPoints[2].x := 1934;
dtmSubPoints[2].y := 239;
dtmSubPoints[2].AreaSize := 0;
dtmSubPoints[2].AreaShape := 0;
dtmSubPoints[2].Color := 939290;
dtmSubPoints[2].Tolerance := LMTol;
dtmSubPoints[3].x := 1941;
dtmSubPoints[3].y := 233;
dtmSubPoints[3].AreaSize := 0;
dtmSubPoints[3].AreaShape := 0;
dtmSubPoints[3].Color := 670294;
dtmSubPoints[3].Tolerance := LMTol;
TempTDTM.MainPoint := dtmMainPoint;
TempTDTM.SubPoints := dtmSubPoints;
Result := AddDTM(TempTDTM);
end;
1: begin
SetArrayLength(dtmSubPoints, 4);
dtmMainPoint.x := 1920;
dtmMainPoint.y := 199;
dtmMainPoint.AreaSize := 0;
dtmMainPoint.AreaShape := 0;
dtmMainPoint.Color := 3562592;
dtmMainPoint.Tolerance := 255;
dtmSubPoints[0].x := 1920;
dtmSubPoints[0].y := 199;
dtmSubPoints[0].AreaSize := 0;
dtmSubPoints[0].AreaShape := 0;
dtmSubPoints[0].Color := 3562592;
dtmSubPoints[0].Tolerance := 255;
dtmSubPoints[1].x := 1907;
dtmSubPoints[1].y := 191;
dtmSubPoints[1].AreaSize := 0;
dtmSubPoints[1].AreaShape := 0;
dtmSubPoints[1].Color := 15658734;
dtmSubPoints[1].Tolerance := LMTol;
dtmSubPoints[2].x := 1937;
dtmSubPoints[2].y := 193;
dtmSubPoints[2].AreaSize := 0;
dtmSubPoints[2].AreaShape := 0;
dtmSubPoints[2].Color := 939290;
dtmSubPoints[2].Tolerance := LMTol;
dtmSubPoints[3].x := 1920;
dtmSubPoints[3].y := 182;
dtmSubPoints[3].AreaSize := 0;
dtmSubPoints[3].AreaShape := 0;
dtmSubPoints[3].Color := 1190712;
dtmSubPoints[3].Tolerance := LMTol;
TempTDTM.MainPoint := dtmMainPoint;
TempTDTM.SubPoints := dtmSubPoints;
Result := AddDTM(TempTDTM);
end;
5: begin
SetArrayLength(dtmSubPoints, 4);
dtmMainPoint.x := 1899;
dtmMainPoint.y := 223;
dtmMainPoint.AreaSize := 0;
dtmMainPoint.AreaShape := 0;
dtmMainPoint.Color := 16777215;
dtmMainPoint.Tolerance := 255;
dtmSubPoints[0].x := 1899;
dtmSubPoints[0].y := 223;
dtmSubPoints[0].AreaSize := 0;
dtmSubPoints[0].AreaShape := 0;
dtmSubPoints[0].Color := 16777215;
dtmSubPoints[0].Tolerance := 255;
dtmSubPoints[1].x := 1898;
dtmSubPoints[1].y := 212;
dtmSubPoints[1].AreaSize := 0;
dtmSubPoints[1].AreaShape := 0;
dtmSubPoints[1].Color := 1335851;
dtmSubPoints[1].Tolerance := LMTol;
dtmSubPoints[2].x := 1894;
dtmSubPoints[2].y := 233;
dtmSubPoints[2].AreaSize := 0;
dtmSubPoints[2].AreaShape := 0;
dtmSubPoints[2].Color := 210996;
dtmSubPoints[2].Tolerance := LMTol;
dtmSubPoints[3].x := 1903;
dtmSubPoints[3].y := 234;
dtmSubPoints[3].AreaSize := 0;
dtmSubPoints[3].AreaShape := 0;
dtmSubPoints[3].Color := 939290;
dtmSubPoints[3].Tolerance := LMTol;
TempTDTM.MainPoint := dtmMainPoint;
TempTDTM.SubPoints := dtmSubPoints;
Result := AddDTM(TempTDTM);
end;
7: begin
SetArrayLength(dtmSubPoints, 4);
dtmMainPoint.x := 1850;
dtmMainPoint.y := 225;
dtmMainPoint.AreaSize := 0;
dtmMainPoint.AreaShape := 0;
dtmMainPoint.Color := 16711422;
dtmMainPoint.Tolerance := 255;
dtmSubPoints[0].x := 1850;
dtmSubPoints[0].y := 225;
dtmSubPoints[0].AreaSize := 0;
dtmSubPoints[0].AreaShape := 0;
dtmSubPoints[0].Color := 16711422;
dtmSubPoints[0].Tolerance := 255;
dtmSubPoints[1].x := 1844;
dtmSubPoints[1].y := 232;
dtmSubPoints[1].AreaSize := 0;
dtmSubPoints[1].AreaShape := 0;
dtmSubPoints[1].Color := 195836;
dtmSubPoints[1].Tolerance := LMTol;
dtmSubPoints[2].x := 1849;
dtmSubPoints[2].y := 233;
dtmSubPoints[2].AreaSize := 0;
dtmSubPoints[2].AreaShape := 0;
dtmSubPoints[2].Color := 60909;
dtmSubPoints[2].Tolerance := LMTol;
dtmSubPoints[3].x := 1852;
dtmSubPoints[3].y := 234;
dtmSubPoints[3].AreaSize := 0;
dtmSubPoints[3].AreaShape := 0;
dtmSubPoints[3].Color := 195836;
dtmSubPoints[3].Tolerance := LMTol;
TempTDTM.MainPoint := dtmMainPoint;
TempTDTM.SubPoints := dtmSubPoints;
Result := AddDTM(TempTDTM);
end;
end;
end;
{==============================================================)
Looks for the DTM in the Minimap. Used to save a bit of typing.
(==============================================================}
function FindMMLandmarkEx(TheDTM: Integer; var x, y: Integer): Boolean;
begin
Result := DTMRotated(TheDTM, x, y, MMx1, MMy1, MMx2, MMy2);
end;
{==============================================================)
Looks for the landmark LoadWalkingDDTM(WalkDTMNumber) in the
minimap. Starts with 5 tolerance and increments by 5 until the
tolerance is > MaxTol.
True if found, False otherwise.
(==============================================================}
function FindMMLandmark(WalkDTMNumber, MaxTol: Integer; var x, y: Integer): Boolean;
var
TheDTM: Integer;
begin
LMTol := 5;
Result := False;
while((LMTol<=MaxTol) and (not Result))do
begin
TheDTM := LoadWalkingDDTM(WalkDTMNumber);
writeln('Searching for a DTM with '+IntToStr(LMTol)+' tolerance...');
if(FindMMLandmarkEx(TheDTM, x, y))then
begin
writeln('Found landmark '+inttostr(WalkDTMNumber)+' with a tolerance of '+inttostr(LMTol)+'.');
Result := True;
end else
begin
IncEx(LMTol, 5);
end;
FreeDTM(TheDTM);
end;
LMTol := 5;
end;
{==============================================================)
Checks to see if we're at the bank.
(==============================================================}
function AtBank: Boolean;
var
x, y: Integer;
begin
Result := FindMMLandmark(7, 25, x, y);
end;
function AtMine: Boolean;
var
x, y: Integer;
begin
Result := FindMMLandmark(0, 25, x, y);
end;
{==================Antiban/Random Functions====================}
{==============================================================)
Automatically responds to trade/assist requests, along with words
in the FunnyText array. Returns true if responded, false otherwise.
(==============================================================}
function AutoRespond: Boolean;
var
flg: Boolean;
i, a: Integer;
Msg: String;
begin
Result := False;
//If we haven't responded to chat in more than 2 mins...
if(GetTimeRunning>LastRespondTime+120000)then
begin
//Going through every message in the chat box...
for i:=1 to 8 do
begin
Msg := Lowercase(GetChatBoxText(i, clBlue));
//If there is player text on that line...
if(not(Msg=''))then
begin
for a:=0 to Length(FunnyText)-1 do
begin
//If it Finds any word in FunnyText in the message...
if(not(Pos(FunnyText[a], Msg)=0))then
begin
//Send a Random message in FunnyResponse with misgakes
TypeSend(AddMistakes(FunnyResponse[Random(Length(FunnyResponse))], 25));
flg := True;
Break;
end;
end;
end;
if(flg)then
begin
flg := False;
Result := True;
LastRespondTime := GetTimeRunning;
Break;
end;
end;
end;
//If we haven't responded to trade/assist requests in more than 5 mins...
if(GetTimeRunning>LastInteractionTime+300000)then
begin
for i:=1 to 8 do
begin
Msg := getChatBoxText(i, clPurple);
if(not(Msg=''))then
begin
flg := True;
TypeSend(AddMistakes(reqResponse[Random(Length(reqResponse))], 25));
end;
if(flg)then
begin
flg := False;
Result := True;
LastInteractionTime := GetTimeRunning;
Break;
end;
end;
end;
end;
{==============================================================)
Says a random thing from RandomSayings. If required is true,
the script says it every time this is called. If required is
false, the script says it randomly when this is called.
(==============================================================}
procedure RandomSpeak(Required: Boolean);
begin
if(Required or (Random(10)=0))then
TypeSend(AddMistakes(RandomSayings[Random(Length(RandomSayings))], 25));
end;
{==============================================================)
Simple, Random antiban. Returns mouse to original position after
each antiban loop.
(==============================================================}
procedure AntiBan;
var
x, y: Integer;
begin
GetMousePos(x, y);
if not LoggedIn then Exit;
if(AutoRespond) then Exit; //If we've autoresponded, no need to do more antiban.
case Random(40) of
1: RandomMovement;
2: RandomRClick;
3: HoverSkill(LampSkill, False);
4: BoredHuman;
5: RandomSpeak(False);
else Wait(1000+random(1500));
end;
MMouse(x, y, 5, 5);
end;
{==============================================================)
Handles randoms that we may encounter.
(==============================================================}
function HandleRandoms: Boolean;
var
dir: Char;
begin
Result := False;
if(FindFight)then
begin
Result := True;
if(EscapeDirection='D')then
begin
dir := FindEscapeDir;
end else
begin
dir := EscapeDirection;
end;
RunAway(dir, True, 1, 2000);
end;
//Won't short-circuit, if that's possible in PaSCAR. Two randoms don't
// occur at once, to my experience :P
Result := FindLamp(Players[CurrentPlayer].Strings[1]) or FindNormalRandoms;
end;
{=====================Mining Functions=======================}
{==============================================================)
Generates an ATPA based on the rocks that the player is mining.
Returns that ATPA sorted in order from closest to player to
farthest from player.
(==============================================================}
function FindMineableRocks: T2DPointArray;
var
Points: TPointArray;
FromPoint: TPoint;
begin
writeln('Looking for mineable rocks.');
writeln(inttostr(currentPlayer));
if((Players[CurrentPlayer].Integers[0] and Copper)=1)then
begin
Points := FindTPAOfColorArray(CopperColors, CopperHST);
end;
if(Players[CurrentPlayer].Integers[0] and Tin=1)then
begin
Points := CombineTPA(Points, FindTPAOfColorArray(TinColors, TinHST));
end;
if(Players[CurrentPlayer].Integers[0] and Iron=1)then
begin
Points := CombineTPA(Points, FindTPAOfColorArray(IronColors, IronHST));
end;
Result := TPAToATPA(Points, 15);
//Ensures that the closest rock isn't, say, at the middle of the list. :P
if(GetNumberOfRocksMining>1)then
begin
FromPoint.x := MSCx;
FromPoint.y := MSCy;
SortATPAFrom(Result, FromPoint); //I love this function. Saved me an hour of writing code. o.o
end;
writeln('Found potential rocks.');
end;
{==============================================================)
Looks through ATPA to find a rock. When a rock is found, it
leaves the mouse on it and returns the TPA of that rock.
(==============================================================}
function SelectRock(ATPA: T2DPointArray): TPointArray;
var
ThePoint: TPoint;
i: Integer;
begin
//Searching for a near rock.
for i:=0 to High(ATPA) do
begin
ThePoint := MiddleTPA(ATPA[i]);
MMouse(ThePoint.x, ThePoint.y, 3, 3);
wait(250+random(250));
//If that's a rock that appeared in our ATPA...
if(IsUpTextMultiCustom(RockUpText))then
begin
Result :=ATPA[i];
Exit;
end;
end;
end;
{==============================================================)
Waits until we start mining the rock. Uses the chat box to find
when we start mining. Returns an Integer based on how well we
did. Also gives the x, y of the colors to look for when the
rock has been mined.
Result possibilities:
0: Successfully executed; mining the rock.
1: Look for another rock; can't reach this one, or the ore is
gone.
2: Fatal error; logged out, can't find anything, etc.
(==============================================================}
function WaitUntilStartedMining(var x, y: Integer; tol: Integer): Integer;
var
ChatStrings, NonFatalStrings: TStringArray;
NewMessage: String;
i, a, StartTime, OldCTS: Integer;
begin
StartTime := GetTimeRunning;
if(not LoggedIn)then
begin
Result := 2;
Exit;
end;
OldCTS := GetColorToleranceSpeed;
ColorToleranceSpeed(1);
writeln('WaitUntilStartedMining Started.');
//Searching for lines that aren't "you swing your pick..."
ChatStrings := ChatBoxTextArray(clBlack);
//If all the text is the same, and is "You swing your pick at the rock"
if(AllIndeciesIdentical(ChatStrings) and (Pos('your pick', ChatStrings[0])<>0))then
begin
//Forcing the player to say a random phrase to vary the chatbox.
RandomSpeak(True);
ColorToleranceSpeed(OldCTS);
Result := 1;
Exit;
end;
//At this point, there has to be a NonMineIndex of not 0.
Result := 0;
//Follow the rock until we get a new message, or AcceptableWalkingTime time expires.
NonFatalStrings := ['swing your', 'can''t reach', 'no ore', 'found a'];
a := High(NonFatalStrings);
ChatStrings := ChatBoxTextArray(clBlack);
//Wait for a nonfatal message, or until AcceptableWalkingTime expires.
repeat
wait(100+random(500));
NewMessage := GetNewChatBoxMessage(ChatStrings);
for i:=0 to a do
begin
writeln('Attempting to find '+newMessage+' in '+NonFatalStrings[i]);
if(pos(NonFatalStrings[i], NewMessage)<>0)then
begin
if(pos('swing your', NewMessage)<>0)then
begin
ColorToleranceSpeed(OldCTS);
Result := 0;
Exit;
end else
begin
ColorToleranceSpeed(OldCTS);
Result := 1;
Exit;
end;
end;
end;
until(((StartTime+AcceptableWalkingTime)<(GetTimeRunning)));
Result := 1;
ColorToleranceSpeed(OldCTS);
end;
{==============================================================)
Waits until the rock is mined.
(==============================================================}
procedure WaitUntilMined(x, y: Integer);
var
StartTime, Errors, OldCTS, Color: Integer;
tempBool: Boolean;
ChatBox: TStringArray;
begin
OldCTS := GetColorToleranceSpeed;
ColorToleranceSpeed(1);
Color := GetColor(x, y);
writeln('Waiting until the rock is mined.');
StartTime := GetTimeRunning;
ChatBox := ChatBoxTextArray(clBlack);
//If the uptext isn't mining
if(not(IsUpTextMultiCustom(RockUpText)))then
begin
//If we found the wrong colors, we wait AcceptableMiningTimes seconds to mine it.
wait(AcceptableMiningTime);
ColorToleranceSpeed(OldCTS);
Exit;
end;
AntiBan;
tempBool := true;
writeln('Antiban done.');
Errors := 0;
MMouse(x, y, 5, 5);
//While 8 seconds haven't passed...
while ((StartTime+AcceptableMiningTime>GetTimeRunning)) do
begin
wait(500+random(1500));
//If we got the ore, we're done.
if(pos('ou manage to ', GetNewChatBoxMessage(ChatBox))<>0)then
Break;
if(Color <> GetColor(x, y))then
Break;
end;
ColorToleranceSpeed(OldCTS);
writeln('Mined.');
end;
{==============================================================)
Walks to a destination. If Bank is true, it walks to the bank.
Otherwise, it walks to the mine. Starts at position spos. If
spos is -1, it starts where it needs to start.
Uses some DDTMs for clicking on directly, others as landmarks or
checkpoints.
(==============================================================}
function WalkToEx(Bank: Boolean; spos: Integer): Boolean;
var
Step, EndValue, AddAngle, x, y, AddVal, Fails, CompassAngle, t, OverallFails, SAdd, TWalk, Tol: Integer;
begin
MakeCompass('N');
wait(400+random(1000));
CompassAngle := Floor(RS_GetCompassAngleDegrees);
if(spos=-1)then
begin
case Bank of
False: Step := 6;
True: Step := 1;
end;
end else
begin
Step := spos;
end;
if(Bank)then
begin
EndValue := 8;
AddVal := 1;
AddAngle := 0;
end else
begin
EndValue := -1;
AddVal := -1;
AddAngle := 180;
end;
TWalk := 0;
//While we aren't done and have failed less than 3 times concecutively...
while((Step<>EndValue) and (Fails<2) and (OverallFails<10))do
begin
if(not LoggedIn)then Exit;
HandleRandoms;
case Step of
0, 1, 5, 7: begin
TWalk := 0;
if(FindMMLandmark(Step, 25, x, y))then
begin
Fails := 0;
writeln('Found landmark '+inttostr(Step));
Mouse(x, y, 5, 5, true);
wait(1000);
HandleRandoms;
if(FlagPresent)then
FFlag(15);
Step := Step + AddVal;
end else
begin
Inc(Fails);
Inc(OverallFails);
writeln('Can''t find landmark '+inttostr(Step)+'... Going to step '+inttostr(Step-AddVal));
Step := Step - AddVal;
end;
end;
2..4, 6: begin
//Walking at ~270/~420, as opposed to ~360/~520
if(Step=6)then
begin
Sadd := -80;
end else
begin
SAdd := 0;
if(Bank)then
begin
t := 5;
end else
begin
t:= 1;
end;
end;
writeln('Attempting pure radialwalk...');
if(not(RadialRoadWalk(FindVarrockRoadColor, 320+AddAngle+SAdd, 380+AddAngle+SAdd, 65, -3, -3)))then
begin
Inc(Fails);
Inc(OverallFails);
writeln('Failed.');
end else
begin
Fails := 0;
writeln('Found road. Walking.');
wait(1000);
Inc(TWalk);
HandleRandoms;
if(Step<>6)then
begin
//If we've RadialWalked more than twice to reach our target...
if(TWalk>2)then
begin
Tol := 15;
end else
begin
Tol := 0;
end;
if(FindMMLandmark(t, Tol, x, y))then
begin
Step := t;
Continue;
end;
end else
begin
Step := Step+AddVal;
end;
end;
end;
end;
end;
Result := (Fails>1) or (OverallFails>9);
end;
{==============================================================)
Walks to Bank (true, goes to the bank. False, goes to the mine.)
Checks to see if we're there first. ;)
(==============================================================}
function WalkTo(Bank: Boolean): Boolean;
begin
//We're going to the bank...
if(Bank)then
begin
if(AtBank)then
begin
Result := True;
Exit;
end else
begin
Result := WalkToEx(True, -1);
Exit;
end;
end;
//We're going to the mine...
if(AtMine)then
begin
Result := True;
Exit;
end;
Result := WalkToEx(False, -1);
end;
{==============================================================)
Banks the items with the pickaxe optional.
(==============================================================}
function BankItems(GetPick: Boolean): Boolean;
var
MLevel, Coord: Integer;
PickCoords, DCoord: TPoint;
begin
Result := False;
if(not(LoggedIn))then Exit;
//If we can't get there, exit.
if(not(WalkTo(True)))then Exit;
MLevel := GetSkillLevel('mining');
//If we couldn't open the bank fast...
if(not(OpenBankFast('veb')))then
if(not(OpenBankQuiet('veb')))then Exit;
//If we're in the pin screen
if(PINScreen)then
if(not(InPin(Players[CurrentPlayer].Strings[0])))then Exit; //If the pin didn't work...
//If we went through all that and are somehow not in the bank screen...
if(not(BankScreen))then Exit;
//If we're looking for/getting a new pickaxe...
if(GetPick)then
begin
DepositAll;
//HasPick gets the pick out for us, as well. Handy, huh? ;)
HasPick(MLevel);
end else
begin
//Getting the inventory slot of our pickaxe so we don't deposit it
PickCoords := FindUsuablePickaxe(GetUsuablePickaxes(MLevel));
if(TPointEquals(PickCoords, DCoord))then //If it's equipped
begin
Coord := 0;
end else
begin
Coord := CoordsToItem(PickCoords.x, PickCoords.y);
end;
//Depositing everything else...
if((Coord=1) or (Coord=0))then
begin
Deposit(Coord+1, 28, True);
end else
begin
if(Coord=28)then
begin
Deposit(1, 27, True);
end else
begin
Deposit(1, Coord-1, True);
Deposit(Coord+1, 28, True);
end;
end;
end;
//If we're not logged in, exit.
if(not(LoggedIn))then Exit;
Result := WalkTo(False); //Return whether we made it back or not.
end;
{===================Main script functions======================}
{==============================================================)
Gives a Progress Report for PlayerNum player.
(==============================================================}
procedure ProgressReportEx(PlayerNum: Integer);
var
Hr, Minutes, Sec: Integer;
begin
ConvertTime(GetTimeRunning, Hr, Minutes, Sec);
writeln('========Macro FTW''s Varrock East Miner+Banker========');
writeln('Been working for '+IntToStr(Hr)+' hours, '+IntToStr(Minutes)+' minutes, and '+IntToStr(Sec)+ ' seconds.');
writeln('Mined '+IntToStr(Players[PlayerNum].Integers[1])+' ores.');
end;
{==============================================================)
Gives a Progress Report for CurrentPlayer
(==============================================================}
procedure ProgressReport;
begin
ProgressReportEx(CurrentPlayer);
end;
{==============================================================)
Player initilization/switch function.
(==============================================================}
procedure GoToNextPlayer(Active: Boolean);
begin
ProgressReport;
NextPlayer(Active);
if(GetNumberOfRocksMining=0)then
begin
writeln(Players[CurrentPlayer].Name+' isn''t mining anything. Going to the next one.');
GoToNextPlayer(False); //Recursion! :D
end;
end;
{==============================================================)
Initializes all of the necessary script variables/etc.
(==============================================================}
procedure SetUpScript;
var
Disguises: array of String;
begin
writeln('Setting up the script.');
SetUpSRL;
DeclarePlayers;
SetUpNicknames;
SetColorAndStringArrays;
ColorToleranceSpeed(2);
//AutoResponding string arrays.
FunnyText := ['lol', 'haha', 'rofl', 'lmao', 'ha'];
FunnyResponse := ['XD', 'Haha!', 'Lol', 'Wow...'];
RandomSayings := ['...', 'I''m a lumberjack and I''m O.K. I sleep all night...', 'Bored... >.<'];
reqResponse := ['Nty', 'No, thanks.', 'Nah.', 'I''m good.', 'No, thanks though.', 'Hm... Nty.'];
//Sets the Rock UpText
RockUpText := ['Mine', 'ine', 'Min'];
//Picks one of the below disguises and uses it.
Disguises := ['Microsoft Word', 'Microsoft Excel', 'Notepad', 'OpenOffice QuickStarter', 'untitled - Paint'];
Disguise(Disguises[Random(GetArrayLength(Disguises))]);
writeln('Script set-up complete.');
end;
{==============================================================)
Sets up a player after login.
(==============================================================}
function SetUpPlayer: Boolean;
begin
SetAngle(True);
SetRun(True);
gameTab(4);
//Game: All. Public: On. Private: Friends. Clan/Trade/Assist: On
SetChat('all', 0);
SetChat('on', 1);
SetChat('friends', 2);
SetChat('on', 3);
SetChat('on', 4);
SetChat('on', 5);
//Do we have a pickaxe?
Result := HasPick(GetSkillLevel('mining'));
end;
{==============================================================)
The main loop of the script.
(==============================================================}
function MainLoop: Boolean;
var
MineableRocks: T2DPointArray;
RockToMine: TPointArray;
x, y, t, TempDTM, Errors, Count, Loads: Integer;
begin
Result := False;
if(not LoggedIn)then Exit;
Loads := LoadsPerPlayer + Random(5);
if(Loads<1)then
Loads := 1;
while Count < Loads do
begin
//The mining loop
while not(InvFull) do
begin
MineableRocks := FindMineableRocks;
RockToMine := SelectRock(MineableRocks);
GetMousePos(x, y);
Mouse(x, y, 1, 1, true); //If your mouse is already on the rock, you don't need
//much 'random' to click it. ;)
t := WaitUntilStartedMining(x, y, 10);
//Depending on what happened in t...
case t of
2: begin
Inc(Errors);
writeln('Fatal error occured.');
if(not LoggedIn)then
begin
writeln('Reason: Not logged in. Logging in...');
LogInPlayer;
wait(3000+random(4000));
Continue;
end;
writeln('Reason: Can''t find rock. Scanning for randoms...');
if(HandleRandoms)then
begin
writeln('Random found. Appropriate action taken; continuing mining.');
Continue;
end;
writeln('Random not found... Attempting to find the mine.');
TempDTM := LoadWalkingDDTM(0);
WalkToEx(False, 0);
FreeDTM(TempDTM); //Has to be repeated. Otherwise, the Continue skips it.
writeln('Something unexpected happened. Going to next player.');
LogOut;
Exit;
end;
1: begin
writeln('Couldn''t get that ore. :/. Continuing on...');
Continue;
end;
end; //End of case
GetMousePos(x, y);
WaitUntilMined(x, y);
//Integers[1] is ores mined.
Inc(Players[CurrentPlayer].Integers[1]);
end;
//Walking to and from the bank, with depositing items.
if(InvFull)then
begin
BankItems((GetSkillLevel('mining') mod 10) = 1);
//If no rocks could be found...
if(Length(FindMineableRocks)=0)then
begin
//Attempt to find the mine.
WalkToEx(False, 0);
if(Length(FindMineableRocks)=0)then
begin
writeln('Can''t find the mine. Logging out.');
Exit;
end;
end;
end;
Inc(Count);
Inc(Trips);
end;
Result := True;
end;
begin
SetUpScript;
repeat
LoginPlayer;
//If we don't have a pick, get one.
if(not(SetUpPlayer))then
//If getting the pick failed, or we don't have the pick after attempting
//to get it... 99 mining used because it would have picked the correct pick
//at the bank.
if(not(BankItems(True)) or (not HasPick(99)))then
begin
GoToNextPlayer(False);
Continue;
end;
GoToNextPlayer(MainLoop);
until(AllPlayersInactive);
end.