Blood wraith does not get identified as blood wraith
Blood wraith is identified correctly but other items match "blood wraith"
Blood wraith is identified correctly with no false hits but is slow
Blood wraith is identified correctly and has no false matches and is very fast
Lechers gonna Leech.
We can't do anything about it but, not help them. Unless they are willing to have a go and coding them selves.
Mat
^^
I can just paste my script then you can copy it and see if you get the same results as me then.
My script
Also i don't want to be a leech, but i just don't have time to learn coding.
i got a error
[Error] C:\Simba\Includes\SRL/SRL/misc/paintsmart.simba(42:33): Unknown identifier 'SmartGetDebugDC' at line 41
Compiling failed.
Hey Guys because I used this script a while back and loved it, I have brought it back from the dead yes i fixed it (the code will be in 2 posts because it wont all fit) enjoy
Code:program PreemptibleRuneSpan; {$DEFINE SMART} {$include_once SRL/SRL.simba} {$include_once SRL/SRL/Misc/Debug.simba} {$include_once SRL/SRL/core/animation.simba} {$include_once SRL/SRL/skill/magic.simba} const SRLStats_User = 'Anonymous'; // Your SRL Stats ID (If you dont have one then just leave it as it is) const SRLStats_Password = 'anon1337'; // Your SRL Stats Password (If you dont have one then just leave it as it is) const CAN_USE_FAIRY_RINGS = False; const ONSCREEN_STATS = False; // set to false if it bothers you, or click Disable Debug button const ONSCREEN_FOLLOW_MODELS = True; // set to false if you don't want to see models being followed const ONSCREEN_TRACK_BOUNDARY = True; // turn off if you don't care to see boundary cube-like map projection points const CLICKBAN_ENABLED = True; // essentially if we click on something and nothing happens, we shouldn't click on it again const TAKES_BREAKS = True; // do we take breaks const BREAK_TIME = 190; // number of minutes before breaks, midpoint const BREAK_TIME_SPREAD = 10; // means +/- 10 minutes const BREAK_DURATION = 8; // break time is always +/- 25% just because we don't need more input const SWITCH_WORLDS_BREAK = True; // switch worlds after a break const KEEP_DEBUG = False; // if you set it to true, the little window will not clear on each stat report const SMART_SERVER_TO_USE = 63; // so that you can change it quickly if your // cache is messed up and you get "no applet" message ////////////////////////////////////// // SERIOUSLY only one supported atm // ////////////////////////////////////// procedure DeclarePlayers; begin HowManyPlayers := 1; NumberOfPlayers(HowManyPlayers); CurrentPlayer := 0; with Players[0] do begin Name := ''; Pass := ''; Pin := ''; // right now banking for hood not supported, might be in future // so you don't need to fill it just yet BoxRewards := ['XP', 'Lamp', 'Book', 'mote', 'ostume', 'ssence']; LampSkill := SKILL_RUNECRAFTING; Member := True; Active := True; end; end; type TModelTarget = (TARGET_UNDEAD_SOUL, TARGET_LIVING_SOUL, TARGET_BLOODY_SKULLS, TARGET_BLOOD_POOL, TARGET_SKULLS, TARGET_JUMPER, TARGET_SHIFTER, TARGET_NEBULA, TARGET_CHAOTIC_CLOUD, TARGET_FIRE_STORM, TARGET_FLESHY_GROWTH, TARGET_VINE, TARGET_FIREBALL, TARGET_ROCK_FRAGMENT, TARGET_WATER_POOL, TARGET_MIND_STORM, TARGET_CYCLONE, TARGET_SOUL_ESSWRAITH, TARGET_BLOOD_ESSWRAITH, TARGET_DEATH_ESSWRAITH, TARGET_LAW_ESSHOUND, TARGET_NATURE_ESSHOUND, TARGET_ASTRAL_ESSHOUND, TARGET_CHAOS_ESSHOUND, TARGET_COSMIC_ESSHOUND, TARGET_BODY_ESSHOUND, TARGET_FIRE_ESSLING, TARGET_EARTH_ESSLING, TARGET_WATER_ESSLING, TARGET_MIND_ESSLING, TARGET_AIR_ESSLING, TARGET_GENERIC_ESSHOUND, TARGET_NONE); var USER_SELECTED_ORDER : array of TModelTarget; procedure InitializeUserSelection; begin USER_SELECTED_ORDER := []; (* Example of order: [ TARGET_UNDEAD_SOUL, TARGET_LIVING_SOUL, TARGET_BLOODY_SKULLS, TARGET_BLOOD_POOL, TARGET_SKULLS, TARGET_JUMPER, TARGET_SHIFTER, TARGET_NEBULA, TARGET_CHAOTIC_CLOUD, TARGET_SOUL_ESSWRAITH, TARGET_BLOOD_ESSWRAITH, TARGET_DEATH_ESSWRAITH, TARGET_LAW_ESSHOUND, TARGET_FLESHY_GROWTH, TARGET_NATURE_ESSHOUND, TARGET_ASTRAL_ESSHOUND, TARGET_FIREBALL, TARGET_VINE, TARGET_FIRE_STORM, TARGET_CHAOS_ESSHOUND, TARGET_COSMIC_ESSHOUND, TARGET_ROCK_FRAGMENT, TARGET_WATER_POOL, TARGET_BODY_ESSHOUND, TARGET_GENERIC_ESSHOUND, TARGET_MIND_STORM, TARGET_CYCLONE, TARGET_FIRE_ESSLING, TARGET_EARTH_ESSLING, TARGET_WATER_ESSLING, TARGET_MIND_ESSLING, TARGET_AIR_ESSLING]; *) end; const USER_IS_ADD = False; const SMART_THIRD_LEVEL = True; const ONSCREEN_TRACK_SECONDARY = False; const TEST_MODELS = False; const OMIT_MODEL_NAMES = False; const LOG_LONG_SEARCHES = False; const CLICKBAN_MAX_AREAS = 60; const VERSION = '4.0.43'; var DEFAULT_TARGET_ORDER : array of TModelTarget; var SELECTED_TARGET_ORDER : array of TModelTarget; procedure InitializeTargetOrder; begin DEFAULT_TARGET_ORDER := [ TARGET_UNDEAD_SOUL, TARGET_LIVING_SOUL, TARGET_BLOODY_SKULLS, TARGET_BLOOD_POOL, TARGET_SKULLS, TARGET_JUMPER, TARGET_SHIFTER, TARGET_NEBULA, TARGET_CHAOTIC_CLOUD, TARGET_SOUL_ESSWRAITH, TARGET_BLOOD_ESSWRAITH, TARGET_DEATH_ESSWRAITH, TARGET_LAW_ESSHOUND, TARGET_FLESHY_GROWTH, TARGET_NATURE_ESSHOUND, TARGET_ASTRAL_ESSHOUND, TARGET_FIREBALL, TARGET_VINE, TARGET_FIRE_STORM, TARGET_CHAOS_ESSHOUND, TARGET_COSMIC_ESSHOUND, TARGET_ROCK_FRAGMENT, TARGET_WATER_POOL, TARGET_BODY_ESSHOUND, TARGET_GENERIC_ESSHOUND, TARGET_MIND_STORM, TARGET_CYCLONE, TARGET_FIRE_ESSLING, TARGET_EARTH_ESSLING, TARGET_WATER_ESSLING, TARGET_MIND_ESSLING, TARGET_AIR_ESSLING]; InitializeUserSelection; if Length(USER_SELECTED_ORDER) > 0 then begin SELECTED_TARGET_ORDER := USER_SELECTED_ORDER; end else begin SELECTED_TARGET_ORDER := DEFAULT_TARGET_ORDER; end; end; type TMatchDegree = (MATCH_EXACT, MATCH_CASE_INSENSITIVE, MATCH_GOOD, MATCH_LOOSE); function SubStringMatchFuzzy(ONE, TWO : String) : Integer; Forward; function SubStringMatchFuzzyEx(ONE, TWO : String; DegreeOfMatch : TMatchDegree) : Integer; Forward; function MatchTextFuzzyEx(MATCHSTRING : String; TARGETTEXT : String; DegreeOfMatch : TMatchDegree) : Boolean; Forward; function MatchUpTextFuzzy(MatchString : String; DegreeOfMatch : TMatchDegree): Boolean; Forward; function WaitOptionFuzzyEx(Option : String; DegreeOfMatch : TMatchDegree; Action: fnct_ActionOptions; Time: Integer) : Boolean; Forward; function WaitOptionFuzzy(Option : String; DegreeOfMatch : TMatchDegree; Time: Integer) : Boolean; Forward; function WaitUpTextFuzzy(Uptext : String; DegreeOfMatch : TMatchDegree; Time: Integer) : Boolean; Forward; const MAP_TYPE_OUTSIDE = -1; // not an area to click const MAP_TYPE_UNTESTED = 0; // beyond edge of island or not yet tested const MAP_TYPE_EDGE = 1; // edge of an island const MAP_TYPE_ISLAND = 2; // this square lies inside current island const STATS_EXP_RUNECRAFTING = 'Runecrafting EXP (Gained)'; const STATS_EXP_TOTAL = 'Total EXP Gained'; const STATS_LEVEL_RUNECRAFTING = 'Runecrafting Levels (Gained)'; const STATS_RUNE_ESSENCE = 'Rune Essence (Mined)'; const STATS_RUNE_AIR = 'Air Runes (Crafted)'; const STATS_RUNE_MIND = 'Mind Runes (Crafted)'; const STATS_RUNE_WATER = 'Water Runes (Crafted)'; const STATS_RUNE_EARTH = 'Earth Runes (Crafted)'; const STATS_RUNE_FIRE = 'Fire Runes (Crafted)'; const STATS_RUNE_BODY = 'Body Runes (Crafted)'; const STATS_RUNE_COSMIC = 'Cosmic Runes (Crafted)'; const STATS_RUNE_CHAOS = 'Chaos Runes (Crafted)'; const STATS_RUNE_ASTRAL = 'Astral Runes (Crafted)'; const STATS_RUNE_NATURE = 'Nature Runes (Crafted)'; const STATS_RUNE_LAW = 'Law Runes (Crafted)'; const STATS_RUNE_DEATH = 'Death Runes (Crafted)'; const STATS_RUNE_BLOOD = 'Blood Runes (Crafted)'; const STATS_RUNE_SOUL = 'Soul Runes (Crafted)'; const TYPE_RUNE_NONE = 0; const TYPE_RUNE_AIR = 1; const TYPE_RUNE_MIND = 2; const TYPE_RUNE_WATER = 3; const TYPE_RUNE_EARTH = 4; const TYPE_RUNE_FIRE = 5; const TYPE_RUNE_BODY = 6; const TYPE_RUNE_COSMIC = 7; const TYPE_RUNE_CHAOS = 8; const TYPE_RUNE_ASTRAL = 9; const TYPE_RUNE_NATURE = 10; const TYPE_RUNE_LAW = 11; const TYPE_RUNE_DEATH = 12; const TYPE_RUNE_BLOOD = 13; const TYPE_RUNE_SOUL = 14; const TYPE_RUNE_ESSENCE = 15; const TYPE_RUNE_MIN = TYPE_RUNE_AIR; const TYPE_RUNE_MAX = TYPE_RUNE_ESSENCE; var STATS_RUNE : array [TYPE_RUNE_MIN..TYPE_RUNE_MAX] of String; var CLICKBANS : TPointArray; procedure ClearClickban; forward; procedure RecordClickban(X, Y : Integer); forward; procedure CalculateScreenPoints; forward; function CheckIfWeCare(X1, Y1, X2, Y2 : Integer) : Boolean; forward; procedure WriteAccountingForCurrentModel(XPDiff : Integer; TimeDiff : Integer); forward; procedure InitializeStatsArray; begin STATS_RUNE[TYPE_RUNE_AIR] := STATS_RUNE_AIR; STATS_RUNE[TYPE_RUNE_MIND] := STATS_RUNE_MIND; STATS_RUNE[TYPE_RUNE_WATER] := STATS_RUNE_WATER; STATS_RUNE[TYPE_RUNE_EARTH] := STATS_RUNE_EARTH; STATS_RUNE[TYPE_RUNE_FIRE] := STATS_RUNE_FIRE; STATS_RUNE[TYPE_RUNE_BODY] := STATS_RUNE_BODY; STATS_RUNE[TYPE_RUNE_COSMIC] := STATS_RUNE_COSMIC; STATS_RUNE[TYPE_RUNE_CHAOS] := STATS_RUNE_CHAOS; STATS_RUNE[TYPE_RUNE_ASTRAL] := STATS_RUNE_ASTRAL; STATS_RUNE[TYPE_RUNE_NATURE] := STATS_RUNE_NATURE; STATS_RUNE[TYPE_RUNE_LAW] := STATS_RUNE_LAW; STATS_RUNE[TYPE_RUNE_DEATH] := STATS_RUNE_DEATH; STATS_RUNE[TYPE_RUNE_BLOOD] := STATS_RUNE_BLOOD; STATS_RUNE[TYPE_RUNE_SOUL] := STATS_RUNE_SOUL; STATS_RUNE[TYPE_RUNE_ESSENCE] := STATS_RUNE_ESSENCE; end; const GENERIC_ESSHOUND = 16628392; type TColorTolerance = record Color : Integer; Tolerance : Integer; MinHitsRequired : Integer; ToleranceSpeed : Integer; end; type TColorToleranceArray = array of TColorTolerance; type TPAModel = record ModelType : TModelTarget; Descriptor : String; ColorToleranceDefinition : TColorToleranceArray; ColorToleranceExcludes : TColorToleranceArray; Hound : Boolean; XP : Integer; MinimumFloor : Integer; MinimumLevel : Integer; MemberOnly : Boolean; Runes : TIntegerArray; ChipRune : Integer; end; type TPAModelArray = array of TPAModel; type TDenseColorInfo = record SumX : Integer; SumY : Integer; Pointcount : Integer; FoundPointCount : Integer; Matching : Boolean; end; type TTemporaryClickBanArea = record LastValid : Integer; AreaLocation : TPointArray; end; type TDenseColorInfoArray = array of TDenseColorInfo; type TModelAccounting = record Description : string; XPAcquired : Integer; Timespan : Integer; end; type TModelAccountingArray = array of TModelAccounting; var MAP : array [0..((MMX2 - MMX1) shr 3)] of array [0..((MMY2 - MMY1) shr 3)] of Integer; var MAP3D : array [0..((MMX2 - MMX1) shr 3)] of array [0..((MMY2 - MMY1) shr 3)] of TBox; var MAPPOINTS : TPointArray; var SCREENPOINTS : TPointArray; var RUNE_LastKnownPosition : array [TYPE_RUNE_MIN..TYPE_RUNE_MAX] of Integer; var TPAModelList : TPAModelArray; var ModelAccounting : TModelAccountingArray; var EnvironmentalExcludes : array [0..3] of TColorToleranceArray; var SmartLines: TStringArray; // totally stealing this because it is implemented well const LINEHEIGHT = 12; {******************************************************************************* Function PrintonSmart; By: Shuttleu Edited By: Ashaman88 Description: Will put progress report on screen. *******************************************************************************} Procedure PrintOnSmart(TP: TStringArray; Placement: TPoint; Color: integer); var mx, my, Pic, I, E, H, TPH, Numb: Integer; TTP: TPointArray; Canvas: TCanvas; begin GetClientDimensions(mx, my); Pic := BitmapFromString(mx, Length(TP) * (LINEHEIGHT + 1) + 5, ''); // my, ''); TPH := High(TP); for I := 0 to TPH do begin TTP := LoadTextTPA(TP[i], UpChars, H); for E := 0 to High(TTP) do begin Numb := (I * (LINEHEIGHT - 1)); FastSetPixel(Pic, TTP[E].x + 1, TTP[E].y + Numb + 1,131072); FastSetPixel(Pic, TTP[E].x, TTP[E].y + Numb, Color); end; end; Canvas := TCANVAS.Create; // Canvas.Handle := SmartGetDebugDC; //DrawBitmap(Pic, Canvas, Placement.x, Placement.y); FreeBitmap(Pic); end; // make uptext and choose type of match function MakeUptext(Model : String; Hound : Boolean) : string; var HOUNDTYPE : string; var posOfSpace : Integer; begin // first of all - hounds tend to have very similar name so let's worry about // non hounds first if (not Hound) then begin Result := 'Siphon ' + Model; Exit; end; // shortest is AIR, or LAW so we will create Spxxxss, where xxx is hound name // because that will have at minimum 7 characters, so 75% match will require // 6 character match, Sp of course will match Siphon, while ss will match // ess(wraith/hound/ling) posOfSpace := Pos(' ', Model); // well we kinda need say... 3 or something of the sort if (posOfSpace > 2) then begin HOUNDTYPE := Copy(Model, 1, posOfSpace - 1); end else begin HOUNDTYPE := Model; end; // do it Result := 'Sp' + HOUNDTYPE + 'ss'; end; // modified ChooseOptionMultiEx function ChooseOptionFuzzyEx(Option: String; DegreeOfMatch : TMatchDegree; Action: fnct_ActionOptions): Boolean; var B: TBox; H, ii, x: Integer; T: TPoint; Options: array of TOptions; begin Result := False; Options := GetChooseOptions('all'); if (Length(Options) < 1) then Exit; H := High(Options); for ii := 0 to H do begin If MatchTextFuzzyEx(Option, Options[ii].Str, DegreeOfMatch) Then begin Result := True; B := Options[ii].Bounds; GetMousePos(T.x, T.y); case Action of ClickLeft: if PointInBox(T, B) then ClickMouse2(true) else MouseBoxEx(B.x1 + 5, B.Y1, B.x2 - 5, B.Y1 + 5,5, 1); Move: if not PointInBox(T, B) then MouseBoxEx(B.x1 + 5, B.Y1, B.x2 - 5, B.Y1 + 5,5, 3); Nothing: begin end; else srl_warn('ChooseOptionMultiEx', 'ClickRight not a valid click for RS menus!', warn_AllVersions); end; Exit; end; end; B := Options[0].BigBox;//to mmouse away if Action <> Nothing then begin x := Max(B.X1 - 52, 0); if x = 0 then x := B.X2+10; MMouse(x, Max(B.Y1 - 50, 0), 40, B.Y2-B.Y1); Wait(200 + Random(100)); end; end; function WaitOptionFuzzy(Option : String; DegreeOfMatch : TMatchDegree; Time: Integer) : Boolean; begin Result := WaitOptionFuzzyEx(Option, DegreeOfMatch, ClickLeft, Time); end; // why use WaitOptionMultiEx when we can just specify type of match function WaitOptionFuzzyEx(Option : String; DegreeOfMatch : TMatchDegree; Action: fnct_ActionOptions; Time: Integer) : Boolean; var TargetTime : Integer; begin Result := False; TargetTime := GetSystemTime + Time; while (GetSystemTime < TargetTime) do begin if (ChooseOptionFuzzyEx(Option, DegreeOfMatch, Action)) then begin Result := True; Exit; end; if (GetSystemTime < TargetTime) then begin // generally speaking, on windows, timer precision is about 1/100 of second // so you can't really sleep 1ms, it will end up being about 9-10 Sleep(1); end else begin // no need to sleep and try again Exit; end; end; end; function WaitUpTextFuzzy(Uptext : String; DegreeOfMatch : TMatchDegree; Time: Integer) : Boolean; var TargetTime : Integer; begin Result := False; TargetTime := GetSystemTime + Time; while (GetSystemTime < TargetTime) do begin if (MatchTextFuzzyEx(Uptext, GetUpText, DegreeOfMatch)) then begin // done Result := True; Exit; end; if (GetSystemTime < TargetTime) then begin // generally speaking, on windows, timer precision is about 1/100 of second // so you can't really sleep 1ms, it will end up being about 9-10 Sleep(1); end else begin // no need to sleep and try again Exit; end; end; end; function MatchTextFuzzyEx(MATCHSTRING : String; TARGETTEXT : String; DegreeOfMatch : TMatchDegree) : Boolean; var COUNT : Integer; begin Result := False; if (Pos(MATCHSTRING, TARGETTEXT) > 0) then begin Result := True; Exit; end; if DegreeOfMatch = MATCH_EXACT then Exit; if DegreeOfMatch = MATCH_CASE_INSENSITIVE then begin if (Pos(Uppercase(MATCHSTRING), Uppercase(TARGETTEXT)) > 0) then begin Result := True; Exit; end; end; if (DegreeOfMatch = MATCH_CASE_INSENSITIVE) then Exit; // check fuzzy - much more difficult - use recursion COUNT := SubStringMatchFuzzyEx(MATCHSTRING, TARGETTEXT, DegreeOfMatch); if (COUNT = 0) then Exit; // no match // determine if good match if (COUNT * 4 >= Length(MATCHSTRING) * 3) then begin // 75% matched Result := True; Exit; end; if (DegreeOfMatch = MATCH_GOOD) then Exit; if (COUNT * 2 >= Length(MATCHSTRING)) then begin // 50% matched Result := True; end; end; // counts number of matches in ordered fashion, i.e. ThIS matches aTIS in 3 // but ThIS matches aTSI in 2 // this is near impossible to take out of recursion because we need to do full // search so rather than trying to get out of recursion, let's optimize with // some globals var ___ACC : Integer; // let us add deadstop - if we need 50% of matches but we only have 47% of string // with 0 matches, we might as well throw in the towel function SubStringMatchFuzzyRec(__ONE, __TWO: String; OffsetOne, OffsetTwo : Integer; DeadStop : Integer) : Integer; var MatchCountOne : Integer; var MatchCountTwo : Integer; var Index : Integer; var ADJUSTMENT : Integer; var ADJOffsetOne : Integer; var ADJOffsetTwo : Integer; begin Inc(___ACC); Result := 0; ADJUSTMENT := 0; ADJOffsetOne := OffsetOne; ADJOffsetTwo := OffsetTwo; // length of string is stored in the string, so it is fast to retrieve if (Length(__ONE) <= ADJOffsetOne) then Exit; if (Length(__TWO) <= ADJOffsetTwo) then Exit; if (Length(__ONE) - ADJOffsetOne < DeadStop) then Exit; if (Length(__TWO) - ADJOffsetTwo < DeadStop) then Exit; while (__ONE[ADJOffsetOne + 1] = __TWO[ADJOffsetTwo + 1]) do begin Inc(ADJUSTMENT); Inc(ADJOffsetOne); Inc(ADJOffsetTwo); // test for end of string if (Length(__ONE) <= ADJOffsetOne) or (Length(__TWO) <= ADJOffsetTwo) then begin // done Result := ADJUSTMENT; Exit; end; end; // if (ADJUSTMENT > 1) then Writeln('ADJRun: ' + IntToStr(ADJUSTMENT)); // short of that split into two cases - recursive shorter first string MatchCountOne := SubStringMatchFuzzyRec(__ONE, __TWO, ADJOffsetOne + 1, ADJOffsetTwo, DeadStop - ADJUSTMENT); // and non recusive shorter second string until match MatchCountTwo := 0; for Index := ADJOffsetTwo + 2 to Length(__TWO) do begin if (__ONE[ADJOffsetOne + 1] = __TWO[Index]) then begin if (Index < Length(__TWO)) then begin if (Length(__ONE) > ADJOffsetOne + 1) then begin MatchCountTwo := SubStringMatchFuzzyRec(__ONE, __TWO, ADJOffsetOne + 1, Index, DeadStop - ADJUSTMENT); end; end; // and one for current match Inc(MatchCountTwo); break; end; end; // check Result := MatchCountOne; if (MatchCountTwo > Result) then Result := MatchCountTwo; Result := Result + ADJUSTMENT; end; function SubStringMatchFuzzy(ONE, TWO : String) : Integer; begin // faster if first param is shorter as it will do less recursive calls Result := SubStringMatchFuzzyEx(ONE, TWO, MATCH_LOOSE); end; function SubStringMatchFuzzyEx(ONE, TWO : String; DegreeOfMatch : TMatchDegree) : Integer; var DeadStop : Integer; var __ONE : String; var __TWO : String; var __LONE : Integer; begin // recursion is unbalanced as one branch was optimize to not use recursion // so result is faster if first string is shorter if (Length(ONE) > Length(TWO)) then begin __ONE := TWO; __TWO := ONE; end else begin __ONE := ONE; __TWO := TWO; end; __LONE := Length(__ONE); if (DegreeOfMatch = MATCH_LOOSE) then begin // divide by two and round up without using floating point DeadStop := (__LONE + 1) shr 1; end else begin // round up multiply by 0.75 without using floating point DeadStop := ((__LONE shl 1) + __LONE + 3) shr 2; end; Result := SubStringMatchFuzzyRec(__ONE, __TWO, 0, 0, DeadStop); end; function MatchUpTextFuzzy(MatchString : String; DegreeOfMatch : TMatchDegree): Boolean; begin Result := MatchTextFuzzyEx(GetUpText, MatchString, DegreeOfMatch); end; procedure LogSmartLine(NewLine : String); var Index : Integer; begin if Length(SmartLines) <> 10 then begin SetLength(SmartLines, 10); end; // rotate out for Index := 9 downto 1 do begin SmartLines[Index] := SmartLines[Index - 1]; end; SmartLines[0] := NewLine; WriteLn(NewLine); // show PrintOnSmart(SmartLines, Point(15,15), clLime); end; procedure AppendSmartLine(AppendLine : String; Done : Boolean); begin if Length(SmartLines) <> 10 then begin SetLength(SmartLines, 10); end; SmartLines[0] := SmartLines[0] + AppendLine; if (Done) then begin WriteLn(SmartLines[0]); end; // show PrintOnSmart(SmartLines, Point(15,15), clLime); end; procedure ClearMap; var MAXX : Integer; var MAXY : Integer; var indexX : Integer; var indexY : Integer; var midX : Integer; var midY : Integer; var radius : Integer; var radius2 : Extended; var XPART : Extended; begin MAXX := Length(MAP); MAXY := Length(MAP[0]); midX := MAXX shr 1; midY := MAXY shr 1; SetLength(SCREENPOINTS, 0); // we are redoing map, will change screenpoints radius := midX; if (radius > midY) then radius := midY; Dec(radius); radius2 := Sqr(radius - 1); for indexX := 0 to MAXX - 1 do begin XPART := Sqr(midX - indexX - 1); for indexY := 0 to MAXY - 1 do begin // check if (midX = indexX + 1) and (midY = indexY + 1) then begin MAP[indexX][indexY] := MAP_TYPE_ISLAND; continue; end; if (Sqr(midY - indexY - 1) + XPART) > radius2 then begin MAP[indexX][indexY] := MAP_TYPE_OUTSIDE; end else begin MAP[indexX][indexY] := MAP_TYPE_UNTESTED; end; end; end; end; // detect edge of an island based on excessive amount of black pixels function TestMapSquare(indexX, indexY : Integer) : Integer; var X1, X2, Y1, Y2 : Integer; var Total : Integer; var ToleranceOfBlack : Integer; begin // until proven otherwise Result := MAP_TYPE_ISLAND; X1 := MMX1 + (indexX shl 3); X2 := X1 + 8; Y1 := MMY1 + (indexY shl 3); Y2 := Y1 + 8; Total := CountColorTolerance(clBlack, X1, Y1, X2, Y2, 30); ToleranceOfBlack := 8; if (Total <= ToleranceOfBlack) then Exit; // we should allow for more black if dots present ToleranceOfBlack := ToleranceOfBlack + ((CountColorTolerance(clWhite, X1, Y1, X2, Y2, 30)) shr 1); if (Total <= ToleranceOfBlack) then Exit; ToleranceOfBlack := ToleranceOfBlack + ((CountColorTolerance($e3fb0a, X1, Y1, X2, Y2, 30)) shr 1); if (Total <= ToleranceOfBlack) then Exit; // we found too much black, this is where the island ends Result := MAP_TYPE_EDGE; end; procedure UpdateMap; var Done : Boolean; var MAXX : Integer; var MAXY : Integer; var indexX : Integer; var indexY : Integer; var NeedTesting : Boolean; var TestResult : Integer; begin MAXX := Length(MAP); MAXY := Length(MAP[0]); // clear map and mark center point ClearMap(); ClearClickban(); repeat // assume done until proven otherwise Done := true; // go through the map for indexX := 0 to MAXX - 1 do begin for indexY := 0 to MAXY - 1 do begin if (MAP[indexX][indexY] <> MAP_TYPE_UNTESTED) then continue; NeedTesting := false; if (indexX > 0) then begin if (MAP[indexX - 1][indexY] = MAP_TYPE_ISLAND) then NeedTesting := true; end; if (indexY > 0) then begin if (MAP[indexX][indexY - 1] = MAP_TYPE_ISLAND) then NeedTesting := true; end; if (indexX < MAXX - 1) then begin if (MAP[indexX + 1][indexY] = MAP_TYPE_ISLAND) then NeedTesting := true; end; if (indexY < MAXY - 1) then begin if (MAP[indexX][indexY + 1] = MAP_TYPE_ISLAND) then NeedTesting := true; end; if not NeedTesting then continue; // test TestResult := TestMapSquare(indexX, indexY); MAP[indexX][indexY] := TestResult; if (TestResult = MAP_TYPE_ISLAND) then Done := false; end; end; until Done; end; // camera angle high const PERSPECTIVE_MM_MAP_SQUARE = 10.5; const PERSPECTIVE_MM_MAP_ASPECT_RATIO = 1; const PERSPECTIVE_MM_CAMERA_Z = 24; const PERSPECTIVE_MM_CAMERA_Y = 40; const PERSPECTIVE_MM_DEPTH_Z = 0; const AXIS_Y_ZERO_OFFSET = 1.5; var RUNESCAPE_MM_ANGLE_HIGH_TRANSFORM : Extended; var RUNESCAPE_MM_DISTANCE_Z : Extended; procedure CalculateTransformAngleMM; var DistanceZ : Extended; begin RUNESCAPE_MM_ANGLE_HIGH_TRANSFORM := ArcCos(PERSPECTIVE_MM_CAMERA_Z / Sqrt(Sqr(PERSPECTIVE_MM_CAMERA_Y) + Sqr(PERSPECTIVE_MM_CAMERA_Z))); // make runescape transform DistanceZ := PERSPECTIVE_MM_CAMERA_Z + PERSPECTIVE_MM_DEPTH_Z; RUNESCAPE_MM_DISTANCE_Z := Sqrt(Sqr(PERSPECTIVE_MM_CAMERA_Y) + Sqr(DistanceZ)); end; // based on minimap offsets function GetPerspectivePointExactMM(X,Y,Z : Extended) : TPoint; var CAMERA_Z_DISTANCE : Extended; var CAMERA_Y_DISTANCE : Extended; var CAMERA_Z_DISTANCE2 : Extended; var CAMERA_Y_DISTANCE2 : Extended; var CAMERA_X_DISTANCE2 : Extended; var CAMERA_XZ_DISTANCE2 : Extended; var CAMERA_YZ_DISTANCE2 : Extended; var CAMERA_XZ_DISTANCE : Extended; var CAMERA_YZ_DISTANCE : Extended; var CAMERA_XYZ_DISTANCE : Extended; var IntegralX : Extended; var IntegralY : Extended; var ModZ : Extended; begin Result.X := MSCX; Result.Y := MSCY; CAMERA_Z_DISTANCE := PERSPECTIVE_MM_CAMERA_Z - Z; CAMERA_Y_DISTANCE := Y; if (CAMERA_Z_DISTANCE < 1) then Exit; CAMERA_Z_DISTANCE2 := Sqr(CAMERA_Z_DISTANCE); CAMERA_Y_DISTANCE2 := Sqr(CAMERA_Y_DISTANCE); CAMERA_X_DISTANCE2 := Sqr(X); CAMERA_XZ_DISTANCE2 := CAMERA_X_DISTANCE2 + CAMERA_Z_DISTANCE2; CAMERA_YZ_DISTANCE2 := CAMERA_Y_DISTANCE2 + CAMERA_Z_DISTANCE2; CAMERA_XZ_DISTANCE := Sqrt(CAMERA_XZ_DISTANCE2); CAMERA_YZ_DISTANCE := Sqrt(CAMERA_YZ_DISTANCE2); CAMERA_XYZ_DISTANCE := Sqrt(CAMERA_X_DISTANCE2 + CAMERA_YZ_DISTANCE2); // we do have asinh after all, it's called ArcSinh IntegralX := CAMERA_YZ_DISTANCE * ArcSinh(X / CAMERA_YZ_DISTANCE); IntegralY := CAMERA_XZ_DISTANCE * ArcSinh(Y / CAMERA_XZ_DISTANCE); // do not fret, asinh(x) = ln(x + sqrt(sqr(x) + 1)) //IntegralX := CAMERA_YZ_DISTANCE * ln((X + sqrt(CAMERA_X_DISTANCE2 + CAMERA_YZ_DISTANCE2))/CAMERA_YZ_DISTANCE); //IntegralY := CAMERA_XZ_DISTANCE * ln((Y + sqrt(CAMERA_Y_DISTANCE2 + CAMERA_XZ_DISTANCE2))/CAMERA_XZ_DISTANCE); // this one is the simple one ModZ := RUNESCAPE_MM_DISTANCE_Z / CAMERA_Z_DISTANCE; Result.X := MSCX + Round(PERSPECTIVE_MM_MAP_SQUARE * PERSPECTIVE_MM_MAP_ASPECT_RATIO * IntegralX * ModZ); Result.Y := MSCY - Round(PERSPECTIVE_MM_MAP_SQUARE * IntegralY * ModZ); end; // this will multiply all axes by 8 to get MM transform // exact value is 8.0 but we want to be on the safe side // by "shrinking" space around player const MM_MULTIPLIER = 7.0; function GetPerspectivePoint(X,Y,Z : Extended) : TPoint; var Y1, Z1 : Extended; var PLAYERSHIFTEDY : Extended; var DistanceZ : Extended; var DistanceYZ : Extended; var POINTEXACT : TPoint; var ANGLE : Extended; begin // make runescape transform but in minimap points DistanceZ := PERSPECTIVE_MM_CAMERA_Z - (Z * MM_MULTIPLIER) + PERSPECTIVE_MM_DEPTH_Z; PLAYERSHIFTEDY := (Y * MM_MULTIPLIER) - AXIS_Y_ZERO_OFFSET; DistanceYZ := Sqrt(Sqr(PERSPECTIVE_MM_CAMERA_Y - PLAYERSHIFTEDY) + Sqr(DistanceZ)); ANGLE := ArcCos(DistanceZ / DistanceYZ); Y1 := Sin(RUNESCAPE_MM_ANGLE_HIGH_TRANSFORM - ANGLE) * DistanceYZ; Z1 := PERSPECTIVE_MM_CAMERA_Z - Cos(RUNESCAPE_MM_ANGLE_HIGH_TRANSFORM - ANGLE) * DistanceYZ; POINTEXACT := GetPerspectivePointExactMM(X * MM_MULTIPLIER,Y1,Z1); Result.x := POINTEXACT.x; Result.y := POINTEXACT.y; end; const MAP_CUBES = 0.45; procedure DrawMapCube(X, Y : Extended; Color : TColor); var PERSPECTIVE : array [0..7] of TPoint; begin if (Y > (PERSPECTIVE_MM_CAMERA_Y - 1) * 8) then Exit; PERSPECTIVE[0] := GetPerspectivePoint(X - MAP_CUBES, 0.5 - MAP_CUBES, Y - MAP_CUBES); PERSPECTIVE[1] := GetPerspectivePoint(X - MAP_CUBES, 0.5 - MAP_CUBES, Y + MAP_CUBES); PERSPECTIVE[2] := GetPerspectivePoint(X + MAP_CUBES, 0.5 - MAP_CUBES, Y + MAP_CUBES); PERSPECTIVE[3] := GetPerspectivePoint(X + MAP_CUBES, 0.5 - MAP_CUBES, Y - MAP_CUBES); PERSPECTIVE[4] := GetPerspectivePoint(X - MAP_CUBES, 0.5 + MAP_CUBES, Y - MAP_CUBES); PERSPECTIVE[5] := GetPerspectivePoint(X - MAP_CUBES, 0.5 + MAP_CUBES, Y + MAP_CUBES); PERSPECTIVE[6] := GetPerspectivePoint(X + MAP_CUBES, 0.5 + MAP_CUBES, Y + MAP_CUBES); PERSPECTIVE[7] := GetPerspectivePoint(X + MAP_CUBES, 0.5 + MAP_CUBES, Y - MAP_CUBES); end; const MAXHEIGHT = 1.25; procedure Initialize3DModelFromMap; var MAXX : Integer; var MAXY : Integer; var indexX : Integer; var indexY : Integer; var X1,X2,Y1,Y2 : Integer; var BOX : TBox; var MidX, MidY : Extended; var ChosenColor : Integer; var XCenter, ZCenterFromY : Extended; var PointOfInterest : TPoint; var TotalPointCount : Integer; begin MAXX := Length(MAP); MAXY := Length(MAP[0]); SetLength(SCREENPOINTS, 0); SetLength(MAPPOINTS, MAXX * MAXY); TotalPointCount := 0; MidX := (MAXX shr 1) - 1.0; MidY := (MAXY shr 1) - 0.75; for indexX := 0 to MAXX - 1 do begin X1 := MMX1 + (indexX shl 3) + 2; X2 := X1 + 4; for indexY := 0 to MAXY - 1 do begin Y1 := MMY1 + (indexY shl 3) + 2; Y2 := Y1 + 4; BOX.X1 := X1; BOX.X2 := X2; BOX.Y1 := Y1; BOX.Y2 := Y2; ChosenColor := clGray; // check case (MAP[indexX][indexY]) of MAP_TYPE_OUTSIDE: ChosenColor := clPurple; MAP_TYPE_UNTESTED: ChosenColor := clGray; MAP_TYPE_EDGE: ChosenColor := clRed; MAP_TYPE_ISLAND: ChosenColor := clGreen; end; XCenter := indexX - MidX; ZCenterFromY := indexY - MidY; // calculate if (ZCenterFromY + 1.5 >= PERSPECTIVE_MM_CAMERA_Z * 8) then begin // too close to camera, not on screen, discard MAP3D[indexX][indexY].X1 := -1; MAP3D[indexX][indexY].Y1 := -1; MAP3D[indexX][indexY].X2 := -1; MAP3D[indexX][indexY].Y2 := -1; continue; end else begin if (XCenter > -0.5) then begin // right edge is determined by front right top PointOfInterest := GetPerspectivePoint(XCenter + 0.5, MAXHEIGHT, ZCenterFromY + 0.5); MAP3D[indexX][indexY].X2 := PointOfInterest.x; end else begin // right edge is determined by back right bottom PointOfInterest := GetPerspectivePoint(XCenter + 0.5, 0, ZCenterFromY - 0.5); MAP3D[indexX][indexY].X2 := PointOfInterest.x; end; // bottom edge is determined by front right bottom PointOfInterest := GetPerspectivePoint(XCenter + 0.5, 0, ZCenterFromY + 0.5); MAP3D[indexX][indexY].Y2 := PointOfInterest.y; if (XCenter < 0.5) then begin // left edge is determined by front left top PointOfInterest := GetPerspectivePoint(XCenter - 0.5, MAXHEIGHT, ZCenterFromY + 0.5); MAP3D[indexX][indexY].X1 := PointOfInterest.x; end else begin // left edge is determined by front left top PointOfInterest := GetPerspectivePoint(XCenter - 0.5, MAXHEIGHT, ZCenterFromY + 0.5); MAP3D[indexX][indexY].X1 := PointOfInterest.x; end; // top edge is determined by back left top PointOfInterest := GetPerspectivePoint(XCenter - 0.5, MAXHEIGHT, ZCenterFromY - 0.5); MAP3D[indexX][indexY].Y1 := PointOfInterest.y; // check if in area if (MAP3D[indexX][indexY].X1 >= MSX2) or (MAP3D[indexX][indexY].Y1 >= MSY2) or (MAP3D[indexX][indexY].X2 <= MSX1) or (MAP3D[indexX][indexY].Y2 <= MSY1) then begin // outside of main screen MAP3D[indexX][indexY].X1 := -1; MAP3D[indexX][indexY].Y1 := -1; MAP3D[indexX][indexY].X2 := -1; MAP3D[indexX][indexY].Y2 := -1; continue; end; end; MAPPOINTS[TotalPointCount].X := IndexX; MAPPOINTS[TotalPointCount].Y := IndexY; Inc(TotalPointCount); DrawMapCube(XCenter, ZCenterFromY, ChosenColor); end; end; SetLength(MAPPOINTS, TotalPointCount); end; procedure DrawMap; var MAXX : Integer; var MAXY : Integer; var indexX : Integer; var indexY : Integer; var X1,X2,Y1,Y2 : Integer; var BOX : TBox; var MidX, MidY : Extended; begin MAXX := Length(MAP); MAXY := Length(MAP[0]); MidX := (MAXX shr 1) - 1.0; MidY := (MAXY shr 1) - 0.75; for indexX := 0 to MAXX - 1 do begin X1 := MMX1 + (indexX shl 3) + 2; X2 := X1 + 4; for indexY := 0 to MAXY - 1 do begin Y1 := MMY1 + (indexY shl 3) + 2; Y2 := Y1 + 4; BOX.X1 := X1; BOX.X2 := X2; BOX.Y1 := Y1; BOX.Y2 := Y2;
Cont....
Code:// check case (MAP[indexX][indexY]) of MAP_TYPE_UNTESTED: begin end; MAP_TYPE_EDGE: begin if ONSCREEN_TRACK_BOUNDARY then if ((IndexY >= 6) and (IndexY <= 11) and (indexX >= 6) and (indexX <= 12)) then DrawMapCube(indexX - MidX, indexY - MidY, clRed); end; MAP_TYPE_ISLAND: begin if ONSCREEN_TRACK_BOUNDARY then if (IndexY = 9) and (indexX = 9) then DrawMapCube(indexX - MidX, indexY - MidY, clGreen); end; end; end; end; end; procedure Initialize3D(); begin CalculateTransformAngleMM; end; procedure InitializeTPAModels(); begin SetLength(TPAModelList, 0); SetLength(ModelAccounting, 0); InitializeTargetOrder; end; function MakeTPAModelCopy(Model : TPAModel) : TPAModel; var Index : Integer; begin Result.ModelType := Model.ModelType; Result.Descriptor := Model.Descriptor; SetLength(Result.ColorToleranceDefinition, Length(Model.ColorToleranceDefinition)); for Index := 0 to Length(Model.ColorToleranceDefinition) - 1 do begin Result.ColorToleranceDefinition[Index].Color := Model.ColorToleranceDefinition[Index].Color; Result.ColorToleranceDefinition[Index].Tolerance := Model.ColorToleranceDefinition[Index].Tolerance; Result.ColorToleranceDefinition[Index].MinHitsRequired := Model.ColorToleranceDefinition[Index].MinHitsRequired; Result.ColorToleranceDefinition[Index].ToleranceSpeed := Model.ColorToleranceDefinition[Index].ToleranceSpeed; end; SetLength(Result.ColorToleranceExcludes, Length(Model.ColorToleranceExcludes)); for Index := 0 to Length(Model.ColorToleranceExcludes) - 1 do begin Result.ColorToleranceExcludes[Index].Color := Model.ColorToleranceExcludes[Index].Color; Result.ColorToleranceExcludes[Index].Tolerance := Model.ColorToleranceExcludes[Index].Tolerance; Result.ColorToleranceExcludes[Index].MinHitsRequired := Model.ColorToleranceExcludes[Index].MinHitsRequired; Result.ColorToleranceExcludes[Index].ToleranceSpeed := Model.ColorToleranceExcludes[Index].ToleranceSpeed; end; Result.Hound := Model.Hound; Result.XP := Model.XP; Result.MinimumFloor := Model.MinimumFloor; Result.MinimumLevel := Model.MinimumLevel; Result.MemberOnly := Model.MemberOnly; SetLength(Result.Runes, Length(Model.Runes)); for Index := 0 to Length(Model.Runes) - 1 do begin Result.Runes[Index] := Model.Runes[Index]; end; Result.ChipRune := Model.ChipRune; end; procedure AddTPAModel(NewModel : TPAModel); var Index : Integer; begin Index := Length(TPAModelList); SetLength(TPAModelList, Index + 1); TPAModelList[Index] := MakeTPAModelCopy(NewModel); end; const STANDARD_TOLERANCE = 10; const WIDER_TOLERANCE = 20; (* COMPLETED: FULL ENVIRONMENTALS FOR ALL FLOORS COMPLETED MODELS: 3RD ALL ESSWRAITHS 3RD ALL SINGLE RUNE NODES: BLOOD POOL (little loose), SKULLS 2ND: DOUBLE RUNE NODES: SINGLE RUNE NODES: F2P NODES: HOUNDS: F2P HOUNDS 1ST: DOUBLE RUNE NODES: SINGLE RUNE NODES: ESSLINGS: NOT YET COMPLETED MODELS: 3RD DOUBLE RUNE NODES: UNDEAD SOULS (NOT WELL TESTED YET), LIVING SOUL (TESTING) 2ND: DOUBLE RUNE NODES: SINGLE RUNE NODES: F2P NODES: HOUNDS: F2P HOUNDS 1ST: DOUBLE RUNE NODES: SINGLE RUNE NODES: ESSLINGS: *) procedure RegisterTPAModels; var Model : TPAModel; begin InitializeTPAModels; (* Ok before i get crap for putting begin/end around blocks that do not need them - i use it so i can collapse code, if you tell me how to get same functionality as #region/#endregion, i'll be happy to change that *) // environmental excludes begin // this is stub and will not contain excludes SetLength(EnvironmentalExcludes[0], 0); end; begin // first floor environmentals SetLength(EnvironmentalExcludes[1], 3); EnvironmentalExcludes[1][0].Color := $286060; EnvironmentalExcludes[1][0].Tolerance := WIDER_TOLERANCE; EnvironmentalExcludes[1][0].ToleranceSpeed := 0; EnvironmentalExcludes[1][0].MinHitsRequired := 900; EnvironmentalExcludes[1][1].Color := $489898; EnvironmentalExcludes[1][1].Tolerance := WIDER_TOLERANCE; EnvironmentalExcludes[1][1].ToleranceSpeed := 0; EnvironmentalExcludes[1][1].MinHitsRequired := 700; EnvironmentalExcludes[1][2].Color := $68A8F8; EnvironmentalExcludes[1][2].Tolerance := WIDER_TOLERANCE; EnvironmentalExcludes[1][2].ToleranceSpeed := 0; EnvironmentalExcludes[1][2].MinHitsRequired := 700; end; begin // second floor environmentals SetLength(EnvironmentalExcludes[2], 3); EnvironmentalExcludes[1][0].Color := $485068; EnvironmentalExcludes[1][0].Tolerance := WIDER_TOLERANCE; EnvironmentalExcludes[1][0].ToleranceSpeed := 0; EnvironmentalExcludes[1][0].MinHitsRequired := 900; EnvironmentalExcludes[1][1].Color := $7068A0; EnvironmentalExcludes[1][1].Tolerance := WIDER_TOLERANCE; EnvironmentalExcludes[1][1].ToleranceSpeed := 0; EnvironmentalExcludes[1][1].MinHitsRequired := 800; EnvironmentalExcludes[1][2].Color := $D080E0; EnvironmentalExcludes[1][2].Tolerance := WIDER_TOLERANCE; EnvironmentalExcludes[1][2].ToleranceSpeed := 0; EnvironmentalExcludes[1][2].MinHitsRequired := 700; end; begin // third floor environmentals SetLength(EnvironmentalExcludes[3], 3); EnvironmentalExcludes[3][0].Color := $787888; EnvironmentalExcludes[3][0].Tolerance := WIDER_TOLERANCE; EnvironmentalExcludes[3][0].ToleranceSpeed := 0; EnvironmentalExcludes[3][0].MinHitsRequired := 700; EnvironmentalExcludes[3][1].Color := $4850A8; EnvironmentalExcludes[3][1].Tolerance := WIDER_TOLERANCE; EnvironmentalExcludes[3][1].ToleranceSpeed := 0; EnvironmentalExcludes[3][1].MinHitsRequired := 700; EnvironmentalExcludes[3][2].Color := $181850; EnvironmentalExcludes[3][2].Tolerance := WIDER_TOLERANCE; EnvironmentalExcludes[3][2].ToleranceSpeed := 0; EnvironmentalExcludes[3][2].MinHitsRequired := 400; end; begin // third floor hounds SetLength(Model.ColorToleranceDefinition, 0); SetLength(Model.ColorToleranceExcludes, 0); Model.MinimumFloor := 3; Model.MemberOnly := True; Model.Hound := True; SetLength(Model.Runes, 1); end; begin // soul wraith Model.Descriptor := 'Soul esswraith'; Model.ModelType := TARGET_SOUL_ESSWRAITH; SetLength(Model.ColorToleranceExcludes, 0); SetLength(Model.ColorToleranceDefinition, 3); begin // colors by palette Model.ColorToleranceDefinition[0].Color := $70B0F8; //C0C0A8; Model.ColorToleranceDefinition[0].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[0].MinHitsRequired := 5; Model.ColorToleranceDefinition[0].ToleranceSpeed := 0; Model.ColorToleranceDefinition[1].Color := $5890b8; Model.ColorToleranceDefinition[1].Tolerance := WIDER_TOLERANCE; Model.ColorToleranceDefinition[1].MinHitsRequired := 5; Model.ColorToleranceDefinition[1].ToleranceSpeed := 0; Model.ColorToleranceDefinition[2].Color := $A08030; Model.ColorToleranceDefinition[2].Tolerance := WIDER_TOLERANCE; Model.ColorToleranceDefinition[2].MinHitsRequired := 5; Model.ColorToleranceDefinition[2].ToleranceSpeed := 0; end; Model.ColorToleranceDefinition[0].Color := 9008683; //8618097; Model.ColorToleranceDefinition[1].Color := 3096660; //8351271; Model.XP := 107; Model.MinimumLevel := 90; Model.Runes[0] := TYPE_RUNE_SOUL; Model.ChipRune := TYPE_RUNE_BLOOD; AddTPAModel(Model); end; begin // blood wraith Model.ModelType := TARGET_BLOOD_ESSWRAITH; Model.Descriptor := 'Blood esswraith'; SetLength(Model.ColorToleranceExcludes, 1); begin // prevent confusion with death Model.ColorToleranceExcludes[0].Color := $688880; Model.ColorToleranceExcludes[0].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceExcludes[0].MinHitsRequired := 40; Model.ColorToleranceExcludes[0].ToleranceSpeed := 0; end; SetLength(Model.ColorToleranceDefinition, 4); begin // colors by palette analysis - first color done Model.ColorToleranceDefinition[0].Color := $B8A0B8; Model.ColorToleranceDefinition[0].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[0].MinHitsRequired := 5; Model.ColorToleranceDefinition[0].ToleranceSpeed := 0; Model.ColorToleranceDefinition[1].Color := 4340806; Model.ColorToleranceDefinition[1].Tolerance := WIDER_TOLERANCE; Model.ColorToleranceDefinition[1].MinHitsRequired := 1; // auto for now Model.ColorToleranceDefinition[1].ToleranceSpeed := 0; Model.ColorToleranceDefinition[2].Color := 7364718; Model.ColorToleranceDefinition[2].Tolerance := WIDER_TOLERANCE; Model.ColorToleranceDefinition[2].MinHitsRequired := 150; // auto for now Model.ColorToleranceDefinition[2].ToleranceSpeed := 0; Model.ColorToleranceDefinition[3].Color := 4408899; Model.ColorToleranceDefinition[3].Tolerance := WIDER_TOLERANCE; Model.ColorToleranceDefinition[3].MinHitsRequired := 110; // auto for now Model.ColorToleranceDefinition[3].ToleranceSpeed := 0; end; Model.XP := 73; Model.MinimumLevel := 77; Model.Runes[0] := TYPE_RUNE_BLOOD; Model.ChipRune := TYPE_RUNE_LAW; AddTPAModel(Model); end; begin // death wraith Model.ModelType := TARGET_DEATH_ESSWRAITH; Model.Descriptor := 'Death esswraith'; SetLength(Model.ColorToleranceExcludes, 0); SetLength(Model.ColorToleranceDefinition, 2); begin Model.ColorToleranceDefinition[0].Color := $688880; Model.ColorToleranceDefinition[0].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[0].MinHitsRequired := 2; Model.ColorToleranceDefinition[0].ToleranceSpeed := 0; Model.ColorToleranceDefinition[1].Color := $304840; Model.ColorToleranceDefinition[1].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[1].MinHitsRequired := 10; Model.ColorToleranceDefinition[1].ToleranceSpeed := 0; end; Model.XP := 60; Model.MinimumLevel := 65; Model.Runes[0] := TYPE_RUNE_DEATH; Model.ChipRune := TYPE_RUNE_NATURE; AddTPAModel(Model); end; // third floor nodes double runes begin SetLength(Model.ColorToleranceDefinition, 0); SetLength(Model.ColorToleranceExcludes, 0); Model.MinimumFloor := 3; Model.MemberOnly := True; Model.Hound := False; SetLength(Model.Runes, 2); Model.ChipRune := TYPE_RUNE_NONE; end; // undead soul NOT YET TESTED begin Model.ModelType := TARGET_UNDEAD_SOUL; Model.Descriptor := 'Undead soul'; SetLength(Model.ColorToleranceExcludes, 0); SetLength(Model.ColorToleranceDefinition, 3); begin Model.ColorToleranceDefinition[0].Color := $343034; // 2564902; Model.ColorToleranceDefinition[0].ToleranceSpeed := 0; Model.ColorToleranceDefinition[0].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[0].MinHitsRequired := 5; // auto for now Model.ColorToleranceDefinition[1].Color := $9888A0; //8476273; Model.ColorToleranceDefinition[1].ToleranceSpeed := 0; Model.ColorToleranceDefinition[1].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[1].MinHitsRequired := 5; // auto for now Model.ColorToleranceDefinition[2].Color := $907090; // 10513548; Model.ColorToleranceDefinition[2].ToleranceSpeed := 0; Model.ColorToleranceDefinition[2].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[2].MinHitsRequired := 5; // auto for now end; Model.XP := 200; Model.MinimumLevel := 95; Model.Runes[0] := TYPE_RUNE_BLOOD; Model.Runes[1] := TYPE_RUNE_DEATH; AddTPAModel(Model); end; begin // bloody skulls Model.ModelType := TARGET_BLOODY_SKULLS; Model.Descriptor := 'Bloody skulls'; SetLength(Model.ColorToleranceExcludes, 0); SetLength(Model.ColorToleranceDefinition, 3); begin // colors by palette analysis Model.ColorToleranceDefinition[0].Color := $000840; Model.ColorToleranceDefinition[0].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[0].MinHitsRequired := 5; Model.ColorToleranceDefinition[0].ToleranceSpeed := 0; Model.ColorToleranceDefinition[1].Color := $080818; Model.ColorToleranceDefinition[1].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[1].MinHitsRequired := 5; Model.ColorToleranceDefinition[1].ToleranceSpeed := 0; Model.ColorToleranceDefinition[2].Color := $303090; Model.ColorToleranceDefinition[2].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[2].MinHitsRequired := 5; Model.ColorToleranceDefinition[2].ToleranceSpeed := 0; end; Model.XP := 160; Model.MinimumLevel := 83; Model.Runes[0] := TYPE_RUNE_BLOOD; Model.Runes[1] := TYPE_RUNE_DEATH; AddTPAModel(Model); end; // third floor nodes single runes begin SetLength(Model.ColorToleranceExcludes, 0); SetLength(Model.ColorToleranceDefinition, 0); Model.MinimumFloor := 3; Model.MemberOnly := True; Model.Hound := False; SetLength(Model.Runes, 1); Model.ChipRune := TYPE_RUNE_NONE; end; begin // living soul Model.ModelType := TARGET_LIVING_SOUL; Model.Descriptor := 'Living soul'; SetLength(Model.ColorToleranceExcludes, 0); SetLength(Model.ColorToleranceDefinition, 3); begin Model.ColorToleranceDefinition[0].Color := $B85840; //12212035; Model.ColorToleranceDefinition[0].MinHitsRequired := 5; Model.ColorToleranceDefinition[0].Tolerance := WIDER_TOLERANCE; Model.ColorToleranceDefinition[0].ToleranceSpeed := 0; Model.ColorToleranceDefinition[1].Color := $C86090;// 13329038; Model.ColorToleranceDefinition[1].MinHitsRequired := 5; Model.ColorToleranceDefinition[1].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[1].ToleranceSpeed := 0; Model.ColorToleranceDefinition[2].Color := $D878A0; //13794450; Model.ColorToleranceDefinition[2].MinHitsRequired := 5; Model.ColorToleranceDefinition[2].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[2].ToleranceSpeed := 0; end; Model.XP := 213; Model.MinimumLevel := 90; Model.Runes[0] := TYPE_RUNE_SOUL; AddTPAModel(Model); end; begin // blood pool Model.ModelType := TARGET_BLOOD_POOL; Model.Descriptor := 'Blood pool'; SetLength(Model.ColorToleranceExcludes, 6); begin // various excludes and reasons why false matches occured // essence by edge Model.ColorToleranceExcludes[0].Color := $686868; Model.ColorToleranceExcludes[0].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceExcludes[0].MinHitsRequired := 10; Model.ColorToleranceExcludes[0].ToleranceSpeed := 0; // purple clothing with brown and red edging, get rid of purple Model.ColorToleranceExcludes[1].Color := $402028; Model.ColorToleranceExcludes[1].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceExcludes[1].MinHitsRequired := 10; Model.ColorToleranceExcludes[1].ToleranceSpeed := 0; // fireball near essence and edge Model.ColorToleranceExcludes[2].Color := $40A0D0; Model.ColorToleranceExcludes[2].Tolerance := WIDER_TOLERANCE; Model.ColorToleranceExcludes[2].MinHitsRequired := 10; Model.ColorToleranceExcludes[2].ToleranceSpeed := 0; // bloody skull Model.ColorToleranceExcludes[3].Color := $303090; Model.ColorToleranceExcludes[3].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceExcludes[3].MinHitsRequired := 5; Model.ColorToleranceExcludes[3].ToleranceSpeed := 0; // blood wraith Model.ColorToleranceExcludes[4].Color := $B8A0B8; Model.ColorToleranceExcludes[4].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceExcludes[4].MinHitsRequired := 5; Model.ColorToleranceExcludes[4].ToleranceSpeed := 0; // stones Model.ColorToleranceExcludes[5].Color := $787888; Model.ColorToleranceExcludes[5].Tolerance := WIDER_TOLERANCE; Model.ColorToleranceExcludes[5].ToleranceSpeed := 0; Model.ColorToleranceExcludes[5].MinHitsRequired := 50; end; SetLength(Model.ColorToleranceDefinition, 3); begin Model.ColorToleranceDefinition[0].Color := $18188A; Model.ColorToleranceDefinition[0].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[0].MinHitsRequired := 30; Model.ColorToleranceDefinition[0].ToleranceSpeed := 0; Model.ColorToleranceDefinition[1].Color := $304050; Model.ColorToleranceDefinition[1].Tolerance := STANDARD_TOLERANCE;// WIDER_TOLERANCE; Model.ColorToleranceDefinition[1].MinHitsRequired := 10; Model.ColorToleranceDefinition[1].ToleranceSpeed := 0; Model.ColorToleranceDefinition[2].Color := $506880; Model.ColorToleranceDefinition[2].Tolerance := STANDARD_TOLERANCE; //WIDER_TOLERANCE; Model.ColorToleranceDefinition[2].MinHitsRequired := 10; Model.ColorToleranceDefinition[2].ToleranceSpeed := 0; end; Model.XP := 146; Model.MinimumLevel := 77; Model.Runes[0] := TYPE_RUNE_BLOOD; AddTPAModel(Model); Model.ColorToleranceDefinition[0].Tolerance := 20; Model.ColorToleranceDefinition[1].Tolerance := 20; Model.ColorToleranceDefinition[2].Tolerance := 20; SetLength(Model.ColorToleranceExcludes, 0); end; begin // skulls Model.ModelType := TARGET_SKULLS; Model.Descriptor := 'Skulls'; SetLength(Model.ColorToleranceExcludes, 0); SetLength(Model.ColorToleranceDefinition, 3); begin Model.ColorToleranceDefinition[0].Color := $98CCE2; Model.ColorToleranceDefinition[0].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[0].MinHitsRequired := 2; Model.ColorToleranceDefinition[0].ToleranceSpeed := 0; Model.ColorToleranceDefinition[1].Color := $405060; Model.ColorToleranceDefinition[1].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[1].MinHitsRequired := 5; Model.ColorToleranceDefinition[1].ToleranceSpeed := 0; Model.ColorToleranceDefinition[2].Color := $0C0D0E; Model.ColorToleranceDefinition[2].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[1].MinHitsRequired := 6; Model.ColorToleranceDefinition[1].ToleranceSpeed := 0; end; Model.XP := 120; Model.MinimumLevel := 65; Model.Runes[0] := TYPE_RUNE_DEATH; AddTPAModel(Model); Model.ColorToleranceDefinition[0].Tolerance := 20; Model.ColorToleranceDefinition[1].Tolerance := 20; Model.ColorToleranceDefinition[2].Tolerance := 20; SetLength(Model.ColorToleranceExcludes, 0); end; // second floor hounds member only begin Model.MinimumFloor := 2; Model.MemberOnly := true; Model.Hound := True; SetLength(Model.Runes, 1); SetLength(Model.ColorToleranceDefinition, 2); Model.ColorToleranceDefinition[0].Tolerance := 20; Model.ColorToleranceDefinition[1].Tolerance := 20; Model.ColorToleranceDefinition[0].MinHitsRequired := 0; // auto for now Model.ColorToleranceDefinition[1].MinHitsRequired := 0; // auto for now Model.ColorToleranceDefinition[0].ToleranceSpeed := 2; Model.ColorToleranceDefinition[1].ToleranceSpeed := 2; end; // law begin Model.ModelType := TARGET_LAW_ESSHOUND; Model.Descriptor := 'Law esshound'; Model.ColorToleranceDefinition[0].Color := 14394930; // 10776124; Model.ColorToleranceDefinition[1].Color := GENERIC_ESSHOUND; Model.XP := 54; Model.MinimumLevel := 54; Model.Runes[0] := TYPE_RUNE_LAW; Model.ChipRune := TYPE_RUNE_ASTRAL; AddTPAModel(Model); end // law/generic begin Model.ModelType := TARGET_GENERIC_ESSHOUND; Model.Descriptor := ' esshound'; Model.ColorToleranceDefinition[0].Color := 16620172; Model.ColorToleranceDefinition[1].Color := GENERIC_ESSHOUND; Model.XP := 22; // so that even body supercedes Model.MinimumLevel := 54; Model.Runes[0] := TYPE_RUNE_NONE; Model.ChipRune := TYPE_RUNE_NONE; AddTPAModel(Model); end; // nature begin Model.ModelType := TARGET_NATURE_ESSHOUND; Model.Descriptor := 'Nature esshound'; Model.ColorToleranceDefinition[0].Color := 5145157; Model.ColorToleranceDefinition[1].Color := GENERIC_ESSHOUND; Model.XP := 44; Model.MinimumLevel := 44; Model.Runes[0] := TYPE_RUNE_NATURE; Model.ChipRune := TYPE_RUNE_CHAOS; AddTPAModel(Model); end; // astral begin Model.ModelType := TARGET_ASTRAL_ESSHOUND; Model.Descriptor := 'Astral esshound'; Model.ColorToleranceDefinition[0].Tolerance := 10; Model.ColorToleranceDefinition[0].Color := 14468828; Model.ColorToleranceDefinition[1].Color := GENERIC_ESSHOUND; Model.XP := 36; Model.MinimumLevel := 40; Model.Runes[0] := TYPE_RUNE_ASTRAL; Model.ChipRune := TYPE_RUNE_COSMIC; AddTPAModel(Model); Model.ColorToleranceDefinition[0].Tolerance := 20; end; // chaos begin Model.ModelType := TARGET_CHAOS_ESSHOUND; Model.Descriptor := 'Chaos esshound'; Model.ColorToleranceDefinition[0].Color := 2729445; //2598117; Model.ColorToleranceDefinition[1].Color := GENERIC_ESSHOUND; Model.XP := 31; Model.MinimumLevel := 36; Model.Runes[0] := TYPE_RUNE_CHAOS; Model.ChipRune := TYPE_RUNE_FIRE; AddTPAModel(Model); end; // cosmic begin Model.ModelType := TARGET_COSMIC_ESSHOUND; Model.Descriptor := 'Cosmic esshound'; Model.ColorToleranceDefinition[0].Tolerance := 10; Model.ColorToleranceDefinition[0].Color := 7339005; //5239547; Model.ColorToleranceDefinition[1].Color := GENERIC_ESSHOUND; Model.XP := 36; Model.MinimumLevel := 40; Model.Runes[0] := TYPE_RUNE_COSMIC; Model.ChipRune := TYPE_RUNE_EARTH; AddTPAModel(Model); Model.ColorToleranceDefinition[0].Tolerance := 10; end; // second floor hounds f2p Model.MinimumFloor := 2; Model.MemberOnly := False; Model.Hound := True; SetLength(Model.Runes, 1); SetLength(Model.ColorToleranceDefinition, 2); Model.ColorToleranceDefinition[0].ToleranceSpeed := 2; Model.ColorToleranceDefinition[1].ToleranceSpeed := 2; // body NOT YET TESTED Model.ModelType := TARGET_BODY_ESSHOUND; Model.Descriptor := 'Body esshound'; Model.ColorToleranceDefinition[0].Color := 11414827; Model.ColorToleranceDefinition[1].Color := GENERIC_ESSHOUND; Model.XP := 23; Model.MinimumLevel := 20; Model.Runes[0] := TYPE_RUNE_BODY; Model.ChipRune := TYPE_RUNE_MIND; AddTPAModel(Model); // second floor nodes member double runes Model.MinimumFloor := 2; Model.MemberOnly := true; Model.Hound := False; SetLength(Model.Runes, 2); Model.ChipRune := TYPE_RUNE_NONE; Model.ColorToleranceDefinition[0].MinHitsRequired := 0; // auto for now Model.ColorToleranceDefinition[1].MinHitsRequired := 0; // auto for now // nebula NOT YET TESTED Model.ModelType := TARGET_NEBULA; Model.Descriptor := 'Nebula'; Model.ColorToleranceDefinition[0].Color := 8001883; Model.ColorToleranceDefinition[1].Color := 9443741; Model.XP := 75; Model.MinimumLevel := 40; Model.Runes[0] := TYPE_RUNE_ASTRAL; Model.Runes[1] := TYPE_RUNE_COSMIC; AddTPAModel(Model); // second floor nodes member single runes Model.MinimumFloor := 2; Model.MemberOnly := true; Model.Hound := False; SetLength(Model.Runes, 1); Model.ChipRune := TYPE_RUNE_NONE; SetLength(Model.ColorToleranceDefinition, 2); begin // jumper Model.ModelType := TARGET_JUMPER; Model.Descriptor := 'Jumper'; SetLength(Model.ColorToleranceExcludes, 0); SetLength(Model.ColorToleranceDefinition, 2); begin Model.ColorToleranceDefinition[0].Color := $F8B050; Model.ColorToleranceDefinition[0].MinHitsRequired := 10; Model.ColorToleranceDefinition[0].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[0].ToleranceSpeed := 0; Model.ColorToleranceDefinition[1].Color := $E8A048; Model.ColorToleranceDefinition[1].MinHitsRequired := 2; Model.ColorToleranceDefinition[1].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[1].ToleranceSpeed := 0; end; Model.XP := 108; Model.MinimumLevel := 54; Model.Runes[0] := TYPE_RUNE_LAW; AddTPAModel(Model); end; begin // shifter Model.ModelType := TARGET_SHIFTER; Model.Descriptor := 'Shifter'; SetLength(Model.ColorToleranceExcludes, 0); SetLength(Model.ColorToleranceDefinition, 2); begin Model.ColorToleranceDefinition[0].Color := $30F828; Model.ColorToleranceDefinition[0].MinHitsRequired := 20; Model.ColorToleranceDefinition[0].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[0].ToleranceSpeed := 0; Model.ColorToleranceDefinition[1].Color := $20D020; Model.ColorToleranceDefinition[1].MinHitsRequired := 5; Model.ColorToleranceDefinition[1].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[1].ToleranceSpeed := 0; end; Model.XP := 87; Model.MinimumLevel := 44; Model.Runes[0] := TYPE_RUNE_NATURE; AddTPAModel(Model); end; // chaotic cloud begin Model.ModelType := TARGET_CHAOTIC_CLOUD; Model.Descriptor := 'Chaotic cloud'; Model.ColorToleranceDefinition[0].Color := 1446423; Model.ColorToleranceDefinition[1].Color := 1511722; Model.ColorToleranceDefinition[0].Tolerance := 20; Model.ColorToleranceDefinition[1].Tolerance := 20; Model.ColorToleranceDefinition[0].MinHitsRequired := 0; // auto for now Model.ColorToleranceDefinition[1].MinHitsRequired := 0; // auto for now Model.ColorToleranceDefinition[0].ToleranceSpeed := 2; Model.ColorToleranceDefinition[1].ToleranceSpeed := 2; Model.XP := 62; Model.MinimumLevel := 35; Model.Runes[0] := TYPE_RUNE_CHAOS; AddTPAModel(Model); end; // second floor nodes f2p begin Model.MinimumFloor := 2; Model.MemberOnly := False; Model.Hound := False; SetLength(Model.Runes, 1); Model.ChipRune := TYPE_RUNE_NONE; SetLength(Model.ColorToleranceDefinition, 4); Model.ColorToleranceDefinition[0].Tolerance := 20; Model.ColorToleranceDefinition[1].Tolerance := 20; Model.ColorToleranceDefinition[2].Tolerance := 20; Model.ColorToleranceDefinition[3].Tolerance := 20; Model.ColorToleranceDefinition[0].MinHitsRequired := 0; // auto for now Model.ColorToleranceDefinition[1].MinHitsRequired := 0; // auto for now Model.ColorToleranceDefinition[2].MinHitsRequired := 0; // auto for now Model.ColorToleranceDefinition[3].MinHitsRequired := 0; // auto for now Model.ColorToleranceDefinition[0].ToleranceSpeed := 2; Model.ColorToleranceDefinition[1].ToleranceSpeed := 2; Model.ColorToleranceDefinition[2].ToleranceSpeed := 2; Model.ColorToleranceDefinition[3].ToleranceSpeed := 2; end; begin // fleshy growth Model.ModelType := TARGET_FLESHY_GROWTH; Model.Descriptor := 'Fleshy growth'; SetLength(Model.ColorToleranceExcludes, 0); SetLength(Model.ColorToleranceDefinition, 4); begin Model.ColorToleranceDefinition[0].Color := $5868a0; Model.ColorToleranceDefinition[0].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[0].ToleranceSpeed := 0; Model.ColorToleranceDefinition[0].MinHitsRequired := 5; Model.ColorToleranceDefinition[1].Color := $303080; Model.ColorToleranceDefinition[1].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[1].ToleranceSpeed := 0; Model.ColorToleranceDefinition[1].MinHitsRequired := 5; Model.ColorToleranceDefinition[2].Color := $305098; Model.ColorToleranceDefinition[2].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[2].ToleranceSpeed := 0; Model.ColorToleranceDefinition[2].MinHitsRequired := 5; Model.ColorToleranceDefinition[3].Color := $485880; Model.ColorToleranceDefinition[3].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[3].ToleranceSpeed := 0; Model.ColorToleranceDefinition[3].MinHitsRequired := 5; end; Model.XP := 46; Model.MinimumLevel := 20; Model.Runes[0] := TYPE_RUNE_BODY; AddTPAModel(Model); end; begin // fire storm Model.ModelType := TARGET_FIRE_STORM; Model.Descriptor := 'Fire storm'; SetLength(Model.ColorToleranceExcludes, 0); SetLength(Model.ColorToleranceDefinition, 3); begin Model.ColorToleranceDefinition[0].Color := $1848D0; Model.ColorToleranceDefinition[0].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[0].ToleranceSpeed := 0; Model.ColorToleranceDefinition[0].MinHitsRequired := 3; Model.ColorToleranceDefinition[1].Color := $1020A0; Model.ColorToleranceDefinition[1].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[1].ToleranceSpeed := 0; Model.ColorToleranceDefinition[1].MinHitsRequired := 5; Model.ColorToleranceDefinition[2].Color := $081028; Model.ColorToleranceDefinition[2].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[2].ToleranceSpeed := 0; Model.ColorToleranceDefinition[2].MinHitsRequired := 5; end; Model.XP := 32; Model.MinimumLevel := 27; SetLength(Model.Runes, 2); Model.Runes[0] := TYPE_RUNE_FIRE; Model.Runes[1] := TYPE_RUNE_AIR; AddTPAModel(Model); end; // first floor nodes double runes Model.MinimumFloor := 1; Model.MemberOnly := False; Model.Hound := False; SetLength(Model.Runes, 2); Model.ChipRune := TYPE_RUNE_NONE; SetLength(Model.ColorToleranceDefinition, 2); Model.ColorToleranceDefinition[0].ToleranceSpeed := 2; Model.ColorToleranceDefinition[1].ToleranceSpeed := 2; Model.ColorToleranceDefinition[0].Tolerance := 20; Model.ColorToleranceDefinition[1].Tolerance := 20; Model.ColorToleranceDefinition[0].MinHitsRequired := 0; // auto for now Model.ColorToleranceDefinition[1].MinHitsRequired := 0; // auto for now // vine Model.ModelType := TARGET_VINE; Model.Descriptor := 'Vine'; Model.ColorToleranceDefinition[0].ToleranceSpeed := 2; Model.ColorToleranceDefinition[1].ToleranceSpeed := 2; Model.ColorToleranceDefinition[0].Tolerance := 10; Model.ColorToleranceDefinition[1].Tolerance := 10; Model.ColorToleranceDefinition[0].MinHitsRequired := 0; // auto for now Model.ColorToleranceDefinition[1].MinHitsRequired := 0; // auto for now Model.ColorToleranceDefinition[0].Color := 2178115; Model.ColorToleranceDefinition[1].Color := 145447; Model.XP := 33; Model.MinimumLevel := 17; Model.Runes[0] := TYPE_RUNE_EARTH; Model.Runes[1] := TYPE_RUNE_WATER; AddTPAModel(Model); Model.ColorToleranceDefinition[0].Tolerance := 20; Model.ColorToleranceDefinition[1].Tolerance := 20; // first floor nodes single runes Model.MinimumFloor := 1; Model.MemberOnly := False; Model.Hound := False; SetLength(Model.Runes, 1); Model.ChipRune := TYPE_RUNE_NONE; // fireball NOT YET TESTED on 2nd and 1st Model.ModelType := TARGET_FIREBALL; Model.Descriptor := 'Fireball'; Model.ColorToleranceDefinition[0].Color := 925837; Model.ColorToleranceDefinition[1].Color := 3513307; Model.XP := 35; Model.MinimumLevel := 14; Model.Runes[0] := TYPE_RUNE_FIRE; AddTPAModel(Model); // rock fragment Model.ModelType := TARGET_ROCK_FRAGMENT; SetLength(Model.ColorToleranceDefinition, 3); Model.ColorToleranceDefinition[0].Tolerance := 8; Model.ColorToleranceDefinition[1].Tolerance := 8; Model.ColorToleranceDefinition[2].Tolerance := 8; Model.ColorToleranceDefinition[0].ToleranceSpeed := 2; Model.ColorToleranceDefinition[1].ToleranceSpeed := 2; Model.ColorToleranceDefinition[2].ToleranceSpeed := 2; Model.Descriptor := 'Rock fragment'; Model.ColorToleranceDefinition[0].Color := 2639195 Model.ColorToleranceDefinition[1].Color := 5289629;//5488036; Model.ColorToleranceDefinition[2].Color := 4826768; Model.XP := 35; Model.MinimumLevel := 14; Model.Runes[0] := TYPE_RUNE_EARTH; AddTPAModel(Model); SetLength(Model.ColorToleranceDefinition, 2); Model.ColorToleranceDefinition[0].Tolerance := 20; Model.ColorToleranceDefinition[1].Tolerance := 20; Model.ColorToleranceDefinition[0].ToleranceSpeed := 2; Model.ColorToleranceDefinition[1].ToleranceSpeed := 2; // water pool NOT YET DONE Model.ModelType := TARGET_WATER_POOL; Model.Descriptor := 'Water pool'; Model.ColorToleranceDefinition[0].Tolerance := 10; Model.ColorToleranceDefinition[1].Tolerance := 10; Model.ColorToleranceDefinition[0].Color := 13353360; Model.ColorToleranceDefinition[1].Color := 10849114;// 12297056; Model.XP := 35; Model.MinimumLevel := 14; Model.Runes[0] := TYPE_RUNE_FIRE; AddTPAModel(Model); Model.ColorToleranceDefinition[0].Tolerance := 20; Model.ColorToleranceDefinition[1].Tolerance := 20; // mind storm NOT YET DONE Model.ModelType := TARGET_MIND_STORM; Model.Descriptor := 'Mind storm'; //Model.ColorToleranceDefinition[0].Color := 925837; //Model.ColorToleranceDefinition[1].Color := 4239833; Model.XP := 35; Model.MinimumLevel := 14; Model.Runes[0] := TYPE_RUNE_MIND; //AddTPAModel(Model); // cyclone NOT YET DONE Model.Descriptor := 'Cyclone'; Model.ModelType := TARGET_CYCLONE; //Model.ColorToleranceDefinition[0].Color := 925837; //Model.ColorToleranceDefinition[1].Color := 4239833; Model.XP := 35; Model.MinimumLevel := 14; Model.Runes[0] := TYPE_RUNE_AIR; //AddTPAModel(Model); // first floor hounds begin Model.MinimumFloor := 1; Model.MemberOnly := False; Model.Hound := True; SetLength(Model.Runes, 1); SetLength(Model.ColorToleranceDefinition, 2); Model.ColorToleranceDefinition[0].MinHitsRequired := 0; // auto for now Model.ColorToleranceDefinition[1].MinHitsRequired := 0; // auto for now Model.ColorToleranceDefinition[0].ToleranceSpeed := 2; Model.ColorToleranceDefinition[1].ToleranceSpeed := 2; end; // fire NOT YET DONE begin Model.ModelType := TARGET_FIRE_ESSLING; Model.Descriptor := 'Fire essling'; Model.ColorToleranceDefinition[0].Color := 5731996; // 12240595; Model.ColorToleranceDefinition[0].Tolerance := 10; // strict Model.ColorToleranceDefinition[1].Color := 11715024; //3692927; // 3890823; Model.ColorToleranceDefinition[1].Tolerance := 10; // strict Model.XP := 17; Model.MinimumLevel := 14; Model.Runes[0] := TYPE_RUNE_FIRE; Model.ChipRune := TYPE_RUNE_WATER; AddTPAModel(Model); // back to loose Model.ColorToleranceDefinition[0].Tolerance := 20; Model.ColorToleranceDefinition[1].Tolerance := 20; end; // earth begin Model.ModelType := TARGET_EARTH_ESSLING; Model.Descriptor := 'Earth essling'; Model.ColorToleranceDefinition[0].Color := 5465237; Model.ColorToleranceDefinition[0].Tolerance := 10; // strict Model.ColorToleranceDefinition[1].Color := 12769230; Model.XP := 14; Model.MinimumLevel := 9; Model.Runes[0] := TYPE_RUNE_EARTH; Model.ChipRune := TYPE_RUNE_WATER; AddTPAModel(Model); // back to loose Model.ColorToleranceDefinition[0].Tolerance := 20; Model.ColorToleranceDefinition[1].Tolerance := 20; end; // water begin Model.ModelType := TARGET_WATER_ESSLING; Model.Descriptor := 'Water essling'; Model.ColorToleranceDefinition[0].Color := 9601474; //4998761; - this one is bad in 2nd floor Model.ColorToleranceDefinition[1].Color := 13218923; //14075248;//13681804; Model.XP := 13; Model.MinimumLevel := 5; Model.Runes[0] := TYPE_RUNE_WATER; Model.ChipRune := TYPE_RUNE_AIR; AddTPAModel(Model); end; // mind begin Model.ModelType := TARGET_MIND_ESSLING; Model.Descriptor := 'Mind essling'; Model.ColorToleranceDefinition[0].Color := 6788506; //5602943; Model.ColorToleranceDefinition[1].Color := 13885421;//8569282; Model.XP := 10; Model.MinimumLevel := 1; Model.Runes[0] := TYPE_RUNE_MIND; Model.ChipRune := TYPE_RUNE_AIR; AddTPAModel(Model); end; begin // air essling Model.ModelType := TARGET_AIR_ESSLING; Model.Descriptor := 'Air essling'; SetLength(Model.ColorToleranceExcludes, 0); SetLength(Model.ColorToleranceDefinition, 4); begin // from palette analysis Model.ColorToleranceDefinition[0].Color := $d8b078; Model.ColorToleranceDefinition[0].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[0].MinHitsRequired := 2; Model.ColorToleranceDefinition[0].ToleranceSpeed := 0; Model.ColorToleranceDefinition[1].Color := $d0d8e0; Model.ColorToleranceDefinition[1].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[1].MinHitsRequired := 2; Model.ColorToleranceDefinition[1].ToleranceSpeed := 0; Model.ColorToleranceDefinition[2].Color := $a88858; Model.ColorToleranceDefinition[2].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[2].MinHitsRequired := 2; Model.ColorToleranceDefinition[2].ToleranceSpeed := 0; Model.ColorToleranceDefinition[3].Color := $786848; Model.ColorToleranceDefinition[3].Tolerance := STANDARD_TOLERANCE; Model.ColorToleranceDefinition[3].MinHitsRequired := 2; Model.ColorToleranceDefinition[3].ToleranceSpeed := 0; end; Model.XP := 10; Model.MinimumLevel := 1; Model.Runes[0] := TYPE_RUNE_AIR; Model.ChipRune := TYPE_RUNE_AIR; AddTPAModel(Model); end; end; function GetSearchOrderTPAModelList(HoundsOnly : Boolean; FloorLevelFilter : Integer; SkillLevelFilter : Integer; IsMember : Boolean) : TPAModelArray; var MyArray : TPAModelArray; var MyIndex : Integer; var index : Integer; var HighestModelXP : Integer; var HighestIndex : Integer; var OutputIndex : Integer; var XPCutoffThird : Integer; var OrderIndex : Integer; var MaxOrder : Integer; begin // init XPCutoffThird := SkillLevelFilter - 20; if (XPCutoffThird > 55) then XPCutoffThird := 55; SetLength(MyArray, Length(TPAModelList)); MyIndex := 0; // sweep for index := 0 to Length(TPAModelList) - 1 do begin if not IsMember then begin if TPAModelList[Index].MemberOnly then continue; end; if HoundsOnly then begin if not TPAModelList[Index].Hound then continue; end; if TPAModelList[Index].MinimumFloor > FloorLevelFilter then continue; if TPAModelList[Index].MinimumLevel > SkillLevelFilter then continue; if (SMART_THIRD_LEVEL) then begin // check if on 3rd level if FloorLevelFilter = 3 then begin // check by XP if (TPAModelList[Index].XP < XPCutoffThird) then continue; end; end; // got result MyArray[MyIndex] := TPAModelList[Index]; Inc(MyIndex); end; // do it SetLength(Result, MyIndex); OutputIndex := 0; // now let's order MaxOrder := Length(SELECTED_TARGET_ORDER); for OrderIndex := 0 to MaxOrder - 1 do begin repeat HighestModelXP := -1; HighestIndex := -1; for index := 0 to MyIndex - 1 do begin if MyArray[index].ModelType <> SELECTED_TARGET_ORDER[OrderIndex] then continue; if MyArray[index].XP < 0 then continue; if MyArray[index].XP <= HighestModelXP then continue; HighestModelXP := MyArray[Index].XP; HighestIndex := index; end; if (HighestIndex >= 0) then begin Result[OutputIndex] := MyArray[HighestIndex]; Inc(OutputIndex); MyArray[HighestIndex].XP := -1; end; until (HighestIndex < 0); end; end; function TestDenseColorRaster(Target : TColorTolerance; X1, Y1, X2, Y2 : Integer) : Boolean; var x,y : Integer; begin SetColorToleranceSpeed(Target.ToleranceSpeed); Result := FindColorTolerance(x, y, Target.Color, X1, Y1, X2, Y2, Target.Tolerance); SetColorToleranceSpeed(1); end; function TestDenseColorRasterCount(Target : TColorTolerance; X1, Y1, X2, Y2 : Integer) : Boolean; var minMatchCount : Integer; var NumberFound : Integer; begin Result := false; SetColorToleranceSpeed(Target.ToleranceSpeed); NumberFound := CountColorTolerance(Target.Color, X1, Y1, X2, Y2, Target.Tolerance); SetColorToleranceSpeed(1); // set up match count if (Target.MinHitsRequired > 0) then begin minMatchCount := Target.MinHitsRequired; end else begin minMatchCount := 5; if (Target.Tolerance < 20) then begin minMatchCount := 1 + (Target.Tolerance shr 2); end; end; if (NumberFound < minMatchCount) then begin // done exit; end; Result := true; end; function CalculateDenseColorInfo(Target : TColorTolerance; X1, Y1, X2, Y2 : Integer) : TDenseColorInfo; var MatchingTPA : TPointArray; var Total : Integer; var Index : Integer; var minMatchCount : Integer; var Found : Boolean; begin Result.Pointcount := 0; Result.SumX := 0; Result.SumY := 0; Result.Matching := false; Result.FoundPointCount := 0; SetColorToleranceSpeed(Target.ToleranceSpeed); Found := FindColorsTolerance(MatchingTPA, Target.Color, X1, Y1, X2, Y2, Target.Tolerance); SetColorToleranceSpeed(1); if not Found then begin // done exit; end; Total := Length(MatchingTPA); Result.FoundPointCount := Total; // set up match count if (Target.MinHitsRequired > 0) then begin minMatchCount := Target.MinHitsRequired; end else begin minMatchCount := 5; if (Target.Tolerance < 20) then begin minMatchCount := 1 + (Target.Tolerance shr 2); end; end; if (Total < minMatchCount) then begin // done exit; end; Result.Matching := true; // check if (Total > 20) then begin // calculate sparse Total := Total div 20; for index := 0 to 19 do begin Inc(Result.Pointcount); Result.SumX := Result.SumX + MatchingTPA[index * Total].x; Result.SumY := Result.SumY + MatchingTPA[index * Total].y; end; end else begin // calculate simple for index := 0 to Total - 1 do begin Inc(Result.Pointcount); Result.SumX := Result.SumX + MatchingTPA[index].x; Result.SumY := Result.SumY + MatchingTPA[index].y; end; end; end; const MAX_MODEL_RESULTS = 10; // most models are at minimum 20x20 but more likely 30x40 or more // so we rasterize in 16x16 increments with 32x32 model spread function FindModel(Model : TPAModel; Environment : TColorToleranceArray) : TPointArray; var X1, Y1, X2, Y2 : Integer; var QuickMatchAll : Boolean; var CurrentRasterInfo : TDenseColorInfoArray; var OverlayCount : Integer; var Index : Integer; var ColorRasters : TDenseColorInfoArray; var SumIndex : Integer; var ResultCount : Integer; var MaxCounter : Integer; var MaxIndex : Integer; var secondaryIndex : Integer; var SCREENPOINTSIndex : Integer; var SCREENPOINTSCount : Integer; var MAXClickBans : Integer; var ClickBan : Boolean; var ExcludeCount : Integer; var EnvironmentCount : Integer; begin // raster info OverlayCount := Length(Model.ColorToleranceDefinition); ExcludeCount := Length(Model.ColorToleranceExcludes); EnvironmentCount := Length(Environment); SetLength(CurrentRasterInfo, OverlayCount); SetLength(ColorRasters, 0); // check if (Length(SCREENPOINTS) <= 0) then CalculateScreenPoints; SCREENPOINTSCount := Length(SCREENPOINTS); MAXClickBans := -1; for Index := 0 to CLICKBAN_MAX_AREAS - 1 do begin if (CLICKBANS[Index].x < 0) then break; MAXClickBans := Index; end; // go through screen for SCREENPOINTSIndex := 0 to SCREENPOINTSCount - 1 do begin // check against clickban ClickBan := false; for Index := 0 to MAXClickBans do begin if CLICKBANS[Index].x <> SCREENPOINTS[SCREENPOINTSIndex].x then continue; if CLICKBANS[Index].y <> SCREENPOINTS[SCREENPOINTSIndex].y then continue; ClickBan := true; break; end; if (ClickBan) then continue; X1 := MSX1 + (SCREENPOINTS[SCREENPOINTSIndex].x shl 4) - 16; X2 := X1 + 32; if (X1 < MSX1) then X1 := MSX1; if (X2 > MSX2) then X2 := MSX2; Y1 := MSY1 + (SCREENPOINTS[SCREENPOINTSIndex].y shl 4) - 16; Y2 := Y1 + 32; if (Y1 < MSX1) then Y1 := MSY1; if (Y2 > MSY2) then Y2 := MSY2; // quick check QuickMatchAll := True; for Index := 0 to OverlayCount - 1 do begin if not TestDenseColorRasterCount(Model.ColorToleranceDefinition[Index], X1, Y1, X2, Y2) then begin QuickMatchAll := false; break; end; end; // check if not QuickMatchAll then continue; // check environment for Index := 0 to EnvironmentCount - 1 do begin if (TestDenseColorRasterCount(Environment[Index], X1, Y1, X2, Y2)) then begin // environment block // SMART_DrawBoxMS(false, IntToBox(X1+11, Y1 + 11, X1+21, Y1 + 21), clNavy) continue; end; end; // check excludes for Index := 0 to ExcludeCount - 1 do begin if (TestDenseColorRasterCount(Model.ColorToleranceExcludes[Index], X1, Y1, X2, Y2)) then begin // model specific block // SMART_DrawBoxMS(false, IntToBox(X1+11, Y1 + 11, X1+21, Y1 + 21), clPurple) continue; end; end; // now get rasters for Index := 0 to OverlayCount - 1 do begin CurrentRasterInfo[Index] := CalculateDenseColorInfo(Model.ColorToleranceDefinition[Index], X1, Y1, X2, Y2); // check if not CurrentRasterInfo[Index].Matching then begin QuickMatchAll := false; break; end; end; if not QuickMatchAll then continue; // calculate new raster SumIndex := Length(ColorRasters); SetLength(ColorRasters, SumIndex + 1); ColorRasters[SumIndex].Matching := true; ColorRasters[SumIndex].Pointcount := 0; ColorRasters[SumIndex].FoundPointCount := 0; ColorRasters[SumIndex].SumX := 0; ColorRasters[SumIndex].SumY := 0; for Index := 0 to OverlayCount - 1 do begin //WriteLn('MATCH: ' + IntToStr(SumIndex) + ', Color layer ' + IntToStr(Index) + ' hitcount ' + IntToStr( // CurrentRasterInfo[Index].FoundPointCount)); ColorRasters[SumIndex].FoundPointCount := ColorRasters[SumIndex].FoundPointCount + CurrentRasterInfo[Index].FoundPointCount; ColorRasters[SumIndex].Pointcount := ColorRasters[SumIndex].Pointcount + CurrentRasterInfo[Index].Pointcount; ColorRasters[SumIndex].SumX := ColorRasters[SumIndex].SumX + CurrentRasterInfo[Index].SumX; ColorRasters[SumIndex].SumY := ColorRasters[SumIndex].SumY + CurrentRasterInfo[Index].SumY; end; end; // now get the results ResultCount := MAX_MODEL_RESULTS; if (ResultCount > Length(ColorRasters)) then begin ResultCount := Length(ColorRasters); end; // build result SetLength(Result, ResultCount); for index := 0 to ResultCount - 1 do begin MaxCounter := -1; MaxIndex := -1; for secondaryIndex := 0 to Length(ColorRasters) - 1 do begin if not ColorRasters[secondaryIndex].Matching then continue; //if ColorRasters[secondaryIndex].Pointcount < MaxCounter then continue; if ColorRasters[secondaryIndex].FoundPointCount < MaxCounter then continue; //MaxCounter := ColorRasters[secondaryIndex].Pointcount; MaxCounter := ColorRasters[secondaryIndex].FoundPointCount; MaxIndex := secondaryIndex; end; // do it //WriteLn('Result ' + IntTOStr(index) + ' is from match ' + IntToStr(MaxIndex)); Result[index].x := ColorRasters[MaxIndex].SumX / ColorRasters[MaxIndex].Pointcount; Result[index].y := ColorRasters[MaxIndex].SumY / ColorRasters[MaxIndex].Pointcount; ColorRasters[MaxIndex].Matching := False; //if (index = 0) then WriteLn('Result#1 ' + IntTOStr(index) + ' is from match ' + IntToStr(MaxIndex) + ' with ' + IntTOStr( //MaxCounter)); end; end; function SkipClick(x, y : Integer) : Boolean; begin // by default we enable click Result := false; // check if in the points section if (Y < 200) and (X < 55) then begin Result := true; exit; end; // check if xp overhead if (Y < 66) and (X > 220) and (X < 300) then begin Result := true; exit; end; // do not click yourself if (X > 235) and (X < 285) AND (Y > 125) AND (Y < 170) then begin Result := true; exit; end; end; procedure CalculateScreenPoints; var RasterX : Integer; var RasterY : Integer; var X1, Y1, X2, Y2 : Integer; var MaxRasterX : Integer; var MaxRasterY : Integer; var SCREENPOINTSCount : Integer; begin // go through screen to figure out which points we care about MaxRasterX := ((MSX2 - MSX1) shr 4); MaxRasterY := ((MSY2 - MSY1) shr 4); SetLength(SCREENPOINTS, (MaxRasterX + 1) * (MaxRasterY * 1)); SCREENPOINTSCount := 0; for RasterX := 0 to MaxRasterX do begin X1 := MSX1 + (RasterX shl 4) - 16; X2 := X1 + 32; if (X1 < MSX1) then X1 := MSX1; if (X2 > MSX2) then X2 := MSX2; for RasterY := 0 to MaxRasterY do begin Y1 := MSY1 + (RasterY shl 4) - 16; Y2 := Y1 + 32; if (Y1 < MSX1) then Y1 := MSY1; if (Y2 > MSY2) then Y2 := MSY2; // finally - we can check against map rosters if not CheckIfWeCare(X1, Y1, X2, Y2) then begin // we do not care //SMART_DrawBoxEx(false, IntToBox(X1,Y1,X2,Y2), clNavy); continue; end; // we care SCREENPOINTS[SCREENPOINTSCount].X := RasterX; SCREENPOINTS[SCREENPOINTSCount].Y := RasterY; Inc(SCREENPOINTSCount); end; end; // done SetLength(SCREENPOINTS, SCREENPOINTSCount); end; // yay, kick some az var LastRightClick : Integer; function FindTarget(HoundsOnly : Boolean; FloorLevelFilter : Integer; SkillLevelFilter : Integer; IsMember : Boolean; XPFilter : Integer; ModelFilter : TModelTarget; UpTextCheck : Boolean; out Location : TPoint; out SelectedOption : Boolean; out ModelsTestedCount : Integer) : TPAModel; var MatchingModels : TPAModelArray; var index : Integer; var resultIndex : Integer; var resultValid : Boolean; var ModelMatches : TPointArray; var Box: TBox; var secondaryFollowed : Boolean; var ModelName : String; var ModelUptext : String; begin ModelsTestedCount := 0; SelectedOption := False; SetColorToleranceSpeed(1); // 2 MatchingModels := GetSearchOrderTPAModelList(HoundsOnly, FloorLevelFilter, SkillLevelFilter, IsMember); Result.XP := -1; Location.x := -1; Location.y := -1; secondaryFollowed := not ONSCREEN_TRACK_SECONDARY; resultValid := false; for index := 0 to Length(MatchingModels) - 1 do begin // see if done - stop on xp or model filter if ((MatchingModels[index].XP <= XPFilter) or (MatchingModels[index].ModelType = ModelFilter)) then begin if (secondaryFollowed) then begin break; end; end; // look ModelName := MatchingModels[Index].Descriptor; ModelUptext := MakeUptext(ModelName, MatchingModels[Index].Hound); // however Siphon Blood pool matches too many in Siphon Blood esswraith ModelMatches := FindModel(MatchingModels[index], EnvironmentalExcludes[FloorLevelFilter]); Inc(ModelsTestedCount); // check if we have matches //WriteLn('testing ' + MatchingModels[Index].Descriptor + ' got ' + IntToStr(Length(ModelMatches)) + ' matches'); if (Length(ModelMatches) <= 0) then continue; // go through results for resultIndex := 0 to Length(ModelMatches) - 1 do begin if SkipClick(ModelMatches[resultIndex].x, ModelMatches[resultIndex].y) then begin if (GetSystemTime - LastRightClick) < RandomRange(15000,20000) then continue; // check if UpTextCheck then begin MMouse(ModelMatches[resultIndex].x, ModelMatches[resultIndex].y, 5, 5); sleep(10+random(60)); if (WaitUpTextFuzzy('Walk here', MATCH_LOOSE, 80)) then begin // nope RecordClickban(ModelMatches[resultIndex].x, ModelMatches[resultIndex].y); continue; end; if (WaitUpTextFuzzy('Climb ladder', MATCH_LOOSE, 80)) then begin // nope RecordClickban(ModelMatches[resultIndex].x, ModelMatches[resultIndex].y); continue; end; if (WaitUpTextFuzzy('Use platform', MATCH_LOOSE, 80)) then begin // nope RecordClickban(ModelMatches[resultIndex].x, ModelMatches[resultIndex].y); continue; end; LastRightClick := GetSystemTime; ClickMouse2(mouse_right); if not WaitOptionFuzzy(ModelUptext, MATCH_GOOD, RandomRange(400,500)) then begin sleep(RandomRange(100,500)); RecordClickban(ModelMatches[resultIndex].x, ModelMatches[resultIndex].y); continue; end; SelectedOption := true; // draw on screen if ONSCREEN_FOLLOW_MODELS then begin // clear previous Box.X1 := ModelMatches[resultIndex].x - 5; Box.Y1 := ModelMatches[resultIndex].y - 5; Box.X2 := ModelMatches[resultIndex].x + 5; Box.Y2 := ModelMatches[resultIndex].y + 5; if (MatchingModels[Index].Hound) then begin //SMART_DrawBoxMS(False, Box, clLime); end else begin //SMART_DrawBoxMS(False, Box, clYellow); end; end; Result := MakeTPAModelCopy(MatchingModels[index]); Location.x := ModelMatches[resultIndex].x; Location.y := ModelMatches[resultIndex].y; //Writeln('found ' + MatchingModels[Index].Descriptor); resultValid := true; break; end; end; if not resultValid and (MatchingModels[index].XP > XPFilter) then begin if UpTextCheck then begin MMouse(ModelMatches[resultIndex].x, ModelMatches[resultIndex].y, 0, 0); // writeln('uptext is [' + GetUpText + '] for [' + ModelName + ']'); if WaitUpTextFuzzy(ModelUptext, MATCH_GOOD, 80) then begin // found uptext end else begin if (GetSystemTime - LastRightClick) < RandomRange(15000,20000) then begin RecordClickban(ModelMatches[resultIndex].x, ModelMatches[resultIndex].y); continue; end; MMouse(ModelMatches[resultIndex].x, ModelMatches[resultIndex].y, 5, 5); sleep(10+random(60)); // writeln('uptext is [' + GetUpText + '] for [' + ModelName + ']'); if (WaitUpTextFuzzy('Walk here', MATCH_LOOSE, 80)) then begin // nope RecordClickban(ModelMatches[resultIndex].x, ModelMatches[resultIndex].y); continue; end; if (WaitUpTextFuzzy('Climb ladder', MATCH_LOOSE, 80)) then begin // nope RecordClickban(ModelMatches[resultIndex].x, ModelMatches[resultIndex].y); continue; end; if (WaitUpTextFuzzy('Use platform', MATCH_LOOSE, 80)) then begin // nope RecordClickban(ModelMatches[resultIndex].x, ModelMatches[resultIndex].y); continue; end; LastRightClick := GetSystemTime; ClickMouse2(mouse_right); if not WaitOptionFuzzy(ModelUptext, MATCH_GOOD, RandomRange(400,500)) then begin sleep(RandomRange(100,500)); // we cannot record clickban, if for example skulls and blood // pool match, recording clickban would prevent skulls from // working, but we should test for the options // RecordClickban(ModelMatches[resultIndex].x, ModelMatches[resultIndex].y); continue; end; SelectedOption := true; end; // draw on screen if ONSCREEN_FOLLOW_MODELS then begin // clear previous Box.X1 := ModelMatches[resultIndex].x - 5; Box.Y1 := ModelMatches[resultIndex].y - 5; Box.X2 := ModelMatches[resultIndex].x + 5; Box.Y2 := ModelMatches[resultIndex].y + 5; if (MatchingModels[Index].Hound) then begin //SMART_DrawBoxMS(False, Box, clLime); end else begin //SMART_DrawBoxMS(False, Box, clYellow); end; end; Result := MakeTPAModelCopy(MatchingModels[index]); Location.x := ModelMatches[resultIndex].x; Location.y := ModelMatches[resultIndex].y; //Writeln('found ' + MatchingModels[Index].Descriptor); resultValid := true; break; end; // draw on screen if ONSCREEN_FOLLOW_MODELS then begin // clear previous Box.X1 := ModelMatches[resultIndex].x - 5; Box.Y1 := ModelMatches[resultIndex].y - 5; Box.X2 := ModelMatches[resultIndex].x + 5; Box.Y2 := ModelMatches[resultIndex].y + 5; if (MatchingModels[Index].Hound) then begin
cont again lol...
Code://SMART_DrawBoxMS(False, Box, clLime); end else begin //SMART_DrawBoxMS(False, Box, clYellow); end; end; Result := MakeTPAModelCopy(MatchingModels[index]); Location.x := ModelMatches[resultIndex].x; Location.y := ModelMatches[resultIndex].y; //Writeln('found ' + MatchingModels[Index].Descriptor); resultValid := true; break; end else begin if ((MatchingModels[index].XP < XPFilter) or (XPFilter <= 0)) then begin if not secondaryFollowed then begin secondaryFollowed := true; // clear previous Box.X1 := ModelMatches[resultIndex].x - 5; Box.Y1 := ModelMatches[resultIndex].y - 5; Box.X2 := ModelMatches[resultIndex].x + 5; Box.Y2 := ModelMatches[resultIndex].y + 5; if (MatchingModels[Index].Hound) then begin //SMART_DrawBoxMS(False, Box, clBlue); //writeln('Marking ' + MatchingModels[Index].Descriptor + ' at ' + IntToStr(ModelMatches[resultIndex].x) + ', ' + IntToStr(ModelMatches[resultIndex].y)); end else begin //SMART_DrawBoxMS(False, Box, clAqua); //writeln('Marking ' + MatchingModels[Index].Descriptor); end; end; break; end; end; end; if resultValid and secondaryFollowed then break; end; SetColorToleranceSpeed(1); end; function CheckIfWeCare(X1, Y1, X2, Y2 : Integer) : Boolean; var Index : Integer; var MAXX : Integer; var indexX, indexY : Integer; var mapType : Integer; begin MAXX := Length(MAPPOINTS); // until we find overlap assume false Result := False; // check overhead if (X1 > MSCX - 35) and (X2 < MSCX + 35) and (Y2 < 70) then Exit; // check left side runespan info if (X2 < 75) and (Y1 < 145) then Exit; // check if counters if (X2 + 40 > MSX2) and (Y1 < 80) then Exit; // now we should check data for Index := 0 to MAXX - 1 do begin indexX := MAPPOINTS[Index].x; indexY := MAPPOINTS[Index].y; mapType := MAP[indexX][indexY]; if (mapType = MAP_TYPE_OUTSIDE) or (mapType = MAP_TYPE_UNTESTED) then continue; // ok we are looking at square that is either inside or border, now do some testing if (X1 >= MAP3D[indexX][indexY].X2) then continue; if (Y1 >= MAP3D[indexX][indexY].Y2) then continue; if (X2 <= MAP3D[indexX][indexY].X1) then continue; if (Y2 <= MAP3D[indexX][indexY].Y1) then continue; // we may have overlap but the first hit is fine Result := True; Exit; end; end; var StartTime : Integer; PreemptCounter : Integer; CurrentTPAModel : TPAModel; // runes DTM_RUNE : array [TYPE_RUNE_MIN .. TYPE_RUNE_MAX] of Integer; // rune counters COUNTER_RUNE : array [TYPE_RUNE_MIN .. TYPE_RUNE_MAX] of Integer; // points COUNTER_POINTS_INITIAL : Integer; COUNTER_POINTS : Integer; DTM_FIRST_FLOOR : Integer; DTM_SECOND_FLOOR : Integer; DTM_THIRD_FLOOR : Integer; DTM_RUNESPHERE : Integer; DTM_YELLOW_WIZARD : Integer; // globals var SkillLevel : Integer; function IsRuneSphere : Boolean; var x, y : Integer; begin // nope not until we actually care Result := FindDTM(DTM_RUNESPHERE, x, y, 4, 130, 64, 190); end; var LastFloor : Integer; var LastCheck : Integer; // returns 1, 2, 3 or 0 if not in runespan function GetFloorLevel : Integer; var X, Y : Integer; begin if (LastFloor > 0) then begin // check reset if (GetSystemTime - LastCheck) < 5000 then begin // eh Result := LastFloor; exit; end; end; LastCheck := GetSystemTime; Result := 0; LastFloor := 0; if FindDTM(DTM_THIRD_FLOOR, x, y, 4, 100, 64, 150) then begin Result := 3; LastFloor := 3; Exit; end; if FindDTM(DTM_SECOND_FLOOR, x, y, 4, 100, 64, 150) then begin Result := 2; LastFloor := 2; Exit; end; if FindDTM(DTM_FIRST_FLOOR, x, y, 4, 100, 64, 150) then begin Result := 1; LastFloor := 1; Exit; end; end; function FloorToString : String; begin case (GetFloorLevel) of 3: Result := 'Highest level RuneSpan'; 2: Result := 'Middle level RuneSpan'; 1: Result := 'Lowest level RuneSpan'; 0: Result := 'We are not in RuneSpan'; end; end; function IsInRuneSpan : Boolean; var i : Integer; var SkillGuideDTM : Integer; var x, y : Integer; begin // see what floor we are Result := (GetFloorLevel > 0); if (Result) then Exit; WriteLn('FLOOR NOT KNOWN'); // check skill guide SkillGuideDTM := DTMFromString('mwQAAAHic42RgYHjKxMDwAogfA/EjKBsk9gCIXwPxMyAWA6oTAWJhIJYCYkkglmaAiIOwABD/2aDLcHeKOsODGdoMfZFSYL4SCwuDoawsgxATE4OhigrYDEKYkQgMBwDkPRLC'); for i := 1 to 3 do begin if (FindDTM(SkillGuideDTM, x, y, 710, 1, 760, 50)) then begin WriteLn('FOUND DTM'); // close Mouse(x, y, 3, 3, true); WriteLn('FOUND DTM - clicked'); Sleep(RandomRange(1000,3000)); WriteLn('FOUND DTM - checking'); Result := GetFloorLevel > 0; if (Result) then Exit; WriteLn('FOUND DTM - FAILED'); end; sleep (RandomRange(300,500)); end; WriteLn('AFTER FOUND DTM'); // move out MMouse(300, 150, 80, 50); // double check for i := 0 to 50 do begin sleep (100); LastFloor := -1; Result := (GetFloorLevel > 0); if Result then exit; end; end; function EnterPortal : Boolean; var PortalDTM : Integer; var X, Y : Integer; var aFound : Extended; var retry : Integer; begin WriteLn('setting up to enter portal'); Result := False; MakeCompass('W'); SetAngle(SRL_ANGLE_LOW); PortalDTM := DTMFromString('mAAEAAHic42FgYMgB4mYgroDiciD2h+IAKM4E4hggngnEGUCcAsRRUDlXIHYGYg8gDgbiSCAOh8o7AfH0qg0MPf2TGfomTmFIycxkaO/qZejs6WdISk9nqGtsYZgweRpDeVUtnAaZKUICZiQRIwMAZkIctw=='); retry := 30; repeat if FindDTMRotated(PortalDTM, x, y, 0, 20, 200, 200, -Pi/4, Pi/4, Pi/16, aFound) then break; Writeln('Not yet found'); Dec(retry); if (retry <= 0) then begin FreeDTM(PortalDTM); // umm sorry Writeln('Sorry'); Exit; end; sleep (50); until retry < 0; Writeln('Found portal: ' + IntToStr(x) + ', ' + IntToStr(y)); FreeDTM(PortalDTM); // get in on highest level you can sleep(1000+random(100)); MMouse(X, Y, 3, 3); sleep(50+random(100)); ClickMouse2(False); sleep(2000+random(1000)); // wait to walk if not WaitOptionMulti(['Ente', 'nter', 'nte'], RandomRange(400,500)) then begin // sorry Writeln('option to enter not found'); Exit; end; Writeln('option to enter portal found'); Wait(4000+random(700)); if (FindNPCChatText('High', Nothing)) then begin Writeln('High level entry found'); TypeSend('3'); end else begin Writeln('High level entry not found, perhaps insufficient skill level'); TypeSend('2'); end; // well that's about it Wait(9000 + Random(3000)); WriteLn('going through welcome dialog'); clickContinue(true, true); Wait(1000 + Random(1000)); WriteLn('dialog finished'); LastFloor := -1; WriteLn('Current Location: ' + FloorToString); Result := IsInRuneSpan; end; function GetBackToRuneSpan : Boolean; var CanUseFairy: Boolean; var HasEdgevilleTeleport : Boolean; var HasDraynorTeleport : Boolean; var HasHoodEquipped : Boolean; var HasHoodInventory : Boolean; var EdgeVilleDTM : Integer; var DraynorDTM : Integer; var HoodDTM : Integer; var edgeX, edgeY, drayX, drayY: Integer; var hoodX, hoodY: Integer; var RuneClear : Integer; begin // umm - no runes for RuneClear := TYPE_RUNE_MIN to TYPE_RUNE_MAX do begin RUNE_LastKnownPosition[RuneClear] := -1; COUNTER_RUNE[RuneClear] := 0; end; // not yet back Result := false; // some set up CanUseFairy := CAN_USE_FAIRY_RINGS; HasEdgevilleTeleport := false; HasDraynorTeleport := false; // check hood HoodDTM := DTMFromString('mwQAAAHic42RgYHBhYmBwAmJPIHYAYhsgtmWCiHsBsSsQPwOqewTETxkQ7DdA/BGI3wHxbSA2k1NhcLVVZ9BWlWBQlJRmkBOXYJASEWXwd9VhkOITZPDQMGAQAaojhBmJwHAAAMO+D1Y='); if (GetCurrentTab <> tab_Equip) then GameTab(tab_Equip); HasHoodEquipped := FindDTM(HoodDTM, hoodX, hoodY, 600, 190, 680, 265); Writeln('GOT ' + IntToStr(hoodX) + ' and ' + IntToSTr(Hoody)); HasHoodInventory := false; if not HasHoodEquipped then begin WriteLn('Hood not equipped, checking inventory'); if (GetCurrentTab <> Tab_Inv) then GameTab(Tab_Inv); HasHoodInventory := FindDTM(HoodDTM, hoodX, hoodY, MIX1, MIY1, MIX2, MIY2); Writeln('GOT inventory ' + IntToStr(hoodX) + ' and ' + IntToSTr(Hoody)); end else begin WriteLn('Hood found equipped, can only have one, skipping inventory check'); end; FreeDTM(HoodDTM); // hood makes simple if ((HasHoodEquipped) or (HasHoodInventory)) then begin // teleport MMouse(hoodX, hoodY, 5, 5); sleep(50+random(100)); ClickMouse2(False); if WaitOptionMulti(['Tele', 'lepo', 'port'],RandomRange(400,500)) then begin WriteLn('Teleporting with hood...'); // wait Wait(8000 + Random(3000)); // done WriteLn('Ok we should be in teleported, now get inside'); MakeCompass('W'); SetAngle(SRL_ANGLE_LOW); // Enter Portal Result := EnterPortal(); // done - either we are there or not exit; end; end; // spell setup if (not SpellSetup) then SetupSpells(); ClickSpellMode(SpellMode_All); if Cast('lumbridge home teleport', False) then begin // wait wait(500 + Random(300)); // edgeville EdgeVilleDTM := DTMFromString('mggAAAHicY2NgYFBhZGDQAGJtINYEYjkgVgTi2UC5uVA8CYqXAfHijTsZgsWlGHpmb2fg8vZgcCzKB9MiQDlsmBEHhgAAoZoL1A=='); HasEdgevilleTeleport := FindDTM(EdgeVilleDTM, edgeX, edgeY, 240, 90, 360, 210); FreeDTM(EdgeVilleDTM); // draynor DraynorDTM := DTMFromString('mggAAAHicY2NgYDBhZGDQA2IrRgjbGEpfAspdhOIzQHwCiO8BcY+KCsMZbWOGYnVVMC0iLsvAyMjEIAKUw4YZcWAIAACSnArb'); HasDraynorTeleport := FindDTM(DraynorDTM, drayX, drayY, 280, 180, 340, 240); FreeDTM(DraynorDTM); end else begin Writeln('Could not cast home teleport'); exit; end; // check if we can tele using fairy if not HasEdgevilleTeleport then begin // nope we walk CanUseFairy := False; end; // for now FORCE walker CanUseFairy := False; // check if we can use fairy if (CanUseFairy) then begin // use it Mouse(edgeX, edgeY, 5, 5, true); // wait Wait(17000 + Random(6000)); // done WriteLn('Ok we should be in Edgeville, but the rest is not yet done'); exit; end else begin if not HasDraynorTeleport then begin // sorry you should go to draynor yourself and activate the lodestone Exit; end; // use it Mouse(drayX, drayY, 5, 5, true); // wait Wait(17000 + Random(6000)); // done WriteLn('Ok we should be in Draynor, but the rest is not yet done'); exit; end; // if we have succeeded, we ought to reset certain counters as, for example, // we will have lost all runes, and we couldn't read point balance. // why? because we may have been ported out in middle of long run, we better // then handle it properly end; function NeedMoreEssence : Boolean; begin // if we fall below 100 we need more Result := (COUNTER_RUNE[TYPE_RUNE_ESSENCE] < 100); end; function DesperatelyNeedsEssence : Boolean; begin // if we fall below 25, we can replenish from floating essence Result := (COUNTER_RUNE[TYPE_RUNE_ESSENCE] < 25); end; function GetInventoryCountFromDTM(DTM_IN : Integer; RUNE_TYPE : Integer) : Integer; var x,y : Integer; var startx, starty, rowsize, colsize, colnumber, rownumber: Integer; var indexx, indexy, index : Integer; var LastKnownPosition : Integer; begin // init Result := 0; // look for runes if not FindDTM(DTM_IN, x, y, MIX1, MIY1, MIX2, MIY2) then begin // see if we have last known position LastKnownPosition := RUNE_LastKnownPosition[RUNE_TYPE]; if (LastKnownPosition <= 0) then exit; // try to get last known position Result := GetAmountBox(InvBox(LastKnownPosition)); exit; end; AreaInfo('inv', startx, starty, rowsize, colsize, colnumber, rownumber); indexx := (x - startx) div colsize; indexy := (y - starty) div rowsize; if (indexx >= colnumber) then Exit; if (indexy >= rownumber) then exit; // get new X/Y LastKnownPosition := 1 + indexx + (colnumber * indexy); (* x := startx + (rowSize * indexx); y := starty + (colsize * indexy); Result := GetAmountBox(IntToBox(x,y, x + rowSize, y + ((colSize * 3) shr 2))); *) Result := GetAmountBox(InvBox(LastKnownPosition)); if (Result > 0) then begin for index := TYPE_RUNE_MIN to TYPE_RUNE_MAX do begin if index = RUNE_TYPE then continue; if (RUNE_LastKnownPosition[index] = LastKnownPosition) then begin // nope RUNE_LastKnownPosition[index] := -1; end; end; RUNE_LastKnownPosition[RUNE_TYPE] := LastKnownPosition; end end; procedure RandomWalkIsland; var maxX : Integer; var maxY : Integer; var excludeX : Integer; var excludeY : Integer; var indexX : Integer; var indexY : Integer; var TotalGreenCount : Integer; var Target : Integer; begin WriteLn('Walking a little'); UpdateMap; DrawMap; maxX := Length(MAP); maxY := Length(MAP[0]); excludeX := 1 + (maxX shr 1); excludeY := 1 + (maxY shr 1); // count TotalGreenCount := 0; for indexX := 0 to maxX - 1 do begin for indexY := 0 to maxY - 1 do begin if (indexX = excludeX) and (indexY = excludeY) then begin continue; end; if (MAP[indexX][indexY] = MAP_TYPE_ISLAND) then begin Inc(TotalGreenCount); end; end; end; // check - cannot walk if nothing found if (TotalGreenCount < 1) then Exit; if (TotalGreenCount = 1) then begin Target := 0; end else begin Target := Random(TotalGreenCount - 1); end; WriteLn(' island square count: ' + IntToStr(TotalGreenCount) + ', selected square ' + IntToStr(Target)); TotalGreenCount := 0; for indexX := 0 to maxX - 1 do begin for indexY := 0 to maxY - 1 do begin if (indexX = excludeX) and (indexY = excludeY) then begin continue; end; if (MAP[indexX][indexY] = MAP_TYPE_ISLAND) then begin // check if (TotalGreenCount = Target) then begin // found target Mouse(MMX1 + 4 + (indexX shl 3), MMY1 + 4 + (indexY shl 3), 4, 4, true); sleep (RandomRange(800,1200)); while (IsMoving) do; UpdateMap(); DrawMap(); exit; end; Inc(TotalGreenCount); end; end; end; end; function DoIncremental(RUNE_TYPE : Integer; DTM_IN : Integer; Initial : Boolean; Current : Integer; StatsVar : String) : Integer; var Difference : Integer; begin Result := GetInventoryCountFromDTM(DTM_IN, RUNE_TYPE); if (Initial) then exit; // check difference Difference := Result - Current; if (Difference > 0) then begin stats_IncVariable(StatsVar, Difference); end; end; function GetSmartValue(NewValue, OldValue : Integer) : Integer; begin // check - shouldn't drop by more than few if (NewValue + 5 > OldValue) then begin Result := NewValue; exit; end; Result := OldValue - 5; if Result < 0 then Result := 0; end; procedure RefreshRuneCounters(Initial : Boolean; Filter : Integer); var Points : Integer; var PointString : String; var Index : Integer; begin // check inventory if (GetCurrentTab <> Tab_Inv) then GameTab(Tab_Inv); // rune counters if (Filter > TYPE_RUNE_MAX) or (Filter < TYPE_RUNE_MIN) then begin // all counters PointString := GetTextAtExWrap(50, 78, 95, 92, 0, 1, 1, 16777215, 0, StatChars); Points := StrToIntDef(GetNumbers(PointString), 0) if (Initial) then begin COUNTER_POINTS := Points; COUNTER_POINTS_INITIAL := Points; end else begin if (Points > COUNTER_POINTS) then begin //stats_IncVariable(STATS_POINTS, Points - CURRENT_POINTS); COUNTER_POINTS := Points; end; end; for Index := TYPE_RUNE_MIN to TYPE_RUNE_MAX do begin COUNTER_RUNE[Index] := GetSmartValue(DoIncremental(Index, DTM_RUNE[Index], Initial, COUNTER_RUNE[Index], STATS_RUNE[Index]), COUNTER_RUNE[Index]); end; end else begin // filter counter COUNTER_RUNE[Filter] := GetSmartValue(DoIncremental(Filter, DTM_RUNE[Filter], Initial, COUNTER_RUNE[Filter], STATS_RUNE[Filter]), COUNTER_RUNE[Filter]); end; end; function GetSomeEssence : Boolean; var tryThisDTM : Integer; var tryThisDTM2 : Integer; var tryThisDTM3 : Integer; var x, y : Integer; var E: Extended; var counter : Integer; var Found : Boolean; begin Writeln('getting essence'); if (GetCurrentTab <> Tab_Inv) then GameTab(Tab_Inv); tryThisDTM := DTMFromString('mlwAAAHicY2dgYLjIyMBwBYjPAfFJID4NxHeB+CEQ7wDKbwfiPVC8FYgPA/FBIE5LTWKIi4liCA0JZDA3M2WIiYpgCPD3ZbC3s2UQAcrjwox4MBQAAFmAEhg='); tryThisDTM2 := DTMFromString('mggAAAHicY2NgYLgMxOeB+CwQ30DiLwbiFUC8BIiXAvFyIF4IxEmJcQwO9rYMPt4eDH6+3gxenm4MkRGhDCJAOWyYEQeGAAAm0g7L'); tryThisDTM3 := DTMFromString('mggAAAHicY2NgYPgOxF+A+CMQv4XSH4B4ExCvA+KtQLwFiDcA8Vog9vJ0Y/Dx9mCwtrJgMNDXY3B3c2GwtbFiEAHKYcOMODAEAABVLg7L'); for counter := 1 to 30 do begin Found := FindDTMRotated(tryThisDTM, X, Y, MSX1, MSY1, MSX2, MSY2, - Pi/4, Pi/4, Pi/16, E); if not Found then Found := FindDTMRotated(tryThisDTM2, X, Y, MSX1, MSY1, MSX2, MSY2, - Pi/4, Pi/4, Pi/16, E); if not Found then Found := FindDTMRotated(tryThisDTM3, X, Y, MSX1, MSY1, MSX2, MSY2, - Pi/4, Pi/4, Pi/16, E); if Found then begin Mouse(x, y, 2, 2, true); if (DidRedClick) then begin while IsMoving do; end; end; RefreshRuneCounters(false, TYPE_RUNE_ESSENCE); if not DesperatelyNeedsEssence then break; // random walk island WriteLn('Walking for essence'); RandomWalkIsland(); // check if not IsInRuneSpan then break; end; FreeDTM(tryThisDTM); FreeDTM(tryThisDTM2); FreeDTM(tryThisDTM3); // check if we got essence - for now assume success Result := not DesperatelyNeedsEssence; end; function InitialSetUp : Boolean; var X, Y : Integer; var NagScreenDTM : Integer; begin LogSmartLine('Checking for Mad Day nag screen...'); NagScreenDTM := DTMFromString('mlwAAAHicY2dgYPjMyMDwAYi/QjGI/Q6IfwGxCFBeEIrFoVgEir9ut2H4czKV4f1GO4YUGxGG7iBZhiBFRYa09HS4GmyYEQ+GAgDZGxE5'); if FindDTM(NagScreenDTM, X, Y, 480, MSY1, MSX2, 30) then begin // found nag screen, we are user so we kinda wait Wait(500 + Random(500)); Mouse(x, y, 2, 2, true); end; FreeDTM(NagScreenDTM); // ok wait for nag screen to go away Wait(500 + Random(500)); AppendSmartLine('DONE', True); LogSmartLine('Checking for randoms...'); // now do randoms FindNormalRandoms; // ok wait just in case the SRL closed some other screen Wait(500 + Random(500)); AppendSmartLine('DONE', True) LogSmartLine('Our location: ' + FloorToString); Result := true; // check if we are in runespan if not IsInRuneSpan then begin LogSmartLine('Getting back to RuneSpan'); // get back to runespan Result := GetBackToRuneSpan(); // see if we failed if not Result then begin LogSmartLine('We are not in RuneSpan and we kinda failed to get back.'); Exit; end; end; LogSmartLine('Checking inventory...'); // woo hoo RefreshRuneCounters(true, TYPE_RUNE_NONE); // just because it is easier to find essence for example SetAngle(SRL_ANGLE_HIGH); AppendSmartLine('DONE', True); // get more essences if needed if DesperatelyNeedsEssence then begin LogSmartLine('Obtaining essence'); Result := GetSomeEssence(); end; end; (* Wizard without being told - the startup yellow wizard: right click - Talk to Wizard continue This is tricky, but I am getting the hang of it Continue You need to wait for a wizard to call continue *) var XPTimeout : Integer; var GuaranteedClick : Boolean; var LastXPTotal : integer; var LastOKTime : Integer; procedure WriteStats; var XPTotal : Integer; var XPPerHour : Integer; var XPDiff : Integer; var PointsTotal : Integer; var PointsPerHour : Integer; var SecondsElapsed : Integer; var SmartLines2: TStringArray; var RunesphereEvent: Boolean; var XPT : String; var XPTf : Integer; begin // get total xp tick XPTotal := GetXPBarTotal - Players[CurrentPlayer].Integers[0]; PointsTotal := COUNTER_POINTS - COUNTER_POINTS_INITIAL; if (XPTotal > 0) then begin XPDiff := XPTotal - LastXPTotal; if (XPDiff) > 0 then begin stats_IncVariable(STATS_EXP_TOTAL, XPDiff); stats_IncVariable(STATS_EXP_RUNECRAFTING, XPDiff); WriteLn('Incrementing variables by ' + IntToStr(XPDiff)); if (XPTotal > 0) then begin LastXPTotal := XPTotal; WriteLn('XP Total Diff = ' + IntToStr(XPDiff)); end; end; end; // plus one - just to be sure we don't divide by zero SecondsElapsed := (1 + ((Getsystemtime-StartTime)/1000)); // mind order of execution, these are integers XPPerHour := (3600 * XPTotal) / SecondsElapsed; PointsPerHour := (3600 * PointsTotal) / SecondsElapsed; RunesphereEvent := IsRuneSphere; if (XPTimeout > 999) then begin XPT := IntToStr(XPTimeout div 1000) + '.'; end else begin XPT := '0.'; end; XPTf := XPTimeout mod 1000; XPT := XPT + IntToStr(XPTf div 100); XPTf := XPTf mod 100; XPT := XPT + IntToStr(XPTf div 10); XPT := XPT + IntToStr(XPTf mod 10); if not KEEP_DEBUG then ClearDebug; WriteLn('============Rough Stats etc...============'); WriteLn('Preemptible RuneSpan v. ' + VERSION); WriteLn('Time Running: ' + TimeRunning); WriteLn('XP Earned: ' + IntToStr(XPTotal) + ', per hour: ' + IntToStr(XPPerHour)); WriteLn('Points Earned: ' + IntToStr(PointsTotal) + ', per hour: ' + IntToStr(PointsPerHour)); WriteLn('Preempted Counter: ' + IntToStr(PreemptCounter)); if (CurrentTPAModel.XP > 0) then begin WriteLn('Current Target: ' + CurrentTPAModel.Descriptor + ', ' + IntToStr(CurrentTPAModel.XP) + 'XP, level ' + IntToStr(CurrentTPAModel.MinimumLevel) + ', XPTIMEOUT ' + XPT + 's'); end; WriteLn('Current Runecrafting Level: ' + IntToStr(SkillLevel)); WriteLn('Essences Available: ' + IntToStr(COUNTER_RUNE[TYPE_RUNE_ESSENCE])); WriteLn('Current Floor: ' + FloorToString); if (RunesphereEvent) then WriteLn('RUNESPHERE is active!!!'); WriteLn('=========================================='); if (ONSCREEN_STATS) then begin SetArrayLength(SmartLines2, 9); SmartLines2[0] := '= Preemptible RuneSpan version ' + VERSION + ' ='; SmartLines2[1] := 'Time Running: ' + TimeRunning; SmartLines2[2] := 'XP Earned: ' + IntToStr(XPTotal) + ', Per hour: ' + IntToStr(XPPerHour); SmartLines2[3] := 'Points Earned: ' + IntToStr(PointsTotal) + ', Per hour: ' + IntToStr(PointsPerHour); SmartLines2[4] := 'Preempted Counter: ' + IntToStr(PreemptCounter); if (CurrentTPAModel.XP > 0) then begin SmartLines2[5] := 'Current Target: ' + CurrentTPAModel.Descriptor + ', ' + IntToStr(CurrentTPAModel.XP) + 'XP, level ' + IntToStr(CurrentTPAModel.MinimumLevel) + ', XPTIMEOUT ' + XPT + 's'; end else begin SmartLines2[5] := 'no target'; end; SmartLines2[6] := 'Current Runecrafting Level: ' + IntToStr(SkillLevel); SmartLines2[7] := 'Essences Available: ' + IntToStr(COUNTER_RUNE[TYPE_RUNE_ESSENCE]); SmartLines2[8] := '======'; if (RunesphereEvent) then begin SmartLines2[8] := '== RUNESPHERE IS ACTIVE =='; end; PrintOnSmart(SmartLines2,Point(15,225),clYellow); end; // commit Stats_Commit; end; const XPTIMEOUT_NODEBASE = 9000; const XPTIMEOUT_HOUNDBASE = 11000; // one - they're slower, two - we can detect their demise procedure CalculateXPTimeout; var DecrementAmount : Integer; begin XPTimeout := XPTIMEOUT_NODEBASE; if (CurrentTPAModel.Hound) then XPTimeout := XPTIMEOUT_HOUNDBASE; DecrementAmount := 2000; if (USER_IS_ADD) then DecrementAmount := 5000; if (SkillLevel > CurrentTPAModel.MinimumLevel) then begin if (SkillLevel > 2 * CurrentTPAModel.MinimumLevel) then begin XPTimeout := XPTimeout - DecrementAmount; end else begin XPTimeout := XPTimeout - ((DecrementAmount * (SkillLevel - CurrentTPAModel.MinimumLevel)) / CurrentTPAModel.MinimumLevel); end; end; end; // only for hounds function DO_SIPHON : Boolean; var EntryXP : Integer; var xpTick : Integer; var PrevRuneEssence : Integer; var NewModel : TPAModel; var TPLocation : TPoint; var SelectedOption : Boolean; var MapRefreshed : Boolean; var ModelsTestCount : Integer; var ModelsTestTimer : Integer; var ModelsTimerString : String; var EntryTime : Integer; var FloorLevel : Integer; var ModelGuaranteed : Boolean; var ModelTimer : Integer; var ModelXP : Integer; var CurrentXP : Integer; begin WriteLn('in siphon'); CurrentXP := GetXPBarTotal; ModelGuaranteed := GuaranteedClick; ModelTimer := GetSystemTime; ModelXP := CurrentXP; MapRefreshed := False; Result := False; // show stats CalculateXPTimeout; //SMART_ClearCanvas(); WriteStats; // initial set up RefreshRuneCounters(False, TYPE_RUNE_ESSENCE); PrevRuneEssence := COUNTER_RUNE[TYPE_RUNE_ESSENCE]; EntryXP := CurrentXP; while (IsMoving) do; sleep (RandomRange(1000,2000)); // just to get animation started LastOKTime := GetSystemTime; EntryTime := GetSystemTime; while ((LastOKTime + XPTimeout) > GetSystemTime) do begin // prevent timeout if (EntryTime + 120000 < GetSystemTime) then begin WriteLn('Checking stuff to prevent timeout'); HoverSkill(SKILL_RUNECRAFTING, False); sleep(RandomRange(200, 1500)); EntryTime := GetSystemTime; WriteLn('Prev essence count: ' + IntToStr(PrevRuneEssence)); end; // get xp tick CurrentXP := GetXPBarTotal; xpTick := CurrentXP - EntryXP; EntryXP := CurrentXP; // reset ok time if ((xpTick) > 0) then begin ModelXP := ModelXP + xpTick; GuaranteedClick := true; // Writeln ('Incremental xp: ' + IntToStr(xpTick)); LastOKTime := GetSystemTime; if not MapRefreshed then begin if (Random(5)) = 1 then CompassMovement(-50, 60, false); MapRefreshed := True; UpdateMap(); DrawMap(); end; Result := True; end; // check if not GuaranteedClick then begin WriteLn('not guaranteed'); // only 1/2 of timeout if (LastOKTime + (XPTimeout shr 1)) < GetSystemTime then //if (LastOKTime + ((XPTimeout + (XPTimeout shl 1)) shr 2)) > GetSystemTime then begin WriteLn('Exiting siphon due to unguaranteed click and early timeout ' + IntToStr(GetSystemTime - LastOKTime)); Exit; end; end; // check exit condition - hound broken down RefreshRuneCounters(False, TYPE_RUNE_ESSENCE); if (PrevRuneEssence > COUNTER_RUNE[TYPE_RUNE_ESSENCE]) then begin // check for reasonable drain if (PrevRuneEssence - COUNTER_RUNE[TYPE_RUNE_ESSENCE] < 3) then begin // ok LastOKTime := GetSystemTime; end; end; if (PrevRuneEssence < COUNTER_RUNE[TYPE_RUNE_ESSENCE]) then begin // creature broken down WriteLn('Creature broken down.'); If not CurrentTPAModel.Hound then begin WriteLn('...but... we did not think it was hound'); end else begin if ModelGuaranteed then begin xpTick := GetXPBarTotal - EntryXP; if xpTick > 0 then begin ModelXP := ModelXP + xpTick; end; WriteAccountingForCurrentModel(ModelXP, GetSystemTime - ModelTimer); end; end; Result := True; WriteLn('Exiting siphon due to broken creature'); LastRightClick := GetSystemTime - 30000; // to immediately allow right click Exit; end; // adjust PrevRuneEssence := COUNTER_RUNE[TYPE_RUNE_ESSENCE]; // we can loop - first see if we can get better target if (NeedMoreEssence) then begin // just to be sure if not IsInRuneSpan then begin Result := True; WriteLn('Exiting siphon due to not in runespan'); Exit; end; WriteLn('need more essence'); if (not CurrentTPAModel.Hound) then begin if ModelGuaranteed then begin xpTick := GetXPBarTotal - EntryXP; if xpTick > 0 then begin ModelXP := ModelXP + xpTick; end; WriteAccountingForCurrentModel(ModelXP, GetSystemTime - ModelTimer); end; // we got to get out of this Result := true; WriteLn('Exiting siphon due to essence count'); Exit; end; // just sleep sleep(RandomRange(1000,2000)); continue; end; // we don't need more essence yet FloorLevel := GetFloorLevel; if (FloorLevel <= 0) then begin if not IsInRuneSpan() then Exit; FloorLevel := GetFloorLevel; end; ModelsTestTimer := GetSystemTime; NewModel := FindTarget(False, FloorLevel, SkillLevel, Players[0].Member, 0, CurrentTPAModel.ModelType, true, TPLocation, SelectedOption, ModelsTestCount); ModelsTestTimer := GetSystemTime - ModelsTestTimer; // check if (ModelsTestCount > 0) then begin ModelsTestTimer := (ModelsTestTimer * 100) / ModelsTestCount; ModelsTimerString := IntToStr(ModelsTestTimer div 100) + '.'; ModelsTestTimer := ModelsTestTimer mod 100; ModelsTimerString := ModelsTimerString + IntToStr(ModelsTestTimer div 10) + IntToStr(ModelsTestTimer mod 10); if (LOG_LONG_SEARCHES) then WriteLn('Pre-empt routine tested ' + IntToStr(ModelsTestCount) + ' model(s) at ' + ModelsTimerString + 'ms each'); end; if (NewModel.XP < 0) then begin // wait a little if (ModelsTestTimer < 800) then begin Sleep(RandomRange(100, 1000 - ModelsTestTimer)); end; continue; end; // check if SelectedOption then begin CurrentXP := GetXPBarTotal; if ModelGuaranteed then begin xpTick := GetXPBarTotal - EntryXP; if xpTick > 0 then begin ModelXP := ModelXP + xpTick; end; WriteAccountingForCurrentModel(ModelXP, GetSystemTime - ModelTimer); end; ModelGuaranteed := true; ModelXP := CurrentXP; ModelTimer := GetSystemTime; GuaranteedClick := true; end else begin GuaranteedClick := false; MMouse(TPLocation.x, tpLocation.y, 2, 2); if (WaitUpTextFuzzy('Walk here', MATCH_LOOSE, 80)) then begin // nope RecordClickban(TPLocation.x, TPLocation.y); continue; end; if (WaitUpTextFuzzy('Climb ladder', MATCH_LOOSE, 80)) then begin // nope RecordClickban(TPLocation.x, TPLocation.y); continue; end; if (WaitUpTextFuzzy('Use platform', MATCH_LOOSE, 80)) then begin // nope RecordClickban(TPLocation.x, TPLocation.y); continue; end; // check if node if (NewModel.Hound) then begin ClickMouse2(mouse_left); GuaranteedClick := false; // GuaranteedClick := DidRedClick; // if not (GuaranteedClick) then continue; end else begin // nodes don't move if (GetSystemTime - LastRightClick) < RandomRange(15000,20000) then begin ClickMouse2(mouse_left); // not guaranteed // GuaranteedClick := DidRedClick; // if not (GuaranteedClick) then continue; GuaranteedClick := false; end else begin LastRightClick := GetSystemTime; ClickMouse2(mouse_Right); if not WaitOptionFuzzy(MakeUptext(NewModel.Descriptor, NewModel.Hound), MATCH_GOOD, RandomRange(400,500)) then begin sleep(RandomRange(100,500)); continue; end; GuaranteedClick := True; end; end; CurrentXP := GetXPBarTotal; if ModelGuaranteed then begin xpTick := GetXPBarTotal - EntryXP; if xpTick > 0 then begin ModelXP := ModelXP + xpTick; end; WriteAccountingForCurrentModel(ModelXP, GetSystemTime - ModelTimer); end; ModelGuaranteed := GuaranteedClick; ModelXP := CurrentXP; ModelTimer := GetSystemTime; GuaranteedClick := true; end; // just wait while (IsMoving) do; // we need to treat accounting correctly so don't assume start until now ModelTimer := GetSystemTime; // will refresh map and move camera MapRefreshed := false; Inc(PreemptCounter); CurrentTPAModel := NewModel; CalculateXPTimeout; if not GuaranteedClick then begin if (ModelsTestTimer < 800) then begin Sleep(RandomRange(100, 1000 - ModelsTestTimer)); end; end; LastOKTime := GetSystemTime; //SMART_ClearCanvas(); WriteStats; UpdateMap(); DrawMap(); end; WriteLn('Exiting siphon through normal loop ' + IntToStr(LastOKTime + XPTimeout) + ' vs ' + IntToStr(GetSystemTime)); end; Procedure antiban; var I: Integer; CurrentCompassDegree: Extended; begin I := Random(1000); case (I) of 0..99 : begin GameTab(tab_Stats); HoverSkill('runecrafting', False); GameTab(28); end; 100..200 : begin SleepAndMoveMouse(7000 + Random(500)); MakeCompass(CurrentCompassDegree-18+Random(32)); end; 200..210 : begin GameTab(Tab_Stats); MakeCompass(CurrentCompassDegree-2+Random(34)); Wait(3000 + Random(500)); GameTab(28); end; 211..220 : begin BoredHuman; MakeCompass('N'); end; 221..300 : begin GameTab(Tab_Stats); Wait(100 + Random(1000)); end; end; end; // hmm ok let's unify what result means - false - we couldn't do our work, true // means we did function MainLoop : boolean; var TPLocation : TPoint; var Looper : Integer; var DID_FIND : Boolean; var SelectedOption : Boolean; var ModelsTestCount : Integer; var ModelsTestTimer : Integer; var ModelsTimerString : String; var LastWasHound : Boolean; var StartTime : Integer; var FloorLevel : Integer; var NewSkillLevel : Integer; begin Result := True; if FindNormalRandoms then begin LastOKTime := GetSystemTime; SetAngle(SRL_ANGLE_HIGH); end; // check if we are in runespan if not IsInRuneSpan then begin FindNormalRandoms; if not LoggedIn() then begin Result := false; Exit; end; // get back to runespan Result := GetBackToRuneSpan(); // see if we failed if not Result then begin WriteLn('We are not in RuneSpan and we kinda failed to get back.'); Exit; end; end; // ok let's do it if (not Result) then exit; RefreshRuneCounters(false, TYPE_RUNE_NONE); // check if (SkillLevel < 1) then begin NewSkillLevel := GetSkillLevel(SKILL_RUNECRAFTING); if (NewSkillLevel > 0) then begin // save SkillLevel := NewSkillLevel; end else begin // ok just pretend this didn't happen for now but if longer than 3 min we // will have to end Result := true; // check if we are without xp for more than 3 minutes if (LastOKTime - GetSystemTime) > 180000 then begin Result := false; end else begin // waiting WriteLn('Waiting for skill info'); Sleep(RandomRange(800, 2700)); end; exit; end; end; // hopping //DoDTMHop2Main; DID_FIND := false; LastWasHound := CurrentTPAModel.Hound; StartTime := GetSystemTime; for Looper := 1 to 50 do begin ModelsTestTimer := GetSystemTime; FloorLevel := GetFloorLevel; if FloorLevel <= 0 then begin if not IsInRunespan() then break; FloorLevel := GetFloorLevel; end; CurrentTPAModel := FindTarget(NeedMoreEssence, FloorLevel, SkillLevel, Players[0].Member, 0, TARGET_NONE, true, TPLocation, SelectedOption, ModelsTestCount); ModelsTestTimer := GetSystemTime - ModelsTestTimer; if (ModelsTestCount > 0) then begin ModelsTestTimer := (ModelsTestTimer * 100) / ModelsTestCount; ModelsTimerString := IntToStr(ModelsTestTimer div 100) + '.'; ModelsTestTimer := ModelsTestTimer mod 100; ModelsTimerString := ModelsTimerString + IntToStr(ModelsTestTimer div 10) + IntToStr(ModelsTestTimer mod 10); if LOG_LONG_SEARCHES then WriteLn('Main loop tested ' + IntToStr(ModelsTestCount) + ' model(s) at ' + ModelsTimerString + 'ms each'); end; if (CurrentTPAModel.XP > 0) then begin if SelectedOption then begin DID_FIND := True; GuaranteedClick := True; writeln('Guaranteed click'); Break; end; GuaranteedClick := False; MMouse(TPLocation.x, TPLocation.y, 2, 2); ClickMouse2(mouse_left); // GuaranteedClick := DidRedClick; DID_FIND := True; if (DID_FIND) then Break; end; // still looping? if LastWasHound then begin // assume 7 seconds recovery time if GetSystemTime - StartTime < 7000 then continue; end; if (Looper mod 3) = 0 then begin // random walk island WriteLn('Walking for target'); RandomWalkIsland(); end; end; while (IsMoving) do; UpdateMap; DrawMap; if (DID_FIND) then DID_FIND := DO_SIPHON; if (DID_FIND) then begin WriteLn('main loop done without finding target'); end else begin WriteLn('main loop failed to find anything'); if (Random(25) = 1) then begin CompassMovement(-50, -20, false); if (Random(4) = 1) then CompassMovement(2, 12, false); end else begin if (Random(10) = 1) then CompassMovement(5, 22, false); end; if (Random(18) = 1) then begin // walk a little RandomWalkIsland; end; if (Random(9) = 1) then begin SetAngle(SRL_ANGLE_LOW); CompassMovement(-40, 100, false); SetAngle(SRL_ANGLE_HIGH); end; end; // ensure that we don't have nag window IsInRuneSpan(); // check if we are without xp for more than 3 minutes if (LastOKTime - GetSystemTime) > 180000 then begin Result := false; end; end; procedure TestModels; var DESC : TStringArray; var MatchingModels : TPAModelArray; var ModelMatches : TPointArray; var index : Integer; var resultIndex : Integer; var MyStart : Integer; var MyEnd : Integer; begin SetColorToleranceSpeed(1); // 2 MatchingModels := GetSearchOrderTPAModelList(False, 3, 99, True) SetLength(DESC, 1); for index := 0 to Length(MatchingModels) - 1 do begin // look if // (MatchingModels[index].Descriptor <> 'Skulls') //and (MatchingModels[index].Descriptor <> 'Fleshy growth') and (MatchingModels[index].Descriptor <> 'Fire storm') //and (MatchingModels[index].Descriptor <> 'Bloody skulls') and (MatchingModels[index].Descriptor <> 'Undead soul') and (MatchingModels[index].Descriptor <> 'Soul esswraith') //(MatchingModels[index].Descriptor <> 'Blood esswraith') then continue; MyStart := GetSystemTime; ModelMatches := FindModel(MatchingModels[index], EnvironmentalExcludes[GetFloorLevel]); MyEnd := GetSystemTime; // check if we have matches Writeln('LOOKING FOR ' + MatchingModels[index].Descriptor + ' TOOK ' + IntToStr(MyEnd - MyStart) + 'ms and got ' + IntToStr(Length(ModelMatches))); if (Length(ModelMatches) <= 0) then continue; DESC[0] := MatchingModels[Index].Descriptor; // go through results for resultIndex := 0 to Length(ModelMatches) - 1 do begin if ModelMatches[resultIndex].x < 6 then continue; if ModelMatches[resultIndex].y < 6 then continue; break; end; end; end; procedure FreeMyDTMs; var Index : Integer; begin // runes for Index := TYPE_RUNE_MIN to TYPE_RUNE_MAX do begin FreeDTM(DTM_RUNE[Index]); end; FreeDTM(DTM_FIRST_FLOOR); FreeDTM(DTM_SECOND_FLOOR); FreeDTM(DTM_THIRD_FLOOR); FreeDTM(DTM_RUNESPHERE); FreeDTM(DTM_YELLOW_WIZARD); end; procedure ClearClickban; var i : integer; begin for i := 0 to CLICKBAN_MAX_AREAS - 1 do begin CLICKBANS[i].X := -1; CLICKBANS[i].Y := -1; end; end; procedure RecordClickbanEX(RasterX, RasterY : Integer); var Index : Integer; var CBCount : Integer; begin // check for Index := 0 to CLICKBAN_MAX_AREAS - 1 do begin if CLICKBANS[Index].x < 0 then begin CBCount := Index; break; end; if CLICKBANS[Index].x <> RasterX then continue; if CLICKBANS[Index].y <> RasterY then continue; // already exists exit; end; // move out if CBCount = CLICKBAN_MAX_AREAS - 1 then begin // watch it buster Dec(CBCount); end; for Index := CBCount - 1 downto 0 do begin CLICKBANS[Index + 1].x := CLICKBANS[Index].x; CLICKBANS[Index + 1].y := CLICKBANS[Index].y; end; CLICKBANS[0].X := RasterX; CLICKBANS[0].Y := RasterY; end; procedure RecordClickban(X, Y : Integer); var RecordXPlus : Boolean; var RecordYPlus : Boolean; var RasterX : Integer; var RasterY : Integer; begin RasterX := (X - MSX1) shr 3; RasterY := (Y - MSY1) shr 3; RecordXPlus := false; RecordYPlus := false; if (RasterX < ((MSX2 - MSX1) shr 3)) then RecordXPlus := True; if (RasterY < ((MSY2 - MSY1) shr 3)) then RecordYPlus := True; RecordClickbanEX(RasterX, RasterY); if RecordYPlus then RecordClickBanEx(RasterX, RasterY + 1); if RecordXPlus then RecordClickBanEx(RasterX + 1, RasterY); if (RecordXPlus and RecordYPlus) then RecordClickBanEx(RasterX + 1, RasterY + 1); if (RasterX > 0) then begin RecordClickBanEX(RasterX - 1, RasterY); if RecordYPlus then RecordClickBanEx(RasterX - 1, RasterY + 1); if (RasterY > 0) then begin RecordClickBanEX(RasterX, RasterY - 1); RecordClickBanEX(RasterX - 1, RasterY - 1); end; end else begin if (RasterY > 0) then begin if RecordXPlus then RecordClickBanEx(RasterX + 1, RasterY - 1); RecordClickbanEX(RasterX, RasterY - 1); end; end; end; procedure WriteAccountingForCurrentModel(XPDiff : Integer; TimeDiff : Integer); begin writeln('Account for current model [' + CurrentTPAModel.Descriptor + '], adding ' + IntToStr(XPDiff) + ' XP in ' + IntToStr(TimeDiff) + ' ticks.'); end; var i : integer; var runecraftingLevelsGained : Integer; var EverythingOk : Boolean; var TargetTime : Integer; var NewSkillLevel : Integer; begin DeclarePlayers; ; SmartSetRefresh(100); SetupSRL; SetupSRLStats(1037, SRLStats_User, SRLStats_Password); LoginPlayer; while not RSReady do Sleep(2000); SmartSetRefresh(60); ClearDebug(); //SMART_ClearCanvas(); WriteLn ('**************************'); LogSmartLine('** Preemptible RuneSpan **'); WriteLn ('**************************'); LogSmartLine('Initializing density models and 3D engine...'); // clear InitializeStatsArray(); CurrentTPAModel.XP := -1; LastFloor := -1; // register TPA models RegisterTPAModels(); Initialize3D(); SetLength(CLICKBANS, CLICKBAN_MAX_AREAS); ClearClickban; AppendSmartLine('DONE', True); LogSmartLine('Initializing inventory DTMs...'); for i := TYPE_RUNE_MIN to TYPE_RUNE_MAX do begin RUNE_LastKnownPosition[i] := -1; COUNTER_RUNE[i] := 0; end; // runes DTM_RUNE[TYPE_RUNE_ESSENCE] := DTMFromString('maQEAAHicrcxNCsJADIbh6A2E9hJSf9pOsRXEotJOOxsRj+9CRUUE3QiufQmzEFzqwMPkS0J6IrLoimyxQYwUKzQoUMFi5q3hUGKJGifu3LHDHk+fj7jghYefXXHAGbePXmYSqeepsqXR37VWRsOBTIucbHQnn2SawzCQJB5rHUV9nQXc+VXnD77eGw4EIEI='); DTM_RUNE[TYPE_RUNE_AIR] := DTMFromString('mFQEAAHic42VgYJjFxMAwHYinAfFsIJ4LxHOAeAYQTwHiiUDcB8XzgHghED8G6nsExM+gGMS/D8UPkcTeAvE7qForC1OGjx8/Mly9epXhy5cvYPzu3TsGO1trBkd7O4bZs+sZ/H29GSLCQhg83FwYLMzNGESA+kjFjGRgFAAALvspiQ=='); DTM_RUNE[TYPE_RUNE_MIND] := DTMFromString('mlwAAAHicY2dgYDjIxMBwHIp3Q/ERIN4PxI8ZIPgBFIPYL4H4ORC7ODsyvFihwWBlac7g7eXB8GqTNpgGYRGgPC7MiAdDAQDaHxOy'); DTM_RUNE[TYPE_RUNE_WATER] := DTMFromString('mrAAAAHic42BgYDjAhMC7gPgYEJ8F4r1QNgcjAwMLEPMwQtggzAbEokAsAMT6pesZdMs3MFQt2cfg6eHG4OLsxKCtrcUQGR7KkBAXzSACtAMfZiSAYQAAHOAP7Q=='); DTM_RUNE[TYPE_RUNE_EARTH] := DTMFromString('m6wAAAHic42ZgYMhiguBiIM4F4hQouxxKJwNxElTNU6D6RwwQ+jkQvwLi+0D8GIjfQzFI/h4QOznaM8yp8maojpZmWNURyxAaEgRm29laM3h5ujPExUYxRISFMHi4uTCIANUTixlJwEgAAPNjGpI='); DTM_RUNE[TYPE_RUNE_FIRE] := DTMFromString('m6wAAAHic42ZgYDjABMEHgXgfEB8F4r1AfASIt0PxSSA+BcQvgOofA/F9KH4AxE+B+BmU/RaI30PlvoXrMPy6Zs3wa78dg4O9KcP9q8EMXyptGX4GqTIEB/kzxERFMDg7OjAYGxkyiADVE4sZScBIAADNxCHK'); DTM_RUNE[TYPE_RUNE_BODY] := DTMFromString('mggAAAHicY2NgYDjIxMBwBIiPAvEBIN4DxLuAmI0RgrmBmBdKg/jOTg4Mf//+ZTA0nc/Q1LqXwch0AUNp+U4GEaBZ2DAjDgwBAKWvDn0='); DTM_RUNE[TYPE_RUNE_COSMIC] := DTMFromString('mrAAAAHic42BgYHBgYmDwAGI/IHYFYjcgdgJiKyC2BGJ2RgQWBmJuIGYCYgEgZgXivz/PMPz5UsBgY23FEBToz/Dnaw+Dm6szQ0JcNENocCCDCNAOfJiRAIYBAPlzD0s='); DTM_RUNE[TYPE_RUNE_CHAOS] := DTMFromString('m6wAAAHic42ZgYMhnYmDIAuJcIM6D0hlAXAzESVBcAsRlQMzGCMHMQMwFxLxAzATE7EDMCsRCQCwMZVtZWjLYWFsx/P37F4yfLFZleLJEA0irMISGBDHEREUwuLo4MViYmzGIAN1BLGYkASMBACzvFec='); DTM_RUNE[TYPE_RUNE_ASTRAL] := DTMFromString('mggAAAHicY2NgYJjOxMAwB4pnAvFEKNZmZGDQBGJdIDaA0lpAfOfYHYaJ3RsZPD3cGG5ee8wQ4O/DsH/jGQYRoFnYMCMODAEA9csQBA=='); DTM_RUNE[TYPE_RUNE_NATURE] := DTMFromString('mrAAAAHic42BgYJjKxMAwE4inAPF0IO6B4vlAvBCIORkZGDiAmA+IWYCYDYiFgFgYyp5zNpJh3uV4hrBtKQx2ttYMwUH+DFERYQwO9rYMZqbGDCJAO/BhRgIYBgB1aQ7c'); DTM_RUNE[TYPE_RUNE_LAW] := DTMFromString('mggAAAHicY2NgYDjEBMH7oXg3EB8DYk1GBgYDKNYGYh0odnJ0YNCce45Ba945Bnc3FyD7LBiLAM3ChhlxYAgAAJOqDgo='); DTM_RUNE[TYPE_RUNE_DEATH] := DTMFromString('m1gAAAHic42JgYMhgYmAoBOJcIC4C4jQgToRikFwZEJcDsSEjBKsCsSYQa0BpEyC2BGJzINYC4t+/f8Oxg70tQ3CQP0Ogvy9DTFQEQ0RYCIOzowODtZUFgwjQbmIwI5EYAQBkixXw'); DTM_RUNE[TYPE_RUNE_BLOOD] := DTMFromString('mlwAAAHicY2dgYMhlYmDIA+I0IC6B4iSoWAgjA4MfEPsDsS8QR0BxFBDvk8th2CVaxODj5cFgb2fDEB0VzhAXE8UQGhzIIAI0FxdmxIOhAADo6Q0q'); DTM_RUNE[TYPE_RUNE_SOUL] := DTMFromString('m6wAAAHic42ZgYIgH4mQgTgXiRCCOAeJIIA4D4mggjoLKZwBxMyMDQxMQ1wFxDRDXAnE9I0QchDuAuB2qxs/Xm2H5igcMc5feY3Cwt2VwdXYE84MD/cF0eFgwQ4C/L4O7mwuDCNBsYjEjCRgJAAB26Blr'); PreemptCounter := 0; DTM_FIRST_FLOOR := DTMFromString('mbQAAAHicY2VgYFADYgkgFgdiLSBWAuIGIC4C4hogLgXiViD+/ZOJYVKdLkPvBDGGuFB2hjU72BlEgOLomBELBgMAfv8KAw=='); DTM_SECOND_FLOOR := DTMFromString('mbQAAAHicY2VgYFAGYk0oLQXE0kBcBcQFQJwPxOVA3A7Ee2sfM2iq2zHcXvaFYcq8hQwyUsoMIkBxdMyIBYMBAKUACrY='); DTM_THIRD_FLOOR := DTMFromString('mbQAAAHicY2VgYFAGYkUglgdiaSCWAeJaIK4E4mIgbgbidpA6ZWWG6x+/M+x/8ophxtoNDIxAKAIUR8eMWDAYAAC72wso'); DTM_RUNESPHERE := DTMFromString('mbQAAAHicY2VgYGADYh4g5mSAABYo5oaKsUPFu/o2Mjg5ZDCkff3FoPXqB4Pd1z8MIkBxdMyIBYMBACN6CfA='); DTM_YELLOW_WIZARD := DTMFromString('mWAAAAHicY2FgYNgLxHuAeDcQ7wfiAiBOBuJoIK4F4qgQP4a/1wsYXp3IYLixI4EBHTCiYRAAAJNrC/E='); AddOnTerminate('FreeMyDTMs'); AppendSmartLine('DONE', True); LogSmartLine('Checking skill level for target selection...'); StartTime := GetSystemTime; LastRightClick := GetSystemTime; SmartSetDebug(True); SkillLevel := GetSkillLevel(SKILL_RUNECRAFTING); AppendSmartLine('DONE (' + IntToStr(SkillLevel) + ')', True); LogSmartLine('Initiating startup sequence...'); if not (InitialSetUp()) then begin LogSmartLine('Failed to set up, could be we could not get to runespan or obtain essences'); Exit; end; LogSmartLine('Obtaining current XP reading...'); if not IsXPBarOpen then ToggleXPBar(true); Players[CurrentPlayer].Integers[0] := GetXPBarTotal; LastXPTotal := 0; SetAngle(SRL_ANGLE_HIGH); AppendSmartLine('DONE (' + IntToStr(Players[CurrentPlayer].Integers[0]) + ')', True); LogSmartLine('Assessing map...'); UpdateMap(); AppendSmartLine('DONE', True); LogSmartLine('Generating map 3D projection cache...'); Initialize3DModelFromMap(); //SMART_ClearCanvas(); AppendSmartLine('DONE', True); DrawMap(); if TEST_MODELS then begin repeat TestModels(); //Sleep(2000); //SMART_ClearCanvas(); until not LoggedIn; end; // set up levels repeat // break target time TargetTime := GetSystemTime + (60000 * BREAK_TIME) - (60000 * BREAK_TIME_SPREAD) + RANDOM(120000 * BREAK_TIME_SPREAD); // do tiers set up LastOKTime := GetSystemTime; repeat EverythingOk := MainLoop; if (EverythingOk) then begin if (DesperatelyNeedsEssence) then begin writeln('desperately need essence'); EverythingOk := GetSomeEssence(); end; end; I := Random(360); case (I) of 0..99 : begin antiban; end; end; CurrentTPAModel.XP := -1; //SMART_ClearCanvas(); WriteStats; UpdateMap; DrawMap; wait(500+Random(300)); // check sparsely if (Random(10) = 1) then begin NewSkillLevel := GetSkillLevel(SKILL_RUNECRAFTING); if (NewSkillLevel > 0) then begin if (SkillLevel > 0) then begin runecraftingLevelsGained := NewSkillLevel - SkillLevel; if (runecraftingLevelsGained > 0) then begin WriteLn('Gratz on level up'); stats_IncVariable(STATS_LEVEL_RUNECRAFTING, runecraftingLevelsGained); // we should rethink SkillLevel := NewSkillLevel; end; end else begin SkillLevel := NewSkillLevel; end; end; end; until (not Loggedin) or (not EverythingOk) or (TargetTime < GetSystemTime); if not TAKES_BREAKS then exit; ExitToLobby; sleep ((45000 * BREAK_DURATION) + RANDOM(30000 * BREAK_DURATION)); if not LoggedIn then begin LoginPlayer; end; MMouse(100,100,100,100); if SWITCH_WORLDS_BREAK then ChangeWorld(RandomWorld(Players[0].Member, False)); Wait(4000 + Random(3000)) FindNormalRandoms; until not TAKES_BREAKS; end.

it says cannot spawn client. it compiles though.
No, THIS:
attitude is.
Jackasses who think they're better than others because they have more knowledge in a certain topic (scripting in this case).
Thanks to kyle for the updated script. I haven't tried it, but the effort is appreciated in any case
I was trying to use your script and was hit with a:
[Error] C:\Simba\Includes\SRL/SRL/misc/paintsmart.simba(42:33): Unknown identifier 'SmartGetDebugDC' at line 41
Compiling failed.
--any help?
It doesn't do the air or mind ones, It only does the water ones for me
Well no paint (cause it kept interfering) but 99! Ran for 10+ hours, to bad I don't have the debug, I forgot about it.
![]()
im getting this error, wat did i do wrong ? o.O
[Error] C:\Simba\Includes\SRL/SRL/misc/paintsmart.simba(42:33): Unknown identifier 'SmartGetDebugDC' at line 41
Compiling failed.
There are currently 1 users browsing this thread. (0 members and 1 guests)