Macro_FTW
06-20-2009, 04:51 AM
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(UsuableUpTe xt), 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.
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(UsuableUpTe xt), 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.