DannyRS
2013-01-08 23:38:23
If you have never played the game before click here for a guide
Almost solved it now I think, will update the functions once I put it through its paces and make sure theres no errors :p
So to anyone that wants to help with a community MTA script and is good at puzzels/math/arrays,
I last worked on this at like 5am so if i made a mistake in this post or misunderstood how the mini-game works, then please correct me :)
I made a start (finished functions below this one marked by orange title), but i need help making this function to really finish this:
FindItemCupboardPosition(ItemToFind: String): Integer;
It will get the current chat text to see what item is in the cupboard you are standing at, then work out the cupboard position the item with a value is at(using the function i made to get the current item values below)
The problem is I'm crap with arrays and math, so for example, if you are at cupboard 0, and the item is a rune longsword, then the emerald is at 7, and the leather boots are at 4 (because of the empty cupboards)
If you check the cupboard and it is empty then you check one that is 3+ away from you to guarantee you find something to compare
The items move and can be at any cupboard in the room every shift
I believe the item order throughout the room is always the same:
Functions made so far:
GetPlayerCupboard: Integer;
Finds what cupboard the player is currently at(0-7)
Positions like this:

WalkToCuboard(ToWalk: Integer): Boolean;
Walks to cupboard 0-7
GetAlchItemWithValue(Value: Integer): String;
Returns the item(string) that is at a value(e.g. 30) currently
e.g. For this image
GetAlchItemWithValue(30) = adamant helm

Full Script if you want to go to the MTA and try things:
Almost solved it now I think, will update the functions once I put it through its paces and make sure theres no errors :p
So to anyone that wants to help with a community MTA script and is good at puzzels/math/arrays,
I last worked on this at like 5am so if i made a mistake in this post or misunderstood how the mini-game works, then please correct me :)
I made a start (finished functions below this one marked by orange title), but i need help making this function to really finish this:
FindItemCupboardPosition(ItemToFind: String): Integer;
It will get the current chat text to see what item is in the cupboard you are standing at, then work out the cupboard position the item with a value is at(using the function i made to get the current item values below)
The problem is I'm crap with arrays and math, so for example, if you are at cupboard 0, and the item is a rune longsword, then the emerald is at 7, and the leather boots are at 4 (because of the empty cupboards)
If you check the cupboard and it is empty then you check one that is 3+ away from you to guarantee you find something to compare
The items move and can be at any cupboard in the room every shift
I believe the item order throughout the room is always the same:
- Leather Boots
- Adamant Kiteshield
- Adamant Helm
- Emerald
- Rune LongSword
- Empty
- Empty
- Empty
//Currently completely reapproaching it :)
Functions made so far:
GetPlayerCupboard: Integer;
Finds what cupboard the player is currently at(0-7)
Positions like this:

CheckBox: Array of TBox;
SetLength(CheckBox, 8);
CheckBox[0]:=IntToBox(89, 87, 104, 98);
CheckBox[1]:=IntToBox(89, 104, 104, 114);
CheckBox[2]:=IntToBox(89, 117, 104, 130);
CheckBox[3]:=IntToBox(89, 135, 104, 146);
CheckBox[4]:=IntToBox(121, 135, 136, 146);
CheckBox[5]:=IntToBox(121, 117, 136, 130);
CheckBox[6]:=IntToBox(121, 104, 136, 114);
CheckBox[7]:=IntToBox(121, 87, 136, 98);
Function GetPlayerCupboard: Integer;
Var
MPOS: TPoint;
Res,I: Integer;
Begin
Res:=-1;
MPOS:=SPS_GetMyPos;
For I:= 0 To 7 Do
If (PointInBox(MPOS, CheckBox[I])) Then
Res:=I;
Result:=Res;
End;
WalkToCuboard(ToWalk: Integer): Boolean;
Walks to cupboard 0-7
Function WalkToCupboard(ToWalk: Integer): Boolean;
Var
WalkPOS: TPoint;
I: Integer;
Res: Boolean;
Begin
Res:=False;
Case ToWalk Of
0: WalkPOS:=Point(99, 91);
1: WalkPOS:=Point(99, 107);
2: WalkPOS:=Point(99, 123);
3: WalkPOS:=Point(99, 143);
4: WalkPOS:=Point(127, 139);
5: WalkPOS:=Point(127, 123);
6: WalkPOS:=Point(127, 107);
7: WalkPOS:=Point(127, 91);
End;
If SPS_BlindWalk(WalkPOS) Then
Res:=True;
Result:=Res;
End;
GetAlchItemWithValue(Value: Integer): String;
Returns the item(string) that is at a value(e.g. 30) currently
e.g. For this image
GetAlchItemWithValue(30) = adamant helm

Function GetAlchItemWithValue(Value: Integer): String;
Var
Row,Col,TempValue,Res: Integer;
Begin
Res:=-1;
Col:=64;
For Row:= 0 To 4 Do
Begin
TempValue:=StrToIntDef(GetTextAtExWrap(475, Col, 493, Col+15, 0, 5, 2, 52275, 2, 'StatChars'),0);
If (TempValue = Value) Then
Res:=Row;
Col:=Col+23;
End;
Case Res Of
-1: Result:='nothing';
0: Result:='leather boots';
1: Result:='adamant kiteshield';
2: Result:='adamant helm';
3: Result:='emerald';
4: Result:='rune longword';
End;
End;
Full Script if you want to go to the MTA and try things:
Program SRLAlchemistsPlayground;
{$Define SMART}
{$I SRL/SRL.Simba}
{$I Sps/Sps.Simba}
{$I SRL/SRL/Misc/Debug.Simba}
//Setup
Const
Debug = True; //Debuging Mode
DebugATPAImage = False; //Debuging ATPA Images Mode
DMP = True; // *** If the SPS Map is Not found found,
//Download them and save them automatically,
//you should leave this as true ***
ScriptVersion = 'V1.0';
//LOGIN INFO STUFF
Procedure DeclarePlayers;
begin
HowManyPlayers := 1;
NumberOfPlayers(HowManyPlayers);
CurrentPlayer := 0;
Players[0].Name :='';
Players[0].Pass :='';
Players[0].Nick :='';
Players[0].Active:=True;
WORLDSWITCHERENABLED:=False;
end;
//dont touch below here unless you know what you are doing
Var
CheckBox: Array of TBox;
ItemOrder: Array of Integer;
CheckBoxOffMap: TBox;
StartingExperience,XPCheck,PlayerActivityTimer: Integer;
{*******************************************************************************
All of these mouse movements and typing are credited to benland100 and flight.
thanks to Ashaman88 for his awesome scripts, i used his as a template
*******************************************************************************}
//By Bandland100, modified by Ashaman88 to shift mouse speeds after every step
//
procedure SuperWindMouse(xs, ys, xe, ye, gravity, wind, minWait, maxWait, maxStep, targetArea: extended);
var
veloX,veloY,windX,windY,veloMag,dist,randomDist,lastDist,step: extended;
lastX,lastY,MSP,W: integer;
sqrt2,sqrt3,sqrt5: extended;
begin
MSP := MouseSpeed;
sqrt2:= sqrt(2);
sqrt3:= sqrt(3);
sqrt5:= sqrt(5);
while hypot(xs - xe, ys - ye) > 1 do
begin
dist:= hypot(xs - xe, ys - ye);
wind:= minE(wind, dist);
if dist >= targetArea then
begin
windX:= windX / sqrt3 + (random(round(wind) * 2 + 1) - wind) / sqrt5;
windY:= windY / sqrt3 + (random(round(wind) * 2 + 1) - wind) / sqrt5;
end else
begin
windX:= windX / sqrt2;
windY:= windY / sqrt2;
if (maxStep < 3) then
begin
maxStep:= random(3) + 3.0;
end else
begin
maxStep:= maxStep / sqrt5;
end;
end;
veloX:= veloX + windX;
veloY:= veloY + windY;
veloX:= veloX + gravity * (xe - xs) / dist;
veloY:= veloY + gravity * (ye - ys) / dist;
if hypot(veloX, veloY) > maxStep then
begin
randomDist:= maxStep / 2.0 + random(round(maxStep) div 2);
veloMag:= sqrt(veloX * veloX + veloY * veloY);
veloX:= (veloX / veloMag) * randomDist;
veloY:= (veloY / veloMag) * randomDist;
end;
lastX:= Round(xs);
lastY:= Round(ys);
xs:= xs + veloX;
ys:= ys + veloY;
case Random(50) of
1..25: W := (MSP + (Random((MSP/4))));
26..50: W := (MSP - (RandomRange((MSP/2), MSP-1)));
end;
if (W < 1) then
W := 1;
if (lastX <> Round(xs)) or (lastY <> Round(ys)) then
MoveMouse(Round(xs), Round(ys));
step:= hypot(xs - lastX, ys - lastY);
//W := round((maxWait - minWait) * (step / maxStep) + minWait);
wait(W);
lastdist:= dist;
end;
if (Round(xe) <> Round(xs)) or (Round(ye) <> Round(ys)) then
MoveMouse(Round(xe), Round(ye));
MouseSpeed := MSP;
end;
Procedure HumanMMouse(eX, eY, ranX, ranY: Integer);
var
randSpeed: extended;
X,Y,X2,Y2,j,Dist,MP: integer;
begin
j := MouseSpeed;
GetMousePos(X, Y);
Dist := Distance(X, Y, eX, eY);
MP := Round(Dist/150);
if MP < 0 then
MP := 1;
randSpeed := (random(MouseSpeed) / 2.0 + MouseSpeed) / 10.0;
X2 := RandomRange(eX-(j*MP), eX+(j*MP));
Y2 := RandomRange(eY-(j*MP), eY+(j*MP));
SuperWindMouse(X, Y, X2, Y2, 11, 8, 10.0 / randSpeed, 12.0 / randSpeed, 10.0 * randSpeed, 10.0 * randSpeed);
GetMousePos(X, Y);
MMouse(eX, eY, ranX, ranY);
MouseSpeed := j;
end;
Procedure HumanMouseBox(X1, Y1, X2, Y2: Integer);
Var
FX, FY: Integer;
Begin
GaussBox(FX,FY,X1,Y1,X2,Y2);
HumanMMouse(FX,FY,0,0)
End;
{*******************************************************************************
procedure FastClick(button: Integer);
By: Flight
Description: Quickly click the mouse.
*******************************************************************************}
procedure FastClick(button: variant);
var
x, y: integer;
ibutton: Integer;
begin
if VariantIsBoolean(button) then
begin
if (button) then
iButton := mouse_left
else
iButton := mouse_right;
end else
iButton := button;
if (iButton = mouse_move) then Exit;
GetMousePos(x, y);
HoldMouse(x, y, iButton);
Wait(RandomRange(60, 150));
GetMousePos(x, y);
ReleaseMouse(x, y, iButton);
end;
Procedure OffMM(RedTu, LeWait, rWait: Integer);
Var
W,H,RX,RY,T,RT: Integer;
Begin
GetClientDimensions(W,H);
H:=H+50;
RX := RandomRange(0, W);
RY := RandomRange(0, H);
Case (RedTu) Of
0..1: HumanMMouse(W/2, RandomRange(-110,-60), RX, 0);
2: HumanMMouse(RandomRange(-50,-10), H/2, 0, RY);
3: HumanMMouse(W/2, h+RandomRange(10,50), RX, 0);
4: HumanMMouse(W+RandomRange(10,50), H/2, 0, RY);
End;
RT:=(Random(rWait));
MarkTime(T);
Repeat
Wait(Random(100));
Until TimeFromMark(T)>(LeWait+RT);
End;
Procedure UseKey(Text: String);
Var
I: Integer;
Begin
For I:=1 To Length(Text) Do
SendKeys(Text[I],RandomRange(90,160),RandomRange(90,160));
Wait(RandomRange(10,50));
End;
Function WaitLoggedIn(Time:Integer): Boolean;
Var
T: Integer;
Begin
MarkTime(T);
Repeat
SRL_ResetNavBar;
If TimeFromMark(T)>Time Then
Begin
Result:=False;
Exit;
End;
Until (GetColor(472, 490) = 16777215);
Result:=True;
End;
//
{*******************************************************************************
DannyRS's Part
*******************************************************************************}
//
Procedure LeftClickSpot(X1, Y1, X2, Y2: Integer);
var Y1NOBanner, Y2NOBanner: Integer;
Begin
Y1NOBanner:=Y1 - 50; Y2NOBanner:=Y2 - 50;
HumanMMouse(RandomRange(X1,X2),RandomRange(Y1NOBanner,Y2NOBanner),0,0);
Wait(9+Random(37));
FastClick(True);
Wait(124+Random(163));
End;
Procedure RightClickSpot(X1, Y1, X2, Y2: Integer);
var Y1NOBanner, Y2NOBanner: Integer;
Begin
Y1NOBanner:=Y1 - 50; Y2NOBanner:=Y2 - 50;
HumanMMouse(RandomRange(X1,X2),RandomRange(Y1NOBanner,Y2NOBanner),0,0);
Wait(9+Random(37));
FastClick(False);
Wait(124+Random(163));
End;
Procedure DragMouseSpot(X1, Y1, X2, Y2: Integer);
var Y1NOBanner, Y2NOBanner: Integer;
Begin
Y1NOBanner:=Y1 - 50; Y2NOBanner:=Y2 - 50;
Wait(150+Random(600));
HumanMMouse(RandomRange(X1,X2),RandomRange(Y1NOBanner,Y2NOBanner),0,0);
Wait(9+Random(37));
End;
Procedure ClickCurrent(ToDo: Boolean);
Begin
Wait(7+Random(37));
FastClick(ToDo);
Wait(124+Random(163));
End;
Procedure DeBugMessage(ToWrite: String);
Begin
If(Debug)Then
Writeln(ToWrite);
End;
Procedure LogOutGame;
Var
x, y: Integer;
Begin
LeftClickSpot(750, 55, 760, 65);
LeftClickSpot(575, 405, 710, 420);
End;
Procedure MinimizeEoCBar(ToDo: Boolean);
Var x, y: Integer;
Begin
If (ToDo) Then
If (FindColorTolerance(x, y, 13224393, 517, 263, 517, 263, 5)) Then
LeftClickSpot(505,318,510,324);
If (Not ToDo) Then
If (Not FindColorTolerance(x, y, 13224393, 517, 263, 517, 263, 5)) Then
LeftClickSpot(505,382,510,385);
End;
Function GetPlayerCupboard: Integer;
Var
MPOS: TPoint;
Res,I: Integer;
Begin
Res:=-1;
MPOS:=SPS_GetMyPos;
For I:= 0 To 7 Do
If (PointInBox(MPOS, CheckBox[I])) Then
Res:=I;
Result:=Res;
End;
Function GetAlchItemWithValue(Value: Integer): String;
Var
Row,Col,TempValue,Res: Integer;
Begin
Res:=-1;
Col:=64;
For Row:= 0 To 4 Do
Begin
TempValue:=StrToIntDef(GetTextAtExWrap(475, Col, 493, Col+15, 0, 5, 2, 52275, 2, 'StatChars'),0);
If (TempValue = Value) Then
Res:=Row;
Col:=Col+23;
End;
Case Res Of
-1: Result:='nothing';
0: Result:='leather boots';
1: Result:='adamant kiteshield';
2: Result:='adamant helm';
3: Result:='emerald';
4: Result:='rune longword';
End;
End;
Function FindItemCupboardPosition(ItemToFind: String): Integer;
Var
ItemCupboardPOS,Count,FoundItemPOSInOrder,Row,Col,TempValue,Res,FoundItem,CheckItem: Integer;
Begin
Res:=-1;
Case GetBlackChatMessage Of
'You found? Leather boots': FoundItem:=0;
'You found? Adamant kiteshield': FoundItem:=1;
'You found? Adamant helm': FoundItem:=2;
'You found? Emerald': FoundItem:=3;
'You found? Rune longsword': FoundItem:=4;
'The cupboard is empty': FoundItem:=-2;
'You have no free space to hold any more items': FoundItem:=-1;
End;
Case ItemToFind Of
'leather boots': CheckItem:=0;
'adamant kiteshield': CheckItem:=1;
'adamant helm': CheckItem:=2;
'emerald': CheckItem:=3;
'rune longword': CheckItem:=4;
End;
For Count:=0 To 7 Do
If FoundItem = ItemOrder[Count] Then
FoundItemPOSInOrder:=ItemOrder[Count];
Result:=Res;
End;
Function WalkToCupboard(ToWalk: Integer): Boolean;
Var
WalkPOS: TPoint;
I: Integer;
Res: Boolean;
Begin
Res:=False;
Case ToWalk Of
0: WalkPOS:=Point(99, 91);
1: WalkPOS:=Point(99, 107);
2: WalkPOS:=Point(99, 123);
3: WalkPOS:=Point(99, 143);
4: WalkPOS:=Point(127, 139);
5: WalkPOS:=Point(127, 123);
6: WalkPOS:=Point(127, 107);
7: WalkPOS:=Point(127, 91);
End;
If SPS_BlindWalk(WalkPOS) Then
Res:=True;
Result:=Res;
End;
Procedure ProgressReport;
Var
XP, XPH, PointsPH: Integer;
Begin
ClearDebug;
If (GetXPBarTotal > XPCheck) Then
MarkTime(PlayerActivityTimer);
XPCheck:= GetXPBarTotal;
XP := (XPCheck - StartingExperience);
XPH := Round(XP * (3600.0 / (GetTimeRunning / 1000.0)));
Writeln('=========SRL-MTA-AP=========================');
Writeln('=========Version: '+ScriptVersion+'=======================');
Writeln('Time Running: ' + TimeRunning);
Writeln('Experience Earned: ' + IntToStr(XP));
Writeln('Experience / Hour: ' + IntToStr(XPH));
Writeln('=============================================');
End;
Procedure MainLoop;
Var
x, y: Integer;
Done,Check: Boolean;
MPOS: TPoint;
num: Integer;
txt: String;
Begin
//Writeln('Welcome to SRL Alchemists Playground');
//Writeln('Start Experience: ' + IntToStr(GetXPBarTotal));
//Pause Before Start Script
//Writeln('Starting in 3...');
//Wait(1000);
//Writeln('Starting in 2...');
//Wait(1000);
//Writeln('Starting in 1...');
//Wait(1000);
MarkTime(PlayerActivityTimer);
//XPCheck:= GetXPBarTotal;
Repeat Begin
Done:= False;
Check:= False;
Writeln(GetAlchItemWithValue(30));
Writeln(IntToStr(GetPlayerCupboard));
Writeln(GetBlackChatMessage);
Done:=True; //DeBuging Only
DeBugMessage('Reached End of Main Loop');
End; Until (Done);
End;
{*******************************-CREDIT-***************************************
All Credit To Ashaman and where ever he learned it, For the map grabbing !!
*******************************************************************************}
Procedure DownloadSPSImage(ImageName: String; Location: String);
Var
Image, Path: string;
FP: Integer;
Begin
If(Debug)Then Begin Writeln('Downloading SPS Map Image'); End;
Image:= GetPage(Location);
Path:= IncludePath + 'SPS\img\runescape_other\' + ImageName + '.png';
Path:= Trim(Path);
FP:= CreateFile(Path);
WriteFileString(FP, Image);
CloseFile(FP);
End;
Function GrabSPSMaps: Boolean;
Var
SPSMMap,SPSMName: String;
Begin
SPSMName:= 'DRAPGSPS';
SPSMMap:= 'http://img33.imageshack.us/img33/9949/drapgsps.png';
If DMP Then
Begin
If (Not FileExists(IncludePath + 'SPS\img\runescape_other\DRAPGSPS.png')) Then
DownloadSPSImage(SPSMName, SPSMMap);
End;
Result:= (FileExists(IncludePath + 'SPS\img\runescape_other\DRAPGSPS.png'));
End;
Procedure RequirementsCheck;
Begin
If (Not GrabSPSMaps) Then
RaiseException(erCustomError, 'SPS Maps Do Not Exist OR They Are Named Incorrectly!');
End;
Procedure SetMyGlobals;
Var Count: Integer;
Begin
if(Debug)then begin
Writeln('Loading Globals'); end;
SetLength(ItemOrder, 8);
SetLength(CheckBox, 8);
For Count:=0 To 7 Do
ItemOrder[Count]:=Count;
CheckBox[0]:=IntToBox(89, 87, 104, 98);
CheckBox[1]:=IntToBox(89, 104, 104, 114);
CheckBox[2]:=IntToBox(89, 117, 104, 130);
CheckBox[3]:=IntToBox(89, 135, 104, 146);
CheckBox[4]:=IntToBox(121, 135, 136, 146);
CheckBox[5]:=IntToBox(121, 117, 136, 130);
CheckBox[6]:=IntToBox(121, 104, 136, 114);
CheckBox[7]:=IntToBox(121, 87, 136, 98);
CheckBoxOffMap:=IntToBox(-2, -2, 1, 1);
End;
Procedure FreeMyGlobals;
Begin
End;
Procedure PollPos;
Var Done: Boolean;
Begin
Repeat
Begin
Writeln(toStr(SPS_GetMyPos));
Wait(1000+Random(50));
End;
Until Done;
End;
Procedure Setup;
Begin
{$IFDEF SIMBAMAJOR980}
SMART_SERVER := 10;
SMART_MEMBERS := TRUE;
SMART_SIGNED := TRUE;
SMART_SUPERDETAIL := FALSE;
SRL_SIXHOURFIX := TRUE;
{$ELSE}
SRL_SIXHOURFIX := TRUE;
SMART_FIXSPEED := TRUE;
{$ENDIF}
SetupSRL;
ClearDebug;
DeclarePlayers;
RequirementsCheck;
SPS_Setup(RUNESCAPE_OTHER, ['DRAPGSPS']);
If Not LoggedIn Then
Begin
Writeln('Not In-Game Trying Log-In');
If Not WaitLoggedIn(1000) Then
LoginPlayer;
Wait(1583+Random(3293));
End;
//ClickNorth(SRL_ANGLE_HIGH);
//ToggleXPBar(True);
//StartingExperience := GetXPBarTotal;
MinimizeEoCBar(False);
MarkTime(PlayerActivityTimer);
SetMyGlobals;
AddOnTerminate('FreeMyGlobals');
SmartSetRefresh(90);
End;
begin
Setup;
ActivateClient;
ClearDebug;
//PollPos;
MainLoop;
//LogOutGame;
end.