Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- program new;
- {$DEFINE SRL_USE_REMOTEINPUT}
- {$I SRL/osr.simba}
- const
- USE_SPELL = ERSSpell.HIGH_LEVEL_ALCHEMY;
- type
- TAlchemyValue = record
- Name: string;
- Points: Int32;
- PatternId: Int32;
- end;
- TAlchemyValues = array of TAlchemyValue;
- var
- RSW: TRSWalker;
- const
- cupboards: TPointArray = [
- [190,154], [190,138], [190,122], [190,106],
- [226,106], [226,122], [226,138], [226,154]
- ];
- pattern: TStringArray := [
- 'Leather boots', 'Adamant kiteshield', 'Adamant med helm', 'Emerald',
- 'Rune longsword','','',''
- ];
- function TRSInventory.GetUnusedSlots(): TIntegerArray;
- var slot: Int32;
- begin
- Inventory.Open();
- for slot:=0 to High(Inventory.GetSlotBoxes()) do
- if not Inventory.IsSlotUsed(slot) then
- Result += slot;
- end;
- function MatchingName(A,B: String): Boolean;
- begin
- Result := LowerCase(A).Pos(LowerCase(B)) > 0;
- end;
- procedure onterm();
- begin
- RSClient.Image.Clear();
- end;
- (*
- Returns the ID of the cupboard in relation to to cupboards list.
- *)
- function NearestCupboardID(): Int32;
- var
- i: Int32;
- p: TPoint;
- begin
- p := RSW.GetMyPos();
- for i:=0 to High(Cupboards) do
- if Cupboards[i].DistanceTo(p) < 11 then
- Exit(i);
- Result := -1;
- end;
- (*
- Uses the pattern list to return what item you just got, if you got one.
- Returns the index from the pattern list.
- *)
- function GetExtractedItemId(unused: TIntegerArray): Int32;
- var
- i: Int32;
- begin
- Inventory.Open();
- Result := -1;
- for i:=0 to High(pattern)-3 do
- if ItemFinder.Find(pattern[i], [Inventory.GetSlotBox(unused[0])]) <> [] then
- Exit(i);
- end;
- (*
- Moves around the playground to find the pattern order.
- *)
- function GetCurrentOrderOffset(): Int32;
- var
- unused: TIntegerArray;
- pos: Int32;
- TPA: TPointArray;
- ATPA: T2DPointArray;
- c: TCircle;
- begin
- repeat
- pos := NearestCupboardID();
- unused := Inventory.GetUnusedSlots();
- srl.FindColors( TPA, CTS2(9082515, 21, 0.30, 0.13), Minimap.PointToMsRect(RSW.WorldToMM(Cupboards[pos])).Bounds());
- ATPA := TPA.Cluster(3);
- c := ATPA.Biggest().MinAreaCircle();
- c.Radius := Round(c.Radius * 0.7);
- RSClient.Image.DrawCircle(c.Mean(), c.Radius, 255);
- Mouse.Click(c, MOUSE_LEFT);
- WaitUntil(Length(Inventory.GetUnusedSlots()) <> Length(unused), 50, 3000);
- Result := GetExtractedItemId(unused);
- if Result = -1 then
- RSW.WalkPath([Cupboards[(pos+3) mod 8]]);
- until Result <> -1;
- Result := srl.Modulo(pos-result, 8);
- end;
- (*
- Using the current order we can generate a translation list
- used to find out what cupboards contains what item.
- *)
- function GetTranslationTable(): TIntegerArray;
- var
- off,x,i: Int32;
- pt: TPoint;
- begin
- off := GetCurrentOrderOffset();
- Result := [];
- for i:=0 to High(pattern) do
- begin
- x := srl.Modulo(i-off, Length(pattern));
- pt := Minimap.PointToMs(RSW.WorldToMM(Cupboards[i]));
- RSClient.Image.DrawText(ToStr(i)+': '+ pattern[x], pt, 255);
- Result += x;
- end;
- end;
- (*
- a little bit of drawing is always nice.
- *)
- procedure DrawTranslationTable(table: TIntegerArray);
- var
- x,i: Int32;
- pt: TPoint;
- begin
- for i:=0 to High(pattern) do
- begin
- x := table[i];
- pt := Minimap.PointToMs(RSW.WorldToMM(Cupboards[i]));
- RSClient.Image.DrawText(ToStr(i)+': '+ pattern[x], pt, 255);
- end;
- end;
- (*
- OCR to generate a list of values.
- *)
- function GetAlchValues(): TAlchemyValues;
- var
- b: TBox;
- TSA: TStringArray;
- TPA: TPointArray;
- ATPA: T2DPointArray;
- i,j,z: Int32;
- function Compare(constref a,b: TAlchemyValue): Int32; static;
- begin
- Result := Sign(B.Points-A.Points);
- end;
- begin
- try
- b := Minimap.Bounds;
- b := [b.x1-250, b.y1+80, b.x2-250, b.y2+50];
- SRL.FindColors(TPA, CTS2(45620, 6, 0.14, 0.01), b);
- ATPA := TPA.Cluster(20, 2);
- ATPA.SortByX(True);
- ATPA.SortByY(True);
- RSClient.Image.DrawBox(b, 255);
- for i:=0 to High(ATPA) do
- begin
- TSA += ocr.Recognize(ATPA[i].Bounds().Expand(2), TOCRColorFilter.Create([45620], [30]), RS_FONT_PLAIN_11);
- z := TSA[High(TSA)].Pos('I');
- if z > 1 then
- begin
- if LowerCase(TSA[High(TSA)][z-1]) = TSA[High(TSA)][z-1] then
- TSA[High(TSA)][z] := 'l';
- end;
- TSA[High(TSA)] := TSA[High(TSA)].Replace('Helm', 'med helm', [rfReplaceAll]);
- end;
- for i:=0 to High(TSA) with 2 do
- for j:=0 to High(pattern) do
- if LowerCase(TSA[i]).Pos(LowerCase(pattern[j])) > 0 then
- begin
- Result += [pattern[j], StrToIntDef(TSA[i+1], 0), j];
- break;
- end;
- Sort(Result, @Compare);
- except
- SetLength(Result, 8); //hack!
- end;
- end;
- (*
- function GetBestAlch(scores: TAlchemyValues): Int32;
- var i: Int32;
- begin
- for i:=0 to High(pattern) do
- if LowerCase(scores[0].Name).Pos(LowerCase(pattern[i])) > 0 then
- Exit(i);
- end;
- *)
- function Equal(A,B: TAlchemyValues): Boolean;
- var i: Int32;
- begin
- Result := True;
- for i:=0 to High(A) do
- if (A[i].Name <> B[i].Name) or (A[i].Points <> B[i].Points) then
- Exit(False);
- end;
- function Extract(): Int32;
- var
- i,item,slot,count: Int32;
- p,best: TPoint;
- TPA: TPointArray;
- ATPA: T2DPointArray;
- translate: TIntegerArray;
- scores,newscores: TAlchemyValues;
- c: TCircle;
- items: TRSItemArray;
- t: TCountDown;
- label
- JUST_ALCH;
- begin
- scores := GetAlchValues();
- if Length(scores) = 0 then
- Exit;
- if Inventory.CountItem(scores[0].Name) > 5 then
- JUST_ALCH;
- translate := GetTranslationTable();
- item := scores[0].PatternId;
- best := cupboards[translate.Find(item)];
- RSW.WalkPath([best]);
- RSClient.Image.Clear();
- DrawTranslationTable(translate);
- // extract fast:
- WriteLn('Stage: Extract');
- t.Init(Random(2000,3500));
- while (scores[0].Name = GetAlchValues()[0].Name) and
- (not t.IsFinished()) do
- begin
- srl.FindColors( TPA, CTS2(9082515, 21, 0.30, 0.13), Minimap.PointToMsRect(RSW.WorldToMM(best)).Bounds());
- ATPA := TPA.Cluster(3);
- c := ATPA.Biggest().MinAreaCircle();
- c.Radius := Round(c.Radius * 0.7);
- Mouse.Click(c, MOUSE_LEFT); //sometimes clicks are not registered --- fix plz!
- Sleep(Random(250,500));
- end;
- JUST_ALCH:
- // cast spell
- WriteLn('Stage: cast spells!');
- repeat
- Magic.CastSpell(USE_SPELL);
- p := Mouse.Position();
- WaitUntil(Inventory.IsOpen(), 20, 5000);
- Inventory.ClickItem(pattern[item]);
- item := (newscores := GetAlchValues())[0].PatternID;
- count := Inventory.CountItem(pattern[item]);
- Wait(150,1000, wdLeft);
- if Random() > 0.05 then Mouse.Move(p, 20);
- WaitUntil(Magic.IsOpen(), 20, 5000);
- Wait(100,170, wdLeft); //reaction time limiter <---
- if count = 0 then break;
- until count = 0;
- if Length(Inventory.GetUnusedSlots()) < 7 then
- begin
- WriteLn('Stage: dropping crap');
- for i:=0 to High(pattern)-3 do
- if not MatchingName(newscores[0].Name, pattern[i]) then
- items += pattern[i];
- Inventory.ShiftDrop(items, DROP_PATTERN_REGULAR);
- end;
- if Inventory.CountItem(newscores[0].Name) >= 2 then
- JUST_ALCH;
- end;
- begin
- RSW_ADAPTIVE_SCREEN_TOGGLE_DISTANCES := [0,60];
- RSW.Setup('mta0');
- RSW.AdaptiveWalk := False;
- AddOnTerminate(@onterm);
- RSClient.Image.Clear();
- RSClient.Image.setFontSize(14);
- RSClient.Image.setFontAntialiasing(False);
- Mouse.Speed := Random(14,17);
- while True do
- begin
- RSClient.Image.Clear();
- Extract();
- // here we can check if we have reached 10K coins so we can leave the room
- // and break this loop
- end;
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement