SRL Archive - MSI Suggestions

Relocater


Coh3n

2010-07-09 15:38:57

From: Coh3n
Alright guys I worked on this for the last hour or so. What I have here is a similar system to walking, except for minimap areas. There's both color and reflection relocation points (a path may or may not work) in the TLocation record, just like there is in the TPath record.

const
RELOCATE_MIN_DIST = 3;

type
TMMColorArea = record
Symbol : string;
DTM : Integer;
W, H : Integer;
Colors : TIntegerArray;
Tolerances : TIntegerArray;
Counts : TIntegerArray;
Bounds : TBox;
end;

TMMColorAreaArray = array of TMMLocation;

type
TLocation = record
Name : string;
Constant : Integer;
RelocatePoints: TPointArray; // Length of these arrays have to be the same,
RelocateAreas : TIntegerArray; // similar to the length of Color/Ref walking paths
end;

var
MSI_ColorAreas: array[0..AREA_ARRAY_LENGTH] of TMMColorArea;

function MSI_LoadColorArea(Which: Integer): Boolean;
begin
case Which of
GE_YEWS_1:
with MSI_ColorAreas[Which] do
begin
end;

GE_YEWS_2:
with MSI_ColorAreas[Which] do
begin
end;
end;

Result := (MSI_ColorAreas[Which].DTM <> -1);
end;

procedure MSI_LoadAllColorAreas;
var
i: Integer;
begin
for i := 0 to High(MSI_ColorAreas) do
MSI_LoadColorArea(i);
end;

{******************************************************************************}
{ function MSI_RelocateColor(...): Boolean; }
{ By: marpis }
{ Description: Finds a location in minimap. First tries to find DTM, then }
{ colors, and if still not found it will find it by symbol }
{******************************************************************************}
function MSI_RelocateColor(var P: TPoint; Location, Index: Integer): Boolean;
Var
SA, EA, tmp_Ang: Extended;
N, I, II, III, H, HH, X, Y, Score, Step: Integer;
ATPA: T2DPointArray;
tmp_TPA: TPointArray;
X1, Y1, X2, Y2: Integer;
Loc: TLocation;
begin
Result := False;
P := Point(-1, -1);

if (not LoggedIn) then
Exit;

if (Length(MSI_Locations[Location].RelocateAreas) <= 0) then
Exit;

Loc := MSI_ColorAreas[MSI_Locations[Location].RelocateAreas[Index]];
Step := (Loc.W * Loc.H) / 10;

{ DTM Search }
if (Loc.DTM > -1) then
while (N < 10) do
begin
if FindDTMRotated(Loc.DTM, X, Y, MMX1, MMY1, MMX2, MMY2, SA, EA, 0.02, tmp_Ang) then
begin
Result := True;
P := Point(X, Y);
MSI_SubDebug('Found relocation point via DTM: (' + IntToStr(P.X) + ', ' + IntToStr(P.Y) + ')');
Exit;
end;
Inc(N);
SA := SA - (N * 0.02);
EA := EA + (N * 0.02);
end;

{ Color search }
if (Length(Loc.Colors) > 0) then
begin
H := High(Loc.Colors);
SetLength(ATPA, H + 1);

for I := 0 to H do
begin
FindColorsSpiralTolerance(MMCX, MMCY, ATPA[I], Loc.Colors[I], MMX1, MMY1, MMX2, MMY2, Loc.Tolerances[I]);
FilterPointsPie(ATPA[I], 0.0, 360.0, 0.0, 76.0, MMCX, MMCY);
end;

{ Go through every TPA that contains one color. }
for I := 0 to H do
begin
HH := High(ATPA[I]);

{ Go through every 10th point in ATPA[I] to avoid lag. }
for II := 0 to HH do
begin
if ((II mod Step) <> 0) then
Continue;

Score := 0;

X1 := ATPA[I][II].X - (Loc.W / 2);
Y1 := ATPA[I][II].Y - (Loc.H / 2);
X2 := ATPA[I][II].X + (Loc.W / 2);
Y2 := ATPA[I][II].Y + (Loc.H / 2);

{ Go through every TPA again, calculating surrounding color counts. }
for III := 0 to H do
begin
tmp_TPA := MSI_ReturnPointsInBox(ATPA[III], IntToBox(X1, Y1, X2, Y2));
if (Length(tmp_TPA) >= Loc.Counts[III]) then
Inc(Score);
end;

{ If there are enough points of all colors, the location has been found. }
if (Score = H) then
begin
Result := True;
X := (X1 + X2) shr 1;
Y := (Y1 + Y2) shr 1;
P := Point(X, Y);
MSI_SubDebug('Found relocation point via color: (' + IntToStr(P.X) + ', ' + IntToStr(P.Y) + ')');
Exit;
end;

end;
end;
end;

{ Symbol Search }
if (Loc.Symbol <> '') then
if FindSymbol(X, Y, Loc.Symbol) then
begin
Result := True;
P := Point(X, Y);
MSI_SubDebug('Found relocation point via symbol: (' + IntToStr(P.X) + ', ' + IntToStr(P.Y) + ')');
Exit;
end;
end;

function MSI_RelocateRef(var p: TPoint; Location, Index: Integer): Boolean;
begin
Result := False;
p := Point(-1, -1);

{$IFDEF REFLECTION}
P := TileToMM(MSI_Locations[Location].RelocatePoints[Index]);
Result := ((p.x > 0) and (p.y > 0));
{$ENDIF}
end;

function MSI_Relocate(Loc: Integer): Boolean;
var
i: Integer;
p: TPoint;
begin
MSI_AddHeader('MSI_Relocate');

for i := 0 to High(MSI_Locations[Loc].RelocatePoints) do
begin
if (not MSI_RelocateRef(p, Loc, i)) then
if (not MSI_RelocateColor(p, Loc, i)) then
Exit;

if (Distance(p.x, p.y, MMCX, MMCY) > RELOCATE_MIN_DIST) then
begin
Mouse(p.x, p.y, 4, 4, True);
MSI_SubDebug('Walking to Point(' + IntToStr(p.x) + ', ' + IntToStr(p.y) + ')');
MSI_Flag;
Result := True;
Break;
end;
end;

MSI_CloseHeader('MSI_Relocate: ' + BoolToStr(Result));
end;
Couple things:
  • I kept RELOCATE_MIN_DIST a constant because I really don't think it needs to be location specific. However, I could easily be proved to be wrong.
  • All of this code (excluding const, vars and types) would go in Relocate.simba, unless there's a better place.


What do you guys think?

NCDS

2010-07-09 15:57:32

Shouldn't

If (Length(Location.Colors) = 0) Then
be

If (Length(Location.Colors) > 0) Then
?

From: Coh3n

Off the top of my head, we could just have it relocate if no trees are found

As long as we waited for a few seconds first to make sure that all the trees just weren't chopped down at that moment.

Other than that, everything looks pretty good at a glance :)

Sir R. M8gic1an

2010-07-09 15:59:46

Looks good. But imo it'll need one more layer.


First of all, if the Color relocation returns (x,y), so should the ref relocation return it. Remember you always have to keep them "equal", otherwise you'll run into trouble later when you have to treat them differently.

TScript = record
Relocators: TIntegerArray //notice this, several relocating points

function MSI_RelocateColor(var TP: TPoint; ...): boolean;
function MSI_RelocateRef(var TP: TPoint; ...): boolean;

function MSI_Relocate: boolean;
var
i: integer;
TP: TPoint;
begin
for i:= High(MSI_Locs[thisLoc].Relocators) DownTo 0 do
begin
if not RelocateColor then
if not RelocateRef then
begin
writeln('TLoc failed');
continue;
end;

if distance(TP.x, TP.y, MMCX, MMCY) > MIN_RELOC_DIS then
begin
//mouse stuff
end else
continue;

end;
end;

What this MIN_RELOC_DIS allows, (and it maybe shouldn't be a const, but rather setup per script) is that if you are cutting a yew, you won't go back to the same exact yew. You'll go to another one.

~RM

NCDS

2010-07-09 16:09:45

From: Rasta Magician
Looks good. But imo it'll need one more layer.


First of all, if the Color relocation returns (x,y), so should the ref relocation return it. Remember you always have to keep them "equal", otherwise you'll run into trouble later when you have to treat them differently.

TScript = record
Relocators: TIntegerArray //notice this, several relocating points

function MSI_RelocateColor(var TP: TPoint; ...): boolean;
function MSI_RelocateRef(var TP: TPoint; ...): boolean;

function MSI_Relocate: boolean;
var
i: integer;
TP: TPoint;
begin
for i:= High(MSI_Locs[thisLoc].Relocators) DownTo 0 do
begin
if not RelocateColor then
if not RelocateRef then
begin
writeln('TLoc failed');
continue;
end;

if distance(TP.x, TP.y, MMCX, MMCY) > MIN_RELOC_DIS then
begin
//mouse stuff
end else
continue;

end;
end;

What this MIN_RELOC_DIS allows, (and it maybe shouldn't be a const, but rather setup per script) is that if you are cutting a yew, you won't go back to the same exact yew. You'll go to another one.

~RM


Definitely should be set up script by script, but I really like the idea :)

3Garrett3

2010-07-09 16:45:44

From: NCDS
Definitely should be set up script by script, but I really like the idea :)


Yeah, the tiles will have to be set in the TScript record for sure.

Coh3n

2010-07-09 17:25:42

Sounds good, except we don't currently have reflection as a colour failsafe because 80% of the colour walking hasn't been developed. The script either uses one or the other (depending on what the user decides). Seems like it would work well enough.

Sir R. M8gic1an

2010-07-09 17:42:34

well about that, lets save ourselves time


//bad
if UseRef then
RefStuff
else
ColorStuff

//good

if not ColorStuff then
if not RefStuff then
writeln('we failed');

//and just have ColorStuff return false

~RM

NCDS

2010-07-09 17:44:45

From: Rasta Magician
well about that, lets save ourselves time


//bad
if UseRef then
RefStuff
else
ColorStuff

//good

if not ColorStuff then
if not RefStuff then
writeln('we failed');

//and just have ColorStuff return false

~RM


I like that. I feel that there should be as little user input required as possible to run MSI, and that just cuts out one more thing :)

Coh3n

2010-07-09 17:47:11

But then the user has to download reflection no matter what, which I guess isn't a big deal, but the way it's setup now is so they can just comment out the DEFINE REFLECTION and they'll be fine. Like if they were to use a script that doesn't use reflection, they would still have to download it.

NCDS

2010-07-09 17:51:48

From: Coh3n
But then the user has to download reflection no matter what, which I guess isn't a big deal, but the way it's setup now is so they can just comment out the DEFINE REFLECTION and they'll be fine. Like if they were to use a script that doesn't use reflection, they would still have to download it.


If a user doesn't have Reflection, they wont be able to run too much for a while considering our only current color walking is for VE normals and oaks. So I would assume that anyone running MSI most likely has Reflection already, why not make it a requirement?

Coh3n

2010-07-09 17:53:47

From: NCDS
If a user doesn't have Reflection, they wont be able to run too much for a while considering our only current color walking is for VE normals and oaks. So I would assume that anyone running MSI most likely has Reflection already, why not make it a requirement?

Yeah, probably wouldn't be a big deal. It would make the code cleaner, which you know I would love. :rolleyes:

Sir R. M8gic1an

2010-07-09 18:00:27

It doesn't force anything on anyone.


function RefSomething: boolean;
begin
Result := false;
{$IFDEF REFLECTION} //this is defined when ref is included, if im not mistaken

//stuff
//stuff
//stuff
{$ENDIF}
end;

~RM

Coh3n

2010-07-09 18:26:51

From: Rasta Magician
It doesn't force anything on anyone.


function RefSomething: boolean;
begin
Result := false;
{$IFDEF REFLECTION} //this is defined when ref is included, if im not mistaken

//stuff
//stuff
//stuff
{$ENDIF}
end;

~RM

But we include Reflection.simba in Setup.scar if it's defined. If we don't define it, it won't compile. If we don't define it and we use

if not Ref then
if not Color then
then we'll get unknown identifiers because since reflection isn't defined, the reflection functions aren't loaded.

Sir R. M8gic1an

2010-07-10 04:51:03

We can load our own reflection stuff, and call our own stuff.

It'll have the IFDEF in there, so it won't compile any of the code that is reflection related unless it's defined, therefore it'll compile because there's no uncompilable code :p

edit: my mistake, but i'll be posting so that Reflection.simba has {$DEFINE REFLECTION} in there. This will allow eaiser management in general and easier management for us.

~RM

Coh3n

2010-07-10 09:53:41

There's no way to exclude reflection and not get unknown identifiers unless we stick with what we have now, which I don't see a problem with. There's only one funtion (MSI_PerformWalk) that uses the ReflectionBroken variable. I guess I just don't understand the advantages of going away from what we currently use.

Nava2

2010-07-10 10:39:06

From: Coh3n
There's no way to exclude reflection and not get unknown identifiers unless we stick with what we have now, which I don't see a problem with. There's only one funtion (MSI_PerformWalk) that uses the ReflectionBroken variable. I guess I just don't understand the advantages of going away from what we currently use.


Thats what Defines are for, friend.

marpis

2010-07-10 10:43:20

From: NCDS
Shouldn't

If (Length(Location.Colors) = 0) Then
be

If (Length(Location.Colors) > 0) Then
?


Lol, yes. :p

Coh3n

2010-07-10 11:22:14

From: Nava2
Thats what Defines are for, friend.

Yeah we got it figured out.

lordsaturn

2010-07-14 13:51:02

I think color should be used as a failsafe for reflection.

Coh3n

2010-07-14 13:52:18

From: lordsaturn
I think color should be used as a failsafe for reflection.

Yeah, I think that's what we're going to do. :)

3Garrett3

2010-07-25 13:09:11

What is the progress on this? Any?

Coh3n

2010-07-25 13:09:47

From: 3Garrett3
What is the progress on this? Any?

Nothing more then what's on the first post.

Coh3n

2010-08-02 20:06:57

Okay, so I've added the TLocation type and Locations.simba. Right now it only loads the Location name and constant. This will make it much easier for our Player Remote extension.

The rest of the relocator will come soon. :)

Awkwardsaw

2010-08-05 11:17:35

From: Coh3n
Okay, so I've added the TLocation type and Locations.simba. Right now it only loads the Location name and constant. This will make it much easier for our Player Remote extension.

The rest of the relocator will come soon. :)


can't wait. its not fun walking an army to locations :p

is there anything else you need?

Coh3n

2010-08-05 11:27:50

From: Awkwardsaw
can't wait. its not fun walking an army to locations :p

That's not exactly what it does…

It will be used for scripts that require movement to a different point. For example, Grand Exchange Yews has 2 trees and with the relocator, we can move to the second tree when the first one is cut down (otherwise it's not visible in the screen).

For what you want, I'm pretty sure RM wrote an Army Relocator somewhere that will walk for city to city.

Awkwardsaw

2010-08-05 12:09:25

ah, ok :p

Sir R. M8gic1an

2010-08-05 21:01:59

My army relocater is in SRL Members.

~RM

Coh3n

2010-08-18 01:12:24

Alright guys I worked on this for the last hour or so. What I have here is a similar system to walking, except for minimap areas. There's both color and reflection relocation points (a path may or may not work) in the TLocation record, just like there is in the TPath record.

const
RELOCATE_MIN_DIST = 3;

type
TMMColorArea = record
Symbol : string;
DTM : Integer;
W, H : Integer;
Colors : TIntegerArray;
Tolerances : TIntegerArray;
Counts : TIntegerArray;
Bounds : TBox;
end;

TMMColorAreaArray = array of TMMLocation;

type
TLocation = record
Name : string;
Constant : Integer;
RelocatePoints: TPointArray; // Length of these arrays have to be the same,
RelocateAreas : TIntegerArray; // similar to the length of Color/Ref walking paths
end;

var
MSI_ColorAreas: array[0..AREA_ARRAY_LENGTH] of TMMColorArea;

function MSI_LoadColorArea(Which: Integer): Boolean;
begin
case Which of
GE_YEWS_1:
with MSI_ColorAreas[Which] do
begin
end;

GE_YEWS_2:
with MSI_ColorAreas[Which] do
begin
end;
end;

Result := (MSI_ColorAreas[Which].DTM <> -1);
end;

procedure MSI_LoadAllColorAreas;
var
i: Integer;
begin
for i := 0 to High(MSI_ColorAreas) do
MSI_LoadColorArea(i);
end;

{******************************************************************************}
{ function MSI_RelocateColor(...): Boolean; }
{ By: marpis }
{ Description: Finds a location in minimap. First tries to find DTM, then }
{ colors, and if still not found it will find it by symbol }
{******************************************************************************}
function MSI_RelocateColor(var P: TPoint; Location, Index: Integer): Boolean;
Var
SA, EA, tmp_Ang: Extended;
N, I, II, III, H, HH, X, Y, Score, Step: Integer;
ATPA: T2DPointArray;
tmp_TPA: TPointArray;
X1, Y1, X2, Y2: Integer;
Loc: TLocation;
begin
Result := False;
P := Point(-1, -1);

if (not LoggedIn) then
Exit;

if (Length(MSI_Locations[Location].RelocateAreas) <= 0) then
Exit;

Loc := MSI_ColorAreas[MSI_Locations[Location].RelocateAreas[Index]];
Step := (Loc.W * Loc.H) / 10;

{ DTM Search }
if (Loc.DTM > -1) then
while (N < 10) do
begin
if FindDTMRotated(Loc.DTM, X, Y, MMX1, MMY1, MMX2, MMY2, SA, EA, 0.02, tmp_Ang) then
begin
Result := True;
P := Point(X, Y);
MSI_SubDebug('Found relocation point via DTM: (' + IntToStr(P.X) + ', ' + IntToStr(P.Y) + ')');
Exit;
end;
Inc(N);
SA := SA - (N * 0.02);
EA := EA + (N * 0.02);
end;

{ Color search }
if (Length(Loc.Colors) > 0) then
begin
H := High(Loc.Colors);
SetLength(ATPA, H + 1);

for I := 0 to H do
begin
FindColorsSpiralTolerance(MMCX, MMCY, ATPA[I], Loc.Colors[I], MMX1, MMY1, MMX2, MMY2, Loc.Tolerances[I]);
FilterPointsPie(ATPA[I], 0.0, 360.0, 0.0, 76.0, MMCX, MMCY);
end;

{ Go through every TPA that contains one color. }
for I := 0 to H do
begin
HH := High(ATPA[I]);

{ Go through every 10th point in ATPA[I] to avoid lag. }
for II := 0 to HH do
begin
if ((II mod Step) <> 0) then
Continue;

Score := 0;

X1 := ATPA[I][II].X - (Loc.W / 2);
Y1 := ATPA[I][II].Y - (Loc.H / 2);
X2 := ATPA[I][II].X + (Loc.W / 2);
Y2 := ATPA[I][II].Y + (Loc.H / 2);

{ Go through every TPA again, calculating surrounding color counts. }
for III := 0 to H do
begin
tmp_TPA := MSI_ReturnPointsInBox(ATPA[III], IntToBox(X1, Y1, X2, Y2));
if (Length(tmp_TPA) >= Loc.Counts[III]) then
Inc(Score);
end;

{ If there are enough points of all colors, the location has been found. }
if (Score = H) then
begin
Result := True;
X := (X1 + X2) shr 1;
Y := (Y1 + Y2) shr 1;
P := Point(X, Y);
MSI_SubDebug('Found relocation point via color: (' + IntToStr(P.X) + ', ' + IntToStr(P.Y) + ')');
Exit;
end;

end;
end;
end;

{ Symbol Search }
if (Loc.Symbol <> '') then
if FindSymbol(X, Y, Loc.Symbol) then
begin
Result := True;
P := Point(X, Y);
MSI_SubDebug('Found relocation point via symbol: (' + IntToStr(P.X) + ', ' + IntToStr(P.Y) + ')');
Exit;
end;
end;

function MSI_RelocateRef(var p: TPoint; Location, Index: Integer): Boolean;
begin
Result := False;
p := Point(-1, -1);

{$IFDEF REFLECTION}
P := TileToMM(MSI_Locations[Location].RelocatePoints[Index]);
Result := ((p.x > 0) and (p.y > 0));
{$ENDIF}
end;

function MSI_Relocate(Loc: Integer): Boolean;
var
i: Integer;
p: TPoint;
begin
MSI_AddHeader('MSI_Relocate');

for i := 0 to High(MSI_Locations[Loc].RelocatePoints) do
begin
if (not MSI_RelocateRef(p, Loc, i)) then
if (not MSI_RelocateColor(p, Loc, i)) then
Exit;

if (Distance(p.x, p.y, MMCX, MMCY) > RELOCATE_MIN_DIST) then
begin
Mouse(p.x, p.y, 4, 4, True);
MSI_SubDebug('Walking to Point(' + IntToStr(p.x) + ', ' + IntToStr(p.y) + ')');
MSI_Flag;
Result := True;
Break;
end;
end;

MSI_CloseHeader('MSI_Relocate: ' + BoolToStr(Result));
end;
Couple things:
  • I kept RELOCATE_MIN_DIST a constant because I really don't think it needs to be location specific. However, I could easily be proved to be wrong.
  • All of this code (excluding const, vars and types) would go in Relocate.simba, unless there's a better place.

What do you guys think?

marpis

2010-08-18 05:23:32

Whee! :)
Looking good. I think you should also debug "Found relocation point via color/symbol/reflection/dtm".

And remember folks, if you want to make a color relocation point, you don't need to enter the color info, just a DTM can be enough.

Coh3n

2010-08-18 11:23:20

From: marpis
Whee! :)
Looking good. I think you should also debug "Found relocation point via color/symbol/reflection/dtm".

And remember folks, if you want to make a color relocation point, you don't need to enter the color info, just a DTM can be enough.

Done.

Coh3n

2010-09-06 23:21:17

I've added Relocate.simba. All that's left is to update the TLocation records with some points, and then testing.

E: This is now setup for all woodcutting scripts. RelocatePoints have been made for SCRIPT_RM_YEWS and SCRIPT_GE_YEWS. Seems to work pretty well. The support for mining and fishing will come shortly. :)

Testing is always appreciated.

Coh3n

2010-09-23 17:56:22

This is up and running for all skills. Necessary points are all that needs to be added to locations (if they require a relocation point).