Sir R. M8gic1an
2010-12-01 07:14:57
I'm not sure about the wording for the threads' title, but here's my idea:
MSI has tutorials on how to code for MSI.
But MSI doesn't have tutorials on how it actually works.
I put it out as a challenge to members to figure out how MSI works and to write tutorials about it ;)
MSI has some of the best colour functions ever developed.
Reading through MSI would not only be great for you,
Reading through MSI and making tutorials would be great for everyone.
Here is a great place to start:
These are the colour object finding routines of MSI.
This is the very core of MSI's success.
There's a lot more to it of course ;) But if someone is actually able to pick up on all the techniques the MSI Devs used on these functions, it'd already be a very good start. :)
~RM
MSI has tutorials on how to code for MSI.
But MSI doesn't have tutorials on how it actually works.
I put it out as a challenge to members to figure out how MSI works and to write tutorials about it ;)
MSI has some of the best colour functions ever developed.
Reading through MSI would not only be great for you,
Reading through MSI and making tutorials would be great for everyone.
Here is a great place to start:
{******************************************************************************}
{ Function MSI_FindObjectsTPA( ... ): Boolean; }
{ By: marpis }
{ Date: 25 June 2010 }
{ Description: Finds objects in mainscreen, saves co-ords in TPA }
{******************************************************************************}
Function MSI_FindObjectsTPA(Var Objs: TPointArray; ObjID: integer; SearchBox: TBox): Boolean;
Var
TPA, TempTPA: TPointArray;
ATPA: T2DPointArray;
I, II, CTS, TMP, H: Integer;
Box: TBox;
Boxes: TBoxArray;
Animating2: TBooleanArray;
BadPoint: Boolean;
Begin
If (Not LoggedIn) Then Exit;
CTS := GetColorToleranceSpeed;
ColorToleranceSpeed(2);
SetColorSpeed2Modifiers(MSI_Objects[objID].Hue, MSI_Objects[objID].Sat);
Box := IntToBox(228, 150, 275, 200);
H := High(MSI_Objects[objID].Colors);
SetLength(ATPA, H + 1);
For I := 0 To H Do
FindColorsSpiralTolerance(MSCX, MSCY, ATPA[I], MSI_Objects[objID].Colors[I], SearchBox.X1, SearchBox.Y1, SearchBox.X2, SearchBox.Y2, MSI_Objects[objID].Tol);
ColorToleranceSpeed(CTS);
SetColorSpeed2Modifiers(0.2, 0.2);
{ Check if some of the colors was not on MS. }
If MSI_Objects[objID].FindAllColors Then
For I := 0 To H Do
If (Length(ATPA) < 1) Then
Begin
MSI_SubDebug('MSI_FindObjectsTPA: All colors weren''t found!');
Objs := [];
Exit;
End;
{ Check if we have enough pixels on MS. }
TPA := MergeATPA(ATPA);
If (Length(TPA) < MSI_Objects[objID].Accuracy) Then
Begin
MSI_SubDebug('MSI_FindObjectsTPA: No colors found!');
Objs := [];
Exit;
End;
ATPA := TPAtoATPAEx(TPA, MSI_Objects[objID].W, MSI_Objects[objID].H);
SortATPAFrom(ATPA, Point(MSCX, MSCY));
H := High(ATPA);
SetLength(TPA, H + 1);
if DEBUG_SMART then
DrawDotsMulti(true, ATPA);
For I := 0 To H Do
TPA[I] := MiddleTPA(ATPA[I]);
H := High(TPA);
SetLength(Boxes, H + 1);
For I := 0 To H Do
Begin
Boxes[I].X1 := TPA[I].X - (MSI_Objects[objID].W / 2);
Boxes[I].Y1 := TPA[I].Y - (MSI_Objects[objID].H / 2);
Boxes[I].X2 := TPA[I].X + (MSI_Objects[objID].W / 2);
Boxes[I].Y2 := TPA[I].Y + (MSI_Objects[objID].H / 2);
End;
If MSI_Objects[objID].Anim Then
Animating2 := AnimatingMulti(Boxes, 100, 1);
For I := 0 To High(TPA) Do
Begin
BadPoint := False;
//DrawBox(Boxes[I], 200);
{ Animation }
If (Not BadPoint) Then
If MSI_Objects[objID].Anim Then
If (Not Animating2[I]) Then
Begin
MSI_SubDebug('MSI_FindObjectsTPA: Not animating!');
BadPoint := True;
End;
{ Exclude own character }
If (Not BadPoint) Then
If MSI_Objects[objID].ExcludeSelf Then
If PointInBox(TPA[I], Box) Then
Begin
MSI_SubDebug('MSI_FindObjectsTPA: Own character!');
BadPoint := True;
End;
{ Invalid point }
If (Not BadPoint) Then
If ((TPA[I].X + TPA[I].Y) < 1) Then
Begin
MSI_SubDebug('MSI_FindObjectsTPA: Invalid point!');
BadPoint := True;
End;
{ Accuracy }
If (Not BadPoint) Then
If (Length(ATPA[I]) < MSI_Objects[objID].Accuracy) Then
Begin
MSI_SubDebug('MSI_FindObjectsTPA: Not enough points!');
BadPoint := True;
End;
{ Bad colors }
If (Not BadPoint) Then
For II := 0 To High(MSI_Objects[objID].BadColors) Do
Begin
MSI_SubDebug('MSI_FindObjectsTPA: Looking for bad color: '+IntToStr(MSI_Objects[objID].BadColors[II]));
If FindColorSpiralTolerance(TMP, TMP, MSI_Objects[objID].BadColors[II], TPA[I].X - (MSI_Objects[objID].W / 2), TPA[I].Y - (MSI_Objects[objID].H / 2), TPA[I].X + (MSI_Objects[objID].W / 2), TPA[I].Y + (MSI_Objects[objID].H / 2), MSI_Objects[objID].BadColorTolerance) Then
Begin
MSI_SubDebug('MSI_FindObjectsTPA: Bad color found!');
BadPoint := True;
Break;
End;
End;
{ FindAllColors }
If (Not BadPoint) Then
If MSI_Objects[objID].FindAllColors Then
For II := 0 To H Do
Begin
TempTPA := MSI_ReturnPointsInBox(ATPA[II], IntToBox(TPA[I].X - (MSI_Objects[objID].W / 2), TPA[I].Y - (MSI_Objects[objID].H / 2), TPA[I].X + (MSI_Objects[objID].W / 2), TPA[I].Y + (MSI_Objects[objID].H / 2)));
If (Length(TempTPA) < 1) Then
Begin
MSI_SubDebug('MSI_FindObjectsTPA: All colors weren''t found!');
BadPoint := True;
Break;
End;
End;
{ Valid point! }
If (Not BadPoint) Then
Begin
SetLength(Objs, Length(Objs) + 1);
Objs[High(Objs)] := TPA[I];
End;
End;
Result := (Length(Objs) > 0);
End;
{******************************************************************************}
{ function MSI_TrackObject(var ObjInfo: TMSObject): boolean; }
{ By: marpis & Sir R. Magician }
{ Date: 09 August 2010 }
{ Description: Follows object while moving (ObjInfo.X, ObjInfo.Y) }
{******************************************************************************}
function MSI_TrackObject(ObjID: integer): boolean;
var
ATPA: T2DPointArray;
TPA: TPointArray;
CTS, T, Tries: integer;
B: TBox;
Previous: TPoint;
BreakNext: boolean;
DistMultiplier: extended;
begin
MSI_AddHeader('Track Object');
Result := true;
Track_Search(T_TrackObject);
CTS := GetColorToleranceSpeed;
ColorToleranceSpeed(2);
SetColorSpeed2Modifiers(MSI_Objects[ObjID].Hue, MSI_Objects[ObjID].Sat);
//Preparing vars for loop
DistMultiplier := Distance(MSCX, MSCY, MSI_Objects[ObjID].X, MSI_Objects[ObjID].Y) / 40;
if DistMultiplier < 1.0 then DistMultiplier := 1.0;
BreakNext := false;
Previous := Point(MSI_Objects[ObjID].X, MSI_Objects[ObjID].Y);
T := GetSystemTime + 30000;
repeat
B := MSI_MakeBox(Point(MSI_Objects[ObjID].X, MSI_Objects[ObjID].Y),
round(MSI_Objects[ObjID].W * DistMultiplier),
round(MSI_Objects[ObjID].H * DistMultiplier));
SMART_DrawBoxEx(True, B, clYellow);
if MSI_FindObjectsTPA(TPA, ObjID, B) then
begin
ATPA := SplitTPA(TPA, MSI_Objects[ObjID].W);
SortATPAFromFirstPoint(ATPA, Point(MSCX, MSCY));
MiddleTPAEx(ATPA[0], MSI_Objects[ObjID].X, MSI_Objects[ObjID].Y);
if tries = 1 then
begin
tries := 0;
DistMultiplier := DistMultiplier - 1.0; //setting the box back to 'normal' size
end;
end else begin
Inc(tries);
if tries = 1 then
begin
DistMultiplier := DistMultiplier + 1.0; //increasing search box
continue;
end else begin
MSI_SubDebug('Lost track of object');
Result := false;
break;
end;
end;
if BreakNext then Break;
if distance(Previous.X, Previous.Y, MSI_Objects[ObjID].X, MSI_Objects[ObjID].Y) < DIST_PIXEL_MOVE then
if not FlagPresent then
if not IsMoving then
BreakNext := true;
Previous := Point(MSI_Objects[ObjID].X, MSI_Objects[ObjID].Y);
Wait(5);
until (T < GetSystemTime);
if Result then
Track_Success(T_TrackObject);
Track_Print(T_TrackObject);
MSI_CloseHeader('TrackObject: ' + BoolToStr(Result));
SetColorSpeed2Modifiers(0.2, 0.2);
ColorToleranceSpeed(2);
end;
{******************************************************************************}
{ Function MSI_FindObjectsIn( ... ): Boolean; }
{ By: marpis }
{ Date: 10 June 2010 }
{ Description: Finds objects in mainscreen }
{******************************************************************************}
Function MSI_FindObjectsIn(Objs: TIntegerArray; Var IndexFound: Integer; SearchBox: TBox; Action: fnct_ActionOptions): Boolean;
Var
TPA, TmpTPA: TPointArray;
TheOptions, UpTexts: TStringArray;
I, II, III, HH, HHH, Hi: Integer;
CheckUpText: Boolean;
Begin
MSI_AddHeader('MSI_FindObjectsIn');
Hi := High(Objs);
SetLength(TheOptions, Hi + 1);
SetLength(UpTexts, Hi + 1);
For I := 0 To Hi Do
Begin
UpTexts[I] := MSI_Objects[Objs[I]].UpText;
TheOptions[I] := MSI_Objects[Objs[I]].Option;
End;
For II := 0 To Hi Do
With MSI_Objects[Objs[II]] Do
If MSI_FindObjectsTPA(TmpTPA, Objs[II], SearchBox) Then
Begin
// If set to, the script will click the closest object (this negates Priority)
if (MSI_Scripts[MSI_Players[CurrentPlayer].Scripts[CurrentScript].Name].ClickClosest) then
begin
MSI_Debug('Clicking closest object to player');
for i := 0 to High(Objs) do
if (MSI_FindObjectsTPA(TmpTPA, Objs[i], SearchBox)) then
begin
//Writeln('Obj'+IntToStr(i));
TPA := CombineTPA(TPA, TmpTPA);
end;
SortTPAFrom(TPA, Point(MSCX, MSCY));
end else
TPA := TmpTPA;
HH := Min((Tries - 1), High(TPA));
For I := 0 to HH Do
Begin
MSI_Debug(IntToStr(Length(TPA))+' objects found!');
X := TPA[I].X;
Y := TPA[I].Y;
IndexFound := II;
If (Action = Nothing) Then
Begin
Result := True;
MSI_CloseHeader('MSI_FindObjectsIn: ' + BoolToStr(Result));
Exit;
End;
HHH := High(UpTexts);
CheckUpText := True;
For III := 0 To HHH Do
If (UpTexts[III] = '') Then
Begin
CheckUpText := False;
Break;
End;
MMouse(TPA[I].X, TPA[I].Y, 2, 2);
Wait(20 + Random(50));
If CheckUpText Then
Result := WaitUpTextMulti(UpTexts, 150 + Random(20))
Else
Result := True;
If (Action = Move) Then
begin
MSI_CloseHeader('MSI_FindObjectsIn: ' + BoolToStr(Result));
Exit;
end;
If Result Then
Begin
GetMousePos(X, Y);
If (MSI_Objects[Objs[II]].RightClickOnly) Or InRange(Random(100), 0, 20) Or (Action = ClickRight) Then
Begin
Mouse(X, Y, 0, 0, False);
If (Action = ClickRight) or (Action = ClickLeft) Then
Result := WaitOptionMulti(TheOptions, 750 + Random(100))
Else
Result := True;
End Else
Begin
Mouse(X, Y, 0, 0, True);
Result := DidRedClick;
End;
If MSI_Objects[Objs[II]].WaitToMove Then
MSI_TrackObject(Objs[II]);
MSI_CloseHeader('MSI_FindObjectsIn: ' + BoolToStr(Result));
Exit;
End Else Begin
MSI_FindRandoms;
MSI_Debug('Uptext didn''t match!');
End;
End;
End;
MSI_CloseHeader('MSI_FindObjectsIn: ' + BoolToStr(Result));
MSI_FindRandoms;
End;
These are the colour object finding routines of MSI.
This is the very core of MSI's success.
There's a lot more to it of course ;) But if someone is actually able to pick up on all the techniques the MSI Devs used on these functions, it'd already be a very good start. :)
~RM