SRL Archive - OSR Help

TBox Coordinates


VastlySuperior

2012-08-30 11:49:56


I need some help. I create a TBox where I find the color of the ore I want to mine, I draw the box but as you can see it is not near my character, when I move to mine the ore, this tbox i created shift as well.

Now my question is this. How do I create the box and let it remain at the location where it was created, because I want to search now for the color of the vein in the rock at the location I already found and clicked to start the mining process,to see when it was successfully mined or stolen by another player while mining so that I can break out of the loop and search for the next rock to mine?

This is the function I use to Check On the color of the ore, if it exist or not.

Function IsVein(var VBox:TPoint): Boolean;
var
VX, VY, x, y: Integer;
VTPA : Array Of TPoint;
ATPA : T2DPointArray;
i : Integer;

Begin
SMART_DrawBoxEx(True, False, IntToBox(VBox.x - 12, VBox.y - 12, VBox.x + 12, VBox.y + 12), ClWhite)
FindColorsSpiralTolerance(VX, VY, VTPA, Colour, VBox.x - 12, VBox.y - 12, VBox.x + 12, VBox.y + 12, TolR)
Begin
ATPA := SplitTPA(VTPA, 6);
For i := 0 To High(ATPA) Do
Begin
If MiddleTPAEX(ATPA[i], VX, VY) then
Begin
MMouse(VX, VY, 1, 1);
End else
Continue;
WriteLn(GetUpText);
Result := FindColorTolerance(x, y, Colour, VBox.x - 12, VBox.y - 12, VBox.x + 12, VBox.y + 12, TolR);
WriteLn(Result);
Exit;
End;
End;
End;

If I don`t move this code works, but when I move this code does not work as it dont find the right coordinates where it is supposed to look for the color.

This is where I create the green box, where I originally have found the ore to mine.

    If not(Mined) Then
Begin
If (FindOre(x, y)) then
Begin
MBox := IntToBox(x - 10, y - 10, x + 10, y + 10);
VBox := IntToBox(x - 15, y - 15, x + 15, y + 15);
SMART_DrawBoxEx(True, False, MBox, ClGreen);
ClickMouse2(Mouse_Left);
MarkTime(RockCounter);
MarkTime(FailSafeTime);
Mined := True;
Box := Point(x, y);
Writeln(Box);
Writeln('Clicked The Ore To Start Mining');
// Wait(RandomRange(800, 1200));
End;
End;

I will appreciate some help with this.

Thanks

E. This is the debug when it does work.

Looking For The Vein Color
Mine Iron ore rocks / 2 more options
True
Looking For The Vein Color
Mine Iron ore rocks / 2 more options
True
Looking For The Vein Color
Mine Iron ore rocks / 2 more options
True
Looking For The Vein Color
Mine Iron ore rocks / 2 more options
True
Looking For The Vein Color
Mine Iron ore rocks / 2 more options
False
Starting Next Loop For Finding Ore

Footy

2012-08-30 12:05:02

I'm not sure how I'd do what you are asking, but why not use pixelshift to check if your character is mining? If the pixelshift is high, your character is currently mining, if its low, you were beaten to the rock, if your invcount went up one, you got the rock.

VastlySuperior

2012-08-30 12:17:17

I currently do that, but it is too slow, when the ore is taken by another player your character is still in the animation so it register as true.

     Repeat
Writeln('Looking For The Vein Color');
If FindNormalRandoms then
Begin
If Not LoggedIn Then
Begin
Writeln('Found unsolvable random');
NextPlayer(False);
End;
End;
Until not(IsVein(Box)) or (FindBlackChatMessage('nage')) or (TimeFromMark(RockCounter) > (3700 + Random(300))) and (not(IsMining));

That`s why I want to include the check to see if the vein color still exist on the rock that was clicked on, which will break just so much faster out of the sequence to start mining again. It is all about speed. At the moment I get beaten quite badly by other bots.

If this is successful I think that is the only check you will need to break out of the loop.

mormonman

2012-08-30 12:19:27

Well, if you move, then of course the coordinates of you box change. You need to implement some sort of tracking. Look into MSI or my roach script for examples.

putonajonny

2012-08-30 12:20:25

Why don't you just always the pixel that is the correct colour that is closest to you?

I may have completely misunderstood what you are saying.

Edit:
You need to work out where you are stood relative to the rock you are mining, then you can work out where the box should be to check in. I did the same thing for my Chop N' Burn script. I'll get you some code in a sec…

VastlySuperior

2012-08-30 13:00:56

From: putonajonny
Why don't you just always the pixel that is the correct color that is closest to you?

I may have completely misunderstood what you are saying.

Edit:
You need to work out where you are stood relative to the rock you are mining, then you can work out where the box should be to check in. I did the same thing for my Chop N' Burn script. I'll get you some code in a sec…


I already sort the TPA`s to find the color the nearest to my character, but when you have taken the nearest ore it must go somewhere else.

Will appreciate the look at the code to see what you have done.

@ mormonman, I will definitely look at the code as well, need something to make this work.

VastlySuperior

2012-08-30 13:31:37


You get some real petty people. I mean what does this say to you?

No, my ass is to big, No, I`m to fat?

Come on. Really? :duh:

Footy

2012-08-30 14:01:01

Lol, I've recieved my fair share of these aswlell.

Runaway

2012-08-30 21:10:11

This sounds like a similar method to what putonajonny was talking about:


type
TRadial = record
Length: Integer;
Angle: Extended;
Direction: String;
end;

function GetRadial(A, B: TPoint): TRadial;
var
Direction: TStringArray;
Angle: Extended;
begin
Direction := ['n', 'e', 's', 'w'];
Angle := Degrees(FixRad((ArcTan2(A.y - B.y, A.x - B.x) + Radians(90)) - Pi));
if not InRange(Round(Angle), 0, 360) then
Exit;
Result.Length := Distance(A.x, A.y, B.x, B.y);
Result.Angle := Angle;
if (Angle >= 315) then
Angle := 360 - Angle;
Result.Direction := Direction[Round(Angle / 90.0)];
end;

If you get the angle between the center of the MS and the rock you're about to click, it will tell you the direction to check for the rock after you've moved. For example, if it returns 75 degrees, you will know to check either the east or north rock for changes.

Hopefully that can help :p

P1ng

2012-08-30 21:59:11

You should check out the function I posted in this thread: http://villavu.com/forum/showthread.php?t=89206

Basically I am still having a little bit of trouble detecting precisely which one you are mining, but with the use of the function Runaway just posted it should be able to detect it perfectly.

If you need any explanation of what the function I have in the other thread does feel free to PM me again or reply here.

VastlySuperior

2012-08-31 04:34:11

@ Runaway Thanks for that Function, far more advanced than what I would have been able to create with my knowledge.

@P1ng The Function you have placed is basically the same as what I have for detecting the vein, but it have the same problem as my own. When you move it looks for the color in the wrong place. But your own thoughts on this would also be appreciated as you will also have to implement this in you script.

This is Just a testing script I have Put together to put my thoughts in writing and test the ideas I have. The Problem is when your character moves so the rest can stay as it is because it does work correctly in checking if the vein is still present.

All I have done is to make some adjustments for when you move to work out where the new box should be created. I have some Issues in assigning the distance value to the variable I have created for it, I don`t really know how to assign just the distance to the variable, how do you get just the distance from the new type that was created.

Also This does not take into account the difference in degrees, In other words how much the x axis has to be adjusted for the new position, all I basically do is deduct the distance from the y axis. You would also need to adjust for when something is not above you (North), but Rather South.

Here is the test Program, Would appreciate some thoughts and suggestions about this.

program DirectionTest;
{$DEFINE SMART}
{$i srl/srl.simba}
{$I SRL/SRL/MISC/SMARTGRAPHICS.SIMBA}
{$i sps/sps.simba}

const
Server = 35; // enter "0" to pick a Random server.
Members = False; // is this player a member
NumbOfPlayers = 1; // how many players should be active
StartPlayer = 0; // the player who should be first used
LoadsToDo = 73; // Set how many repetitions to do of a certain Activity
PowerMine = False; // True Or False For Drop Ore
OreChoice = 0; // Valid Mining Choices

var
Path:TPointArray;
OreSpot:Tpoint;
Desc:String;
Start_Time, End_Time, TotalTime, TripStart, TripEnd, TripTotal, Colour,
TolR, Cam, CopperLoads, ClayLoads, GoldLoads, IronLoads, TinLoads,
TotalLoads, MCurrentXP, MOriginalXP, CMSkillLevel, MSkillGain,
TotalXP, OMSkillLevel: Integer;
MineFirstRun, LostMyWay:Boolean;
MBox:TBox;

procedure DeclarePlayers; // Setup Players
Begin
HowManyPlayers := 1;
NumberOfPlayers(HowManyPlayers);
CurrentPlayer := 0;
with players[0] do
Begin
Name := ''; // Player Username
Pass := ''; // Player Password
Pin := ''; // Player Bankpin Number
Nick := ''; // Player Nickname
Worldinfo := [Members,Server];
Boxrewards := ['xp','xp','lamp'];
Lampskill := Skill_Crafting;
Active := True;
End;
End;

procedure SetLocation;
Begin
Flag;
SPS_WalkToPos(OreSpot);
End;

function AutoColorIron: Integer;
var
arP: TPointArray;
arC: TIntegerArray;
tmpCTS, i, arL: Integer;
begin
tmpCTS := GetColorToleranceSpeed;
ColorToleranceSpeed(2);
SetColorSpeed2Modifiers(0.05, 0.93);

FindColorsSpiralTolerance(MSCX, MSCY, arP, 3227492, MSX1, MSY1, MSX2, MSY2, 7);
if (Length(arP) = 0) then
begin
Writeln('Failed to find the color, no result.');
ColorToleranceSpeed(tmpCTS);
SetColorSpeed2Modifiers(0.2, 0.2);
Exit;
end;

arC := GetColors(arP);
ClearSameIntegers(arC);
arL := High(arC);

for i := 0 to arL do
begin
Result := arC[i];
//Writeln('AutoColor = ' + IntToStr(arC[i]));
Break;
end;

ColorToleranceSpeed(tmpCTS);
SetColorSpeed2Modifiers(0.2, 0.2);

if (i = arL + 1) then
Writeln('AutoColor failed in finding the color.');
end;

procedure SelectRock(Choice:Integer); // Select The Type Of Rock To Mine
Begin
Case Choice of
0: Begin // Mine Iron
Colour := AutoColorIron;
TolR := 7;
Desc := 'ron';
Case Random(3) of
0..1: Begin
OreSpot := Point(139,208);
Cam := 150;
End;
2: Begin
OreSpot := Point(95,184);
Cam := 0;
End;
End;
End;
End;
End;

type
TRadial = record
Length: Integer;
Angle: Extended;
Direction: String;
end;
function GetRadial(A, B: TPoint): TRadial; // Credit To Runaway
var // For This Function
Direction: TStringArray;
Angle: Extended;
begin
Direction := ['n', 'e', 's', 'w'];
Angle := Degrees(FixRad((ArcTan2(A.y - B.y, A.x - B.x) + Radians(90)) - Pi));
if not InRange(Round(Angle), 0, 360) then
Exit;
Result.Length := Distance(A.x, A.y, B.x, B.y);
Result.Angle := Angle;
if (Angle >= 315) then
Angle := 360 - Angle;
Result.Direction := Direction[Round(Angle / 90.0)];
end;

Function IsVein(var VBox:TPoint): Boolean;
var
VX, VY, x, y: Integer;
VTPA : Array Of TPoint;
ATPA : T2DPointArray;
i : Integer;

Begin
SMART_DrawBoxEx(True, False, IntToBox(VBox.x - 12, VBox.y - 12, VBox.x + 12, VBox.y + 12), ClWhite)
FindColorsSpiralTolerance(VX, VY, VTPA, Colour, VBox.x - 12, VBox.y - 12, VBox.x + 12, VBox.y + 12, TolR)
Begin
ATPA := SplitTPA(VTPA, 6);
For i := 0 To High(ATPA) Do
Begin
If MiddleTPAEX(ATPA[i], VX, VY) then
Begin
MMouse(VX, VY, 1, 1);
End else
Continue;
WriteLn(GetUpText);
Result := FindColorTolerance(x, y, Colour, VBox.x - 12, VBox.y - 12, VBox.x + 12, VBox.y + 12, TolR);
WriteLn(Result);
Exit;
End;
End;
End;

Function FindOre(var x,y:integer) : Boolean;
var
ItemX, ItemY : Integer;
TPA : Array Of TPoint;
ATPA : T2DPointArray;
i : Integer;
PlayerBox, MBox: TPointArray;
Begin
SMART_ClearMS;
PlayerBox := TPAFromBox(IntToBox(MSCx - 15, MSCy - 25, MSCx + 15, MSCy + 20));
// MiningBox := IntToBox((x + 100),(y + 100),(x - 100),(y - 100));
// SMART_DrawBoxEx(True, False, IntToBox((MSCX - 100), (MSCY - 100), (MSCX + 100), (MSCY + 100)), ClRed);
FindColorsSpiralTolerance(ItemX, ItemY, TPA, Colour, (MSCX - 80), (MSCY - 80), (MSCX + 80), (MSCY + 80), TolR)
ClearTPAFromTPAWrap(TPA, PlayerBox, {var}TPA);
SortTPAFrom(TPA, IntToPoint(MSCx, MSCy));
Begin
ATPA := SplitTPA(TPA, 10);
For i := 0 To High(ATPA) Do
Begin
If MiddleTPAEX(ATPA[i], ItemX, ItemY) then
Begin
MMouse(ItemX, ItemY, 1, 1);
End else
Continue;
If WaitUptext(Desc, 300) Then
Begin
x := ItemX;
y := ItemY;
Writeln('We Have Found The Ore');
Result := True;
Exit;
End;
End;
End;
End;

procedure Mining; // Mining Operations
var
x, y, RockCounter, FailSafeTime, TempTime, Counter, ODistance,
NDistance, TDistance: integer;
Mined:Boolean;
Ore, NOre, Player:Tpoint;
VBox:TBox;
Direction:TRadial;
Begin
If FindNormalRandoms then
Begin
If Not LoggedIn Then
Begin
Writeln('Found unsolvable random');
NextPlayer(False);
End;
End;
MarkTime(FailSafeTime);
Writeln('Clear The Canvas');
SMART_ClearMS;
Writeln('Select The Type Of Ore To Mine');
Mined := False;
SelectRock(OreChoice);
ToggleXPBar(True);
Writeln('Set The Location Of The Ore I`m Going To Mine');
SetLocation;
While IsMoving do
Begin
Wait(50);
If (TimeFromMark(FailSafeTime) > 5000) then
Begin
Break;
End;
End;
MakeCompass(Cam);
Wait(200 + Random(100));
SetAngle(SRL_ANGLE_HIGH);
MarkTime(FailSafeTime);
Mined := False;
Writeln('The Beginning Of the Mining Sequence');
Repeat
Disguise('Starting Mining For ' + Desc);
If FindNormalRandoms then
Begin
If Not LoggedIn Then
Begin
Writeln('Found unsolvable random');
NextPlayer(False);
End;
End;
SelectRock(OreChoice);
While IsMoving Do
Begin
Wait(10);
End;
Writeln('Start Looking For The Ore');
If (FindOre(x, y)) then
Begin
MBox := IntToBox(x - 10, y - 10, x + 10, y + 10);
VBox := IntToBox(x - 15, y - 15, x + 15, y + 15);
SMART_DrawBoxEx(True, False, MBox, ClGreen);
If not(Mined) Then
Begin
ClickMouse2(Mouse_Left);
MarkTime(RockCounter);
MarkTime(FailSafeTime);
Mined := True;
Ore := Point(x, y);
Writeln(Ore);
Player := Point(MSCX, MSCY);
Direction := GetRadial(Ore, Player);
ODistance := Direction.Length;
Writeln(Direction);
Writeln('Clicked The Ore To Start Mining');
End;
// Wait(RandomRange(800, 1200));
End;
While IsMoving Do
Begin
SMART_ClearCanvasArea(VBox);
Player := Point(MSCX, MSCY);
Direction := GetRadial(Ore, Player);
NDistance := Direction.Length;
Writeln('New TPoint For Ore');
TDistance = (ODistance - NDistance);
ODistance := NDistance;
NOre := Point(x, y - TDistance);
Ore := NOre;
Writeln('Create New Box');
VBox := IntToBox(NOre.x - 20, NOre.y - 20, NOre.x + 20, NOre.y + 20);
SMART_DrawBoxEx(True, False, IntToBox(NOre.x - 12, NOre.y - 12, NOre.x + 12, NOre.y + 12), ClWhite)
End;
Antiban;
While IsVein(NOre) or not(FindBlackChatMessage('nage')) or (TimeFromMark(RockCounter) > (3700 + Random(300))) and (not(IsMining)) do
Begin
Writeln('Looking For The Vein Color');
If FindNormalRandoms then
Begin
If Not LoggedIn Then
Begin
Writeln('Found unsolvable random');
NextPlayer(False);
End;
End;
End;
{ Repeat
Writeln('Looking For The Vein Color');
If FindNormalRandoms then
Begin
If Not LoggedIn Then
Begin
Writeln('Found unsolvable random');
NextPlayer(False);
End;
End;
Until {not(IsVein(NOre)) or }(FindBlackChatMessage('nage')) or (TimeFromMark(RockCounter) > (3700 + Random(300))) and (not(IsMining));}
Writeln('Starting Next Loop For Finding Ore');
Mined := False;
SMART_ClearCanvasArea(VBox);
Until (InvFull);
End;

procedure SetupClient; // Setup Client For Run
Begin
WriteLn('Start Bot Client');
SRL_SIXHOURFIX := True;
SMART_FIXSPEED := True;
Setupsrl;
SRL_EnableNavBar;
Objdtm_Setup;
DeclarePlayers;
If not (loggedin) then
Begin
LoginPlayertoLob;
OpenWorldScreen;
SelectWorld(Server);
LoginPlayer;
Wait(4000+Random(400));
End;
SPS_Setup(RUNESCAPE_OTHER,['remington']);
End;

Begin // Begin Main Loop
SetupClient;
SetAngle(srl_angle_high);
// Repeat
Mining;
// Until allplayersinactive;
End.

I can`t believe that a Function was not already created for the Includes for srl that could do this as I don`t think I`m the only one who would find something like this very useful to use in scripts.

Maybe Someone should create such a function and make a request that it should be included in the srl includes.

The Only time you should need this is when you are moving from one place to another object or place.

Or is there already a function which do exactly what i`m trying to find here? And if so can someone share it and show examples of how to use it.

Thanks guys.

E. Also what would work better, the while do loop or repeat until?
E2. If I use
Direction.Length
to get the distance value I`m receiving errors, what do I do wrong when trying to get the custom type`s value. Direction was declared as a TRadial
type
TRadial = record
Length: Integer;
Angle: Extended;
Direction: String;
end;

Runaway

2012-08-31 11:45:42

I haven't tested your script yet, but the distance isn't working because you've made a mistake setting the Distance vars:


// First
Direction := GetRadial(Ore, Player);
Distance := Direction.Length; // <- Should be ODistance

// Second
Direction := GetRadial(Ore, Player);
NDistance := Direction.Length;

TDistance = (ODistance - NDistance);


Interesting use of length though :o I'm not entirely sure how well it would work in this situation since you're using the same values in GetRadial each time. Now that I think about it… you might be able to do something much more simple!


//
ClickMouse2(mouse_Left);
Writeln('Clicked The Ore To Start Mining');
MarkTime(RockCounter);
MarkTime(FailSafeTime);
Mined := True;
Ore := Point(x, y);
Player := Point(MSCX, MSCY);
Radial := GetRadial(Ore, Player);
Wait(500+Random(250));
while IsMoving or FlagPresent do
Wait(100);
SMART_ClearCanvasArea(VBox);
case Lowecase(Radial.Direction) of
'n': NOre := Point(MSCX, MSCY - 40);
'e': NOre := Point(MSCX + 40, MSCY);
's': NOre := Point(MSCX, MSCY + 40);
'w': NOre := Point(MSCX - 40, MSCY);
end;
// etc.

Since you know you'll be right next to whatever ore you're mining, you should be able to use the MS constants to figure out where to check. All in theory though :pinch:

VastlySuperior

2012-08-31 12:16:20

From: Runaway
I haven't tested your script yet, but the distance isn't working because you've made a mistake setting the Distance vars:


// First
Direction := GetRadial(Ore, Player);
Distance := Direction.Length; // <- Should be ODistance

// Second
Direction := GetRadial(Ore, Player);
NDistance := Direction.Length;

TDistance = (ODistance - NDistance);


Interesting use of length though :o I'm not entirely sure how well it would work in this situation since you're using the same values in GetRadial each time. Now that I think about it… you might be able to do something much more simple!


//
ClickMouse2(mouse_Left);
Writeln('Clicked The Ore To Start Mining');
MarkTime(RockCounter);
MarkTime(FailSafeTime);
Mined := True;
Ore := Point(x, y);
Player := Point(MSCX, MSCY);
Radial := GetRadial(Ore, Player);
Wait(500+Random(250));
while IsMoving or FlagPresent do
Wait(100);
SMART_ClearCanvasArea(VBox);
case Lowecase(Radial.Direction) of
'n': NOre := Point(MSCX, MSCY - 40);
'e': NOre := Point(MSCX + 40, MSCY);
's': NOre := Point(MSCX, MSCY + 40);
'w': NOre := Point(MSCX - 40, MSCY);
end;
// etc.

Since you know you'll be right next to whatever ore you're mining, you should be able to use the MS constants to figure out where to check. All in theory though :pinch:


Yes my logic was a bit off there. I have corrected it in the post as well as added the correct steps, I think in using that.

    While IsMoving Do
Begin
SMART_ClearCanvasArea(VBox);
Player := Point(MSCX, MSCY);
Direction := GetRadial(Ore, Player);
NDistance := Direction.Length;
Writeln('New TPoint For Ore');
TDistance = (ODistance - NDistance);
ODistance := NDistance;
NOre := Point(x, y - TDistance);
Ore := NOre;
Writeln('Create New Box');
VBox := IntToBox(NOre.x - 20, NOre.y - 20, NOre.x + 20, NOre.y + 20);
SMART_DrawBoxEx(True, False, IntToBox(NOre.x - 12, NOre.y - 12, NOre.x + 12, NOre.y + 12), ClWhite)
End;

I will test your new suggestion now and give you some feedback on that. I think That would rather be much more easy to do than what I was thinking of doing with the distance and the degrees.

E. Its not working, If the angles were square, your suggestion might have worked, but because it does not end up all the time precisely north east west or south the box is once again misformed, the value 40 is also not always accurate as you get big rocks and smaller rocks.

My own idea is also not up to par as it moves like something out of a very lagy connection and the x axis is totally off, but the Y axis seems to line up. If only you could take the distance to the object, the angle or degrees at which you are in relation to the object and took those 2 values and make a calculation on how many pixels the x axis have to shift then maybe it would work. I just don`t know. It seems this is a lost cause unless another way could be found to select the rock you have previously clicked.

P1ng

2012-08-31 23:25:17

I don't check for IsOre to be true until I have stopped moving, thus it doesn't just check as soon as it's clicked the rock, it will wait until it starts moving then wait while it is moving. then when it stops it will check for IsOre thus it checks the closes rock which usually is the correct one you want. Still having some minor issues, but Runaway's function should be able to overcome these minor issues.