Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Program WorldTracker;
- { ++++ World Population Tracker for Oldschool RS +++ }
- { ++ Written by Frement, minor edits by Samerdl +++ }
- const
- ManualRefresh = false; // Make it so you have to click Refresh to re-load data.
- Sleep_Intervals = 500; // Wait time between refresh rates.
- MinCount = 3; // When a world increase this amount, it will show it green.
- MsgBoxe = true; // Display a message box warning when a world increase above WarnCount.
- WarnCount = 8; // How many players should the world increase for a warn message.
- XDistance = 70; // Formating of the text, X.
- Ydistance = 19; // Formating of the text, Y.
- type
- TWorld = record // loading up a record of data.
- World, Players: Integer; // Two vars, World and Players.
- end;
- TDisplay = record // Display Record.
- Surface: Integer; // The Display is a bitmap which is debugged using ImgForm
- Width, Height: Integer; // Width and Height definition.
- end;
- TWorldArray = Array of TWorld; // Defining that TworldArray is an Array of Tworld, so we can call it in the script.
- function World(__World, __Players: Integer): TWorld; // Creating a function that is a Tworld.
- begin
- Result.World := __World; // What do the two underscores mean?
- Result.Players := __Players; // kinda of hard to understand this part, we are basically defining what Tworld is?
- end;
- var
- MSGBoXES: boolean;
- function SortWorlds(Worlds: TWorldArray): TWorldArray;
- var
- I, J, K: Integer;
- begin
- K := 301;
- repeat
- for I := 0 to High(Worlds) do begin // Loops each world 61 times (-1)
- if (Worlds[I].World = K) then begin // After the world slot is done 61 times, it increase slot to two and loops it 61 times again (-1)
- Inc(J);
- SetLength(Result, J);
- Result[J - 1] := Worlds[I];
- end;
- end;
- Inc(K); // After each loop it will increase K by 1 number.
- until(Length(Result) = Length(Worlds)); // This part i dont understand, how does the script know what worlds length is? It's not really defined is it?.
- end;
- function CalculateDifference(LC, CC: TWorldArray): TWorldArray;
- var
- I: Integer;
- begin
- SetLength(Result, Length(LC)); // Sets the length of the Array.
- for I := 0 to High(LC) do begin // Loops all the world results.
- Result[I] := World(LC[I].World, CC[I].Players - LC[I].Players); // Then calculates the difference between The players in the array, in this case CC is the current world data.
- end; // So its Original Player count - Current player count (after script finishes the loop.
- end; // Which gives us the result for each world calculated, inside the array of loop.
- // SO.. if i understood this correctly so far:
- // It sorts the worlds in The array, loops each world 62 times then gives it a minus 1, till it reaches 61 slots total. Sorts them from 301 to 378.
- // After that, It will calculate the difference, when we call Currentworld data it will load up the world data and then we'll loop it again and calculate the difference between all worlds - in real time player count.
- function GetData: String;
- var
- HTTPClient: Integer;
- begin
- HTTPClient := InitializeHTTPClient(False); // This creats a new client and assigns it an ID, used for web functions
- Result := GetHTTPPage(HTTPClient, 'http://oldschool.runescape.com/slu'); // gets the URL data - raw data, No post AddPostVariable needed here. GetHttpPage is same as GetPage except it lets us choose what client we want our data from.
- FreeHTTPClient(HTTPClient); // Frees the client to prevent memory leaks.
- end;
- function GetWorldData: TWorldArray;
- var
- Pieces, WorldPieces: TStringArray;
- I, J: Integer;
- begin // here we are calling a function within a function... never thought about that lol.
- Pieces := MultiBetween(GetData, 'e(', '");'); // This grabs each line of world data, from the start e(3... till the end ,""), grabs the spacing between them, what it eventually does is remove all the spacing between the lines.
- for I := 0 to High(Pieces) do begin // Starts a loop from world 301 till 378.
- if (Pos('oldschool', Pieces[I]) > 0) then begin // If the position of the world oldschool till the end of the line is bigger than zero (fail safe i suppose).
- WorldPieces := Explode(',', Pieces[I]); // It deletes all the commas from our text array.
- Inc(J); // loops it total 61 times and each time it adds a new world to the array, including the number of the world and population.
- SetLength(Result, J); // Sets the length of the result in ascending
- Result[J - 1] := World(StrToInt(WorldPieces[0]), StrToInt(WorldPieces[4])); //This part i don't understand at all, when you put worldpieces to any other number other than 0 and 4 the script wont compile :Error: Exception: "false" is an invalid integer at line 73
- end;
- end;
- end;
- //Display Functionality
- function Display(Width, Height: Integer): TDisplay;
- begin
- Result.Surface := CreateBitmap(Width, Height); // Creates a bitmap as surface.
- Result.Width := Width; // Defines its width.
- Result.Height := Height; // And height.
- DisplayDebugImgWindow(Result.Width, Result.Height); // Displays the bitmap.
- end;
- procedure ClearDisplay(__Display: TDisplay);
- begin
- FastDrawClear(__Display.Surface, clBlack); // Draws Color on every Pixel of the Bitmap (Thus creating a Background).
- end;
- procedure FlushDisplay(__Display: TDisplay);
- begin
- DrawBitmapDebugImg(__Display.Surface); // Drawing.
- end;
- procedure FreeDisplay(__Display: TDisplay);
- begin
- FreeBitmap(__Display.Surface); // Frees the Bitmap.
- end;
- procedure DisplayDrawText(__Display: TDisplay; Text, Font: string; X, Y, Color: Integer);
- var
- TPA: TPointArray;
- W, H: Integer;
- begin
- TPA := TPAFromText(Text, Font, W, H); // Loads The world data info as a TPA.
- OffsetTPA(TPA, Point(X, Y)); // Offsets the TPA
- DrawTPABitmap(__Display.Surface, TPA, Color); // Draws it on the ImgForm.
- end;
- procedure AnsweredNo;
- begin
- Writeln('Disabling MsgBox for world Tracking...');
- MSGBoXES := false; // Used to disable further MsgBox warnings when a player clicks 'cancel'.
- end;
- procedure DisplayDrawWorldInfo(__Display: TDisplay; World, Players, X, Y: Integer);
- var
- TPA: TPointArray;
- WorldInfos, C, W, W2, H, H2: Integer;
- begin
- if (Players < 0) then // If Player count is negative then it draws red.
- C := 255;
- if (Players = 0) or ((Players < MinCount) and (Players > 0)) then
- c := 16777215; // if Player count is between 0 - mincount then draws white.
- if (Players >= MinCount) then
- C := 65280; // If its above then it draws green.
- TPA := TPAFromText(ToStr(World) + ':', 'SmallChars', W, H); // Loops the world Data.
- OffsetTPA(TPA, Point(X, Y)); // Offsets them in order.
- DrawTPABitmap(__Display.Surface, TPA, clYellow); // Draws the world Data.
- TPA := TPAFromText(ToStr(Players), 'SmallChars', W2, H2);// Loops the Player pop data.
- OffsetTPA(TPA, Point(X + W + 2, Y)); // Offsets them in order.
- DrawTPABitmap(__Display.Surface, TPA, C); // Draws it (Thus adding World + Player info.
- if (ManualRefresh = true) then // If manual refresh is Enabled, then it will draw a Refresh button, so to speak.
- DisplayDrawText(__Display, 'Refresh', 'SmallChars', 225, 310, 16744192);
- if (Players >= WarnCount) and (MSGBoXES = true) then
- begin
- WorldInfos := MessageBox('World: ' + IntToSTr(World) + ' Just went up by: ' + IntToStr(Players) + ' - Players', 'World Notice', 1);
- writeln(ToStr(WorldInfos));
- case (WorldInfos) of
- 1: Exit; // If a player Clicks ok then it exists the message box..
- 2: AnsweredNo;// If a player clicks cancel then it will disable further message box warnings.
- end;
- end;
- end;
- procedure DrawWorldData(__Display: TDisplay; Worlds: TWorldArray);
- var
- I, XOffset, YOffset, X, Y: Integer;
- begin
- ClearDisplay(__Display); // Resets the Display each time with black background.
- XOffset := XDistance; // Off Sets X/Y distance to be displayed in order.
- YOffset := YDistance;
- DisplayDrawText(__Display, ' OSRS World Tracker - By Frement', 'SmallChars', 30, 10, 16744192);
- for I := 0 to High(Worlds) do // Loops all the worlds
- begin // Loops all the world Data
- DisplayDrawWorldInfo(__Display, Worlds[I].World, Worlds[I].Players, 20 + (XOffset * X), 40 + (YOffset * Y));
- Inc(Y); // Increases the Y spacing on each world
- if (Y > 15) then
- begin
- Y := 0; // if the Y goes beyond the limit, it resets it..
- Inc(X); // And then increases the X thus creating a new Column
- end;
- end;
- FlushDisplay(__Display); // Draws the Bitmap
- end;
- var
- LastCount, CurrentCount, Diff: TWorldArray;
- __Display: TDisplay;
- Box1: Tbox;
- // 'Client' Display Functionality, used to read the refresh click area.
- // Taken from SmartParams file :-).
- function FindAndSetTarget(TitlePrefix: string; SetAsTarget: Boolean): Boolean;
- var
- T: TSysProcArr;
- I: Integer;
- begin
- T := GetProcesses; // Gets all the process.
- for I := High(T) downto 0 do // And loops..
- if Pos(TitlePrefix, T[I].Title) <> 0 then // Finds the Process with a similar title..
- begin
- Result := True; // Once it does,
- if SetAsTarget then // If a user choses to make it active then..
- SetTarget(T[I]); // It will set it as 'Active' Target!.
- Exit;
- end;
- end;
- //Taken from SmartParams file as well.
- procedure GetRealMousePos(var X, Y: Integer);
- var
- KMTarget, ITarget: Integer;
- begin
- {$IFDEF LAPE}
- writeln('GetRealMousePos not implemented yet in SRL-5 Lape!');
- TerminateScript;
- {$ELSE}
- KMTarget := GetKeyMouseTarget;
- ITarget := GetImageTarget;
- FindAndSetTarget('DebugImgForm', True);
- GetTClient.IOManager.GetMousePos(X, Y);
- FreeTarget(GetImageTarget);
- SetKeyMouseTarget(KMTarget);
- SetImageTarget(ITarget); // basically sets specific mouse area to that active client.
- {$ENDIF}
- end;
- function IsRealMouseInBox(B: TBox): Boolean;
- var
- P: TPoint;
- begin
- GetRealMousePos(P.X, P.Y); // Uses the above command to get the mouse position on target.
- if PointInBox(P, B) then // And if the mouse is inside a Tbox area then..
- begin
- if ismouseButtonDown(Mouse_left) then // If a player does a mouse_left click in that area
- result := true; // THen it will read it as a 'refresh' its not a real button lol.
- end;
- end;
- procedure OnTerminate;
- begin // Frees the bitmap on terminate, to prevent memory leaks.
- FreeDisplay(__Display);
- end;
- procedure refresh;
- begin
- cleardebug; // Clears Debug.
- LastCount := SortWorlds(GetWorldData); ///Calls 3 functions within each other, 1) Grabs the Data then delets all the spacing between lines and useless information, 2) Creates all 61 worlds (-1) with player count and sorts them in an array. This gives us the current Count.
- Sleep(Sleep_Intervals); // Does a small wait between the data grab..
- CurrentCount := SortWorlds(GetWorldData); // Grabs the current data. Same as above.
- Diff := CalculateDifference(LastCount, CurrentCount); // Calculates the differece between eachworld
- DrawWorldData(__Display, Diff);
- SetTargetBitmap(__Display.Surface);
- end;
- begin
- __Display := Display(305, 350); // __Sets the Height/Width of the Bitmap and displays it.
- AddOnTerminate('OnTerminate');
- FindAndSetTarget('DebugImgForm', true); // Sets the Debugged image as target.
- box1 := IntToBox(223, 325, 274, 350); // Defines where the "Refresh" button area is.
- MSGBoXES := MsgBoxe; // Relays MsgBoxes data (so it can be set to false if a user clicks 'cancel'
- repeat
- if (ManualRefresh = true) then // if it's manual refresh then.
- begin
- if IsRealMouseInBox(box1) then // It will only refresh Data when a player clicks on the 'refresh' button..
- refresh
- end else // Else (if refresh is disabled) then it will just loop it.
- refresh;
- until (False);
- end.
Add Comment
Please, Sign In to add comment