Guest User

Untitled

a guest
Apr 13th, 2017
693
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 36.35 KB | None | 0 0
  1. (*
  2. Player Management
  3. =================
  4.  
  5. The Players file stores the functions related to the Players array. It also
  6. stores properties of the TPlayer type.
  7.  
  8. The source for this file can be found `here <https://github.com/SRL/SRL-6/blob/master/lib/core/players.simba>`_.
  9.  
  10. *)
  11.  
  12. {$f-}
  13.  
  14. (*
  15. Consts, Types, Vars
  16. ~~~~~~~~~~~~~~~~~~~
  17.  
  18. The following constants, types and variables are used throughout the chatBox methods.
  19.  
  20. *)
  21.  
  22. {*
  23. **const Internal**
  24.  
  25. File's internal constants.
  26.  
  27. * __LOGIN_COLOR_TEXT: The color of the login screen text.
  28.  
  29. *}
  30. const
  31. {$IFNDEF CODEINSIGHT}
  32. __LOGIN_COLOR_TEXT = 16777215;
  33. {$ENDIF}
  34.  
  35. {*
  36. **var Internal**
  37.  
  38. File's internal variables.
  39.  
  40. * __boxUsername: TBox of the username edit box.
  41. * __boxPassword: TBox of the password edit box.
  42. * __areDynamicInterfacesSet: Used to set the bounds of dynamic interfaces.
  43.  
  44. *}
  45. var
  46. {$IFNDEF CODEINSIGHT}
  47. __boxUsername: TBox = [-1, -1, -1, -1];
  48. __boxPassword: TBox = [-1, -1, -1, -1];
  49. __areDynamicInterfacesSet: boolean = false;
  50. {$ENDIF}
  51.  
  52. (*
  53. **type TPlayer**
  54.  
  55. A record that stores useful information about the current players. It is up to
  56. the scripter to set most of these attributes in their scripts.
  57.  
  58. .. code-block:: pascal
  59.  
  60. type
  61. TPlayer = record
  62. loginName: string;
  63. displayName: string;
  64. nickname: string;
  65. password: string;
  66. bankPin: string;
  67. location: string;
  68. isActive: boolean;
  69. isMember: boolean;
  70. findMod: boolean;
  71. findTrade: boolean;
  72. reincarnate: boolean;
  73. secureLogin: boolean;
  74. worked: TTimeMarker; // Automatically calculated if SRL's login methods are used
  75. world: integer; // -1 to click play button; 0 for random world
  76. skillLevel: array[0..(SKILL_COUNT - 1)] of integer;
  77. booleans: array[0..99] of boolean;
  78. integers: array[0..99] of integer;
  79. strings: array[0..99] of string;
  80. extendeds: array[0..99] of extended;
  81. variants: array[0..99] of variant;
  82. end;
  83.  
  84. *)
  85. type
  86. TPlayer = record
  87. loginName: string;
  88. displayName: string;
  89. nickname: string;
  90. password: string;
  91. bankPin: string;
  92. location: string;
  93. isActive: boolean;
  94. isMember: boolean;
  95. findMod: boolean;
  96. findTrade: boolean;
  97. reincarnate: boolean;
  98. secureLogin: boolean;
  99. worked: TTimeMarker; // Automatically calculated if SRL's login methods are used
  100. world: integer; // -1 to click play button; 0 for random world
  101. skillLevel: array[0..(SKILL_COUNT - 1)] of integer;
  102. booleans: array[0..99] of boolean;
  103. integers: array[0..99] of integer;
  104. strings: array[0..99] of string;
  105. extendeds: array[0..99] of extended;
  106. variants: array[0..99] of variant;
  107. end;
  108.  
  109. TPlayerArray = array of TPlayer;
  110.  
  111. type
  112. PF_TPlayer = record (TPlayer)
  113. settings: TStringArray;
  114. end;
  115.  
  116. PF_TPlayerArray = array of PF_TPlayer;
  117.  
  118. (*
  119. **var Player Variables**
  120.  
  121. All the variables associated with players.simba.
  122.  
  123. .. code-block:: pascal
  124.  
  125. var
  126. players: TPlayerArray;
  127. currentPlayer: integer;
  128. disableIPScreenshots: boolean;
  129.  
  130. * players: An array which contains all players
  131. * currentPlayer: The index of the player currently running in the players array
  132. * disableIPScreenshots: Disables the screenshots taken in the lobby screen
  133.  
  134. *)
  135. var
  136. players: TPlayerArray;
  137. currentPlayer: integer;
  138. disableIPScreenshots: boolean;
  139.  
  140. {*
  141. Raf_GetArmyNames
  142. ----------------
  143.  
  144. .. code-block:: pascal
  145.  
  146. function Raf_GetArmyNames(out names: TStringArray): boolean;
  147.  
  148. Returns the army names saved by the Rafiki Player Manager as a TStringArray.
  149.  
  150. .. note::
  151.  
  152. - by Olly
  153.  
  154. Example:
  155.  
  156. .. code-block:: pascal
  157.  
  158. Raf_GetArmyNames(tsa);
  159. *}
  160. function Raf_GetArmyNames(out names: TStringArray): boolean;
  161. var
  162. s: string := Settings.getPrefix();
  163. begin
  164. Settings.setPrefix('');
  165. try
  166. result := Settings.ListKeys('Rafiki/Armys/', names);
  167. finally
  168. Settings.setPrefix(s);
  169. end;
  170. end;
  171.  
  172. {*
  173. Raf_FindArmy
  174. ------------
  175.  
  176. .. code-block:: pascal
  177.  
  178. function Raf_FindArmy(const name: string): boolean;
  179.  
  180. Returns true if the army 'name' is saved in the Rafiki Player Manager.
  181.  
  182. .. note::
  183.  
  184. - by Olly
  185.  
  186. Example:
  187.  
  188. .. code-block:: pascal
  189.  
  190. if Raf_FindArmy('default') then
  191. writeLn('The army exists');
  192. *}
  193. function Raf_FindArmy(const name: string): boolean;
  194. var
  195. strings: TStringArray;
  196. i: integer;
  197. begin
  198. result := false;
  199.  
  200. if Raf_GetArmyNames(strings) then
  201. for i := 0 to high(strings) do
  202. if (SameText(Replace(Name, ' ', '_', [rfReplaceAll]), Strings[i])) then
  203. Exit(True);
  204. end;
  205.  
  206. {*
  207. Raf_IsArmyEncrypted
  208. -------------------
  209.  
  210. .. code-block:: pascal
  211.  
  212. function Raf_IsArmyEncrypted(const armyName: string): boolean;
  213.  
  214. Returns true if the army 'armyName' is encripted in the Rafiki Player Manager.
  215.  
  216. .. note::
  217.  
  218. - by Olly
  219.  
  220. Example:
  221.  
  222. .. code-block:: pascal
  223.  
  224. writeLn(Raf_IsArmyEncripted('default'));
  225. *}
  226. function Raf_IsArmyEncrypted(const armyName: string): boolean;
  227. var
  228. s: string := Settings.getPrefix();
  229. begin
  230. if (not Raf_FindArmy(armyName)) then
  231. exit(false);
  232.  
  233. Settings.setPrefix('');
  234. try
  235. result := (lowercase(Settings.getKeyValueDef('Rafiki/Armys/'+armyName+'/Encrpyted', 'False')) = 'true');
  236. finally
  237. Settings.setPrefix(s);
  238. end;
  239. end;
  240.  
  241. {*
  242. Raf_DecryptArmy
  243. ---------------
  244.  
  245. .. code-block:: pascal
  246.  
  247. function Raf_DecryptArmy(const armyName: string; var data: string): boolean;
  248.  
  249. Decrypts the army 'armyName' if the player inputs the correct password.
  250.  
  251. .. note::
  252.  
  253. - by Olly
  254.  
  255. Example:
  256.  
  257. .. code-block:: pascal
  258.  
  259. *}
  260. function Raf_DecryptArmy(const armyName: string; var data: string): boolean;
  261. var
  262. pass, dataCopy: string;
  263. label
  264. lStart;
  265. begin
  266. dataCopy := copy(data);
  267.  
  268. lStart:
  269. pass := '';
  270. data := copy(dataCopy);
  271.  
  272. if (InputQuery('Rafiki Player Manager', 'Please enter your army password for decryption', pass)) then
  273. begin
  274. rc2_decrypt(pass, htSHA512, data);
  275. result := ExecRegExpr('<player>', data);
  276. end else begin
  277. print('Input query was cancled');
  278. exit(false);
  279. end;
  280.  
  281. if (not result) then
  282. if (MessageDlg('Rafiki_DecryptArmy', 'Wrong password for decryption', mtError, [mbRetry, mbOk]) = 4) then
  283. goto lStart
  284. else
  285. print('Ok clicked');
  286. end;
  287.  
  288. {*
  289. Raf_GetPlayers
  290. --------------
  291.  
  292. .. code-block:: pascal
  293.  
  294. function Raf_GetPlayers(ArmyName: String; out _Players: TPlayerArray): Boolean;
  295.  
  296. Returns all the players in 'ArmyName' as a TPlayerArray.
  297.  
  298. .. note::
  299.  
  300. - by Olly
  301.  
  302. Example:
  303.  
  304. .. code-block:: pascal
  305.  
  306. *}
  307. function Raf_GetPlayers(ArmyName: String; out _Players: TPlayerArray): Boolean;
  308. var
  309. Data, Pref: String;
  310. TSA: TStringArray;
  311. i: integer;
  312. begin
  313. Result := False;
  314. Print('Raf_GetPlayers()', TDebug.HEADER);
  315.  
  316. if (not Raf_FindArmy(ArmyName)) then
  317. Exit(Print('Army doesn''t exist!', False, 'Raf_GetPlayers: Result = false'));
  318.  
  319. Pref := Settings.getPrefix();
  320. Settings.setPrefix('Rafiki/Armys/');
  321. ArmyName := Replace(Lowercase(ArmyName), ' ', '_', [rfReplaceAll]);
  322.  
  323. try
  324. Print('Army exists, reading the players...');
  325. Data := DeCompressString(Base64Decode(Settings.GetKeyValueDef(ArmyName + '/Player_Data', '')));
  326.  
  327. if Raf_IsArmyEncrypted(ArmyName) then
  328. if (not Raf_DecryptArmy(ArmyName, Data)) then
  329. Exit(Print('Failed to decrpyt army', False, 'Raf_GetPlayers: Result = false'));
  330.  
  331. if (Length(Data) <= 1) or (Pos('<player>', Data) = 0) then
  332. begin
  333. Print('Corrupted army file, going to remove it');
  334. Print('Deleted = ' + BoolToStr(Settings.DeleteKey(ArmyName), 'Succesfull', 'Failed'));
  335. Exit();
  336. end;
  337.  
  338. TSA := MultiBetween(Data, '<player>', '</player>');
  339. SetLength(_Players, Length(TSA));
  340.  
  341. for i := 0 to High(_Players) do
  342. with _Players[i] do
  343. begin
  344. loginName := Between('<loginName>', '</loginName>', TSA[i]);
  345. nickName := Between('<nickName>', '</nickName>', TSA[i]);
  346. password := Between('<password>', '</password>', TSA[i]);
  347. bankPin := Between('<bankPin>', '</bankPin>', TSA[i]);
  348. isMember := StrToBoolDef(Between('<isMember>', '</isMember>', TSA[i]), False);
  349. end;
  350. finally
  351. Settings.setPrefix(Pref);
  352. end;
  353.  
  354. Result := (Length(_Players) > 0);
  355. Printf('Raf_GetPlayers: Result = %s', [toString(Result)], TDebug.FOOTER);
  356. end;
  357.  
  358. {*
  359. Raf_GetPlayers (overload)
  360. -------------------------
  361.  
  362. .. code-block:: pascal
  363.  
  364. function Raf_GetPlayers(const armyName: string; out __players: PF_TPlayerArray): boolean; overload;
  365.  
  366. As above, but returns the players as a PF_TPlayerArray. This is used to load
  367. an army inside the SRL Player Form.
  368.  
  369. .. note::
  370.  
  371. - by Olly
  372.  
  373. Example:
  374.  
  375. .. code-block:: pascal
  376.  
  377. *}
  378. function Raf_GetPlayers(const armyName: string; out __players: PF_TPlayerArray): boolean; overload;
  379. var
  380. tmp: TPlayerArray;
  381. i: integer;
  382. begin
  383. result := Raf_GetPlayers(armyName, tmp);
  384. setLength(__players, length(tmp));
  385.  
  386. for i := 0 to high(tmp) do
  387. with (__players[i]) do
  388. begin
  389. loginName := tmp[i].loginName;
  390. nickName := tmp[i].nickName;
  391. password := tmp[i].password;
  392. bankPin := tmp[i].bankPin;
  393. isMember := tmp[i].isMember;
  394. end;
  395. end;
  396.  
  397. {*
  398. __setDynamicInterfaces
  399. ~~~~~~~~~~~~~~~~~~~~~~
  400.  
  401. .. code-block:: pascal
  402.  
  403. procedure __setDynamicInterfaces();
  404.  
  405. Sets the dynamic interfaces upon login.
  406.  
  407. .. note::
  408.  
  409. - by Coh3n
  410. - Last updated: 22 December 2012 by Zyt3x
  411.  
  412. Example:
  413.  
  414. .. code-block:: pascal
  415.  
  416. __setDynamicInterfaces();
  417. *}
  418. {$IFNDEF CODEINSIGHT}
  419. procedure __setDynamicInterfaces();
  420. begin
  421. if actionBar.__find() then
  422. begin
  423. chatBox.__setup();
  424. mainScreen.__setup();
  425. metrics.__setup(); <--- ERROR HERE
  426.  
  427. __areDynamicInterfacesSet := true;
  428.  
  429. print('Dynamic interfaces have been set.', TDebug.SUB);
  430. end;
  431. end;
  432. {$ENDIF}
  433.  
  434. (*
  435. isLoggedIn
  436. ~~~~~~~~~~
  437.  
  438. .. code-block:: pascal
  439.  
  440. function isLoggedIn(): boolean;
  441.  
  442. Returns true if a player is logged in. It uses the top left corner of the logout
  443. button to return the result.
  444.  
  445. .. note::
  446.  
  447. - by Olly & Coh3n
  448. - Last updated: 11 August 2013 by Coh3n
  449.  
  450. Example:
  451.  
  452. .. code-block:: pascal
  453.  
  454. if isLoggedIn() then
  455. writeln('We are logged in!');
  456. *)
  457. function isLoggedIn(): boolean;
  458. const
  459. LOGOUT_BUTTON_COLOUR = 3446209;
  460. begin
  461. result := (getColor(796, 3) = LOGOUT_BUTTON_COLOUR);
  462.  
  463. if result and (not __areDynamicInterfacesSet) then
  464. __setDynamicInterfaces();
  465. end;
  466.  
  467. (*
  468. TPlayerArray methods
  469. ~~~~~~~~~~~~~~~~~~~~
  470.  
  471. The following methods should be called through the **players** variable.
  472.  
  473. Example:
  474.  
  475. .. code-block:: pascal
  476.  
  477. if players.getActive() >=1 then
  478. writeln('There is still active players');
  479. *)
  480.  
  481. (*
  482. getActive
  483. ---------
  484.  
  485. .. code-block:: pascal
  486.  
  487. function TPlayerArray.getActive(): integer;
  488.  
  489. Returns the number of players that are still active in the TPlayerArray.
  490.  
  491. .. note::
  492.  
  493. - by ss23 & Coh3n
  494. - Last updated: 22 December 2012 by Coh3n
  495.  
  496. Example:
  497.  
  498. .. code-block:: pascal
  499.  
  500. while (players.getActive() > 0) do
  501. mainloop();
  502. *)
  503. function TPlayerArray.getActive(): integer;
  504. var
  505. i: integer;
  506. begin
  507. for i := 0 to high(self) do
  508. if self[i].isActive then
  509. inc(result);
  510. end;
  511.  
  512. {*
  513. __add
  514. -----
  515.  
  516. .. code-block:: pascal
  517.  
  518. procedure TPlayerArray._add(info: TPlayer);
  519.  
  520. Adds the player with **info** to the TPlayerArray.
  521.  
  522. .. note::
  523.  
  524. - by Zyt3x & Coh3n
  525. - Last updated: 22 December 2012 by Coh3n
  526.  
  527. Example:
  528.  
  529. .. code-block:: pascal
  530.  
  531. var
  532. P: TPlayer;
  533. Players: TPlayerArray;
  534. begin
  535. P.loginName := 'example@example.com';
  536. P.password := 'examplepassword123';
  537. end;
  538.  
  539. Players._add(P);
  540. end;
  541. *}
  542. procedure TPlayerArray.__add(const info: TPlayer);
  543. begin
  544. setLength(self, length(self) + 1);
  545. self[high(self)] := info;
  546. end;
  547.  
  548. {*
  549. __setDefaults
  550. -------------
  551.  
  552. .. code-block:: pascal
  553.  
  554. procedure TPlayerArray.__setDefaults();
  555.  
  556. Initialises the main TPlayer variables for all players in the TPlayerArray
  557.  
  558. .. note::
  559.  
  560. - by Bart (masterBB)
  561. - Last updated: 4 April 2013 by Bart
  562.  
  563. Example:
  564.  
  565. .. code-block:: pascal
  566.  
  567. players.__setDefaults();
  568.  
  569. *}
  570. procedure TPlayerArray.__setDefaults();
  571. var
  572. i: integer;
  573. begin
  574. for i := 0 to high(self) do
  575. begin
  576. self[i].isActive := true;
  577. self[i].findMod := true;
  578. self[i].worked.name := 'Player '+toStr(i);
  579. self[i].worked.start();
  580. self[i].worked.pause();
  581. self[i].world := -1;
  582. end;
  583. end;
  584.  
  585. (*
  586. setup
  587. -----
  588.  
  589. .. code-block:: pascal
  590.  
  591. procedure TPlayerArray.setup(names: TStringArray; const army: string = 'default');
  592.  
  593. Sets up the TPlayerArray with the players **names** . It will look for the
  594. **names** in the army **army** *(default = 'default')* . This should be used if
  595. you are not using the SRLPlayerForm, and your players are setup in Rafiki.
  596.  
  597. .. note::
  598.  
  599. - by Bart (masterBB)
  600. - Last updated: 4 April 2013 by Bart
  601.  
  602. Example:
  603.  
  604. .. code-block:: pascal
  605.  
  606. players.setup(['woodcutter5', 'miner3', 'fisher6'], 'BartsArmy');
  607.  
  608. *)
  609. procedure TPlayerArray.setup(names: TStringArray; const army: string = 'default');
  610. var
  611. i, j: integer;
  612. tmp: TPlayerArray;
  613. begin
  614. print('TPlayerArray.setup()', TDebug.HEADER);
  615. printf('Attempting to load player(s) "%s" from army "%s"', [toString(names), army]);
  616.  
  617. if (not Raf_GetPlayers(army, tmp)) then
  618. begin
  619. print('Unable to get players from army', TDebug.ERROR);
  620. print('TPlayerArray.setup(): Failure', TDebug.FATAL);
  621. end;
  622.  
  623. for i := 0 to high(names) do
  624. for j := 0 to high(tmp) do
  625. begin
  626. if (names[i] = tmp[j].loginName) or (names[i] = tmp[j].displayName) or (names[i] = tmp[j].nickname) then
  627. begin
  628. print('Loaded player: '+names[i]);
  629. self.__add(tmp[j]);
  630. break;
  631. end;
  632.  
  633. if (j = high(tmp)) then
  634. print('Invalid player name: '+names[i], TDebug.WARNING);
  635. end;
  636.  
  637. if (length(players) < 1) then
  638. begin
  639. print('Unable to find any players in army', TDebug.ERROR);
  640. print('TPlayerArray.setup(): Failure', TDebug.FATAL);
  641. end;
  642.  
  643. self.__setDefaults();
  644. print('TPlayerArray.setup(): Success', TDebug.FOOTER);
  645. end;
  646.  
  647. (*
  648. setup (overload)
  649. ----------------
  650.  
  651. .. code-block:: pascal
  652.  
  653. procedure TPlayerArray.setup(const players: PF_TPlayerArray); overload;
  654.  
  655. Same as above, except the list of players is passed from the SRL Player Form.
  656.  
  657. .. note::
  658.  
  659. - by Olly
  660.  
  661. Example:
  662.  
  663. .. code-block:: pascal
  664.  
  665. players.setup(playerForm.players);
  666.  
  667. *)
  668. procedure TPlayerArray.setup(const players: PF_TPlayerArray); overload;
  669. var
  670. i: integer;
  671. p: TPlayer;
  672. begin
  673. for i := 0 to high(players) do
  674. begin
  675. p.loginName := players[i].loginName;
  676. p.nickName := players[i].nickName;
  677. p.password := players[i].password;
  678. p.bankPin := players[i].bankPin;
  679. p.isMember := players[i].isMember;
  680. self.__add(p);
  681. end;
  682. self.__setDefaults();
  683. end;
  684.  
  685. (*
  686. switchTo
  687. --------
  688.  
  689. .. code-block:: pascal
  690.  
  691. function TPlayerArray.switchTo(player: integer; active: boolean = true; login: boolean = true): boolean;
  692.  
  693. Switches to the **player** index in the TPlayerArray. Sets the previous player's
  694. activity to **active** *(default = true)* . It will login the new player if
  695. **login** is set to true *(default = true)* .
  696.  
  697. .. note::
  698.  
  699. - by Dankness, Ron, Raymond, ZephyrsFury & Coh3n
  700. - Last updated: 15 March 2015 by The Mayor
  701.  
  702. Example:
  703.  
  704. .. code-block:: pascal
  705.  
  706. players.switchTo(3);
  707. players.switchTo(3, false);
  708. players.switchTo(3, false, false); // To switch but not login
  709.  
  710. *)
  711. function TPlayerArray.switchTo(player: integer; active: boolean = true; login: boolean = true): boolean;
  712. begin
  713. self[currentPlayer].isActive := active;
  714. self[currentPlayer].logout();
  715.  
  716. if (self.getActive() <= 0) then
  717. begin
  718. print('All players inactive...', TDebug.SUB);
  719. exit(false);
  720. end;
  721.  
  722. print('Switching to player '+toStr(player)+' ('+self[player].nickname+')', TDebug.SUB);
  723. currentPlayer := player;
  724.  
  725. if (SRL_Events[EVENT_PLAYER_NEXT] <> nil) then
  726. SRL_Events[EVENT_PLAYER_NEXT]();
  727.  
  728. result := true;
  729. if login then result := self[currentPlayer].login()
  730. end;
  731.  
  732. (*
  733. next
  734. ----
  735.  
  736. .. code-block:: pascal
  737.  
  738. function TPlayerArray.next(active: boolean = true; login: boolean = true): boolean;
  739.  
  740. Switches to the next active player in the TPlayerArray. Sets the previous player's
  741. activity to **active** *(default = true)* . It will login the new player if
  742. **login** is set to true *(default = true)* .
  743.  
  744. .. note::
  745.  
  746. - by ZephyrsFury & Coh3n
  747. - Last updated: 15 March 2015 by The Mayor
  748.  
  749. Example:
  750.  
  751. .. code-block:: pascal
  752.  
  753. players.next();
  754. players.next(false);
  755. players.next(false, false);
  756.  
  757. *)
  758. function TPlayerArray.next(active: boolean = true; login: boolean = true): boolean;
  759. var
  760. nP: integer;
  761. begin
  762. nP := (currentPlayer + 1) mod length(self);
  763.  
  764. // get the next active player index
  765. while (not self[nP].isActive) do
  766. nP := (nP + 1) mod length(self);
  767.  
  768. result := self.switchTo(nP, active, login);
  769. end;
  770.  
  771. (*
  772. randomNext
  773. ----------
  774.  
  775. .. code-block:: pascal
  776.  
  777. function TPlayerArray.randomNext(active: boolean = true; login: boolean = true): boolean;
  778.  
  779. Switches to a random active player in the TPlayerArray. Sets the previous player's
  780. activity to **active** *(default = true)* . It will login the new player if
  781. **login** is set to true *(default = true)* .
  782.  
  783. .. note::
  784.  
  785. - by ZephyrsFury & Coh3n
  786. - Last updated: 15 March 2015 by The Mayor
  787.  
  788. Example:
  789.  
  790. .. code-block:: pascal
  791.  
  792. players.randomNext();
  793. players.randomNext(false);
  794. players.randomNext(false, false);
  795.  
  796. *)
  797. function TPlayerArray.randomNext(active: boolean = true; login: boolean = true): boolean;
  798. var
  799. nP: integer;
  800. begin
  801. nP := random(length(self));
  802.  
  803. // get an active random player index
  804. while (not self[nP].isActive) or (nP = currentPlayer) do
  805. begin
  806. if (self.getActive() = 1) and (nP = currentPlayer) then // if there's only 1 player left
  807. break;
  808.  
  809. nP := random(length(self));
  810. end;
  811.  
  812. result := self.switchTo(nP, active, login);
  813. end;
  814.  
  815. (*
  816. TPlayer methods
  817. ~~~~~~~~~~~~~~~
  818.  
  819. The following methods should be called through the **players** array, with the
  820. appropriate index *(normally currentPlayer)* .
  821.  
  822. Example:
  823.  
  824. .. code-block:: pascal
  825.  
  826. if players[currentPlayer].login() then
  827. writeln('We just logged in the player that is currently active');
  828. *)
  829.  
  830. (*
  831. write
  832. -----
  833.  
  834. .. code-block:: pascal
  835.  
  836. procedure TPlayer.write();
  837.  
  838. Writes the standard information about the player to the debug box.
  839.  
  840. .. note::
  841.  
  842. - by Coh3n
  843. - Last updated: 22 December 2012 by Zyt3x
  844.  
  845. Example:
  846.  
  847. .. code-block:: pascal
  848.  
  849. players[currentPlayer].write();
  850.  
  851. *)
  852. procedure TPlayer.write();
  853. begin
  854. print('TPlayer.write()', TDebug.HEADER);
  855.  
  856. print('Login Name: ' + self.loginName);
  857. print('Display Name: ' + self.displayName);
  858. print('Nickname: ' + self.nickname);
  859. print('Member: ' + toStr(self.isMember));
  860. print('Active: ' + toStr(self.isActive));
  861. print('Worked: ' + toStr(self.worked.getTime()));
  862. print('Total Worked: ' + toStr(self.worked.getTotalTime()));
  863.  
  864. print('TPlayer.write()', TDebug.FOOTER);
  865. end;
  866.  
  867. {*
  868. __setInputBoxes
  869. ---------------
  870.  
  871. .. code-block:: pascal
  872.  
  873. function __setInputBoxes(): boolean;
  874.  
  875. Finds and sets the username and password box parameters. Returns true if
  876. both boxes are found.
  877.  
  878. .. note::
  879.  
  880. - by Coh3n
  881. - Last updated: 3 January 2015 by The Mayor
  882.  
  883. Example:
  884.  
  885. .. code-block:: pascal
  886.  
  887. __setInputBoxes();
  888. *}
  889. {$IFNDEF CODEINSIGHT}
  890. function __setInputBoxes(): boolean;
  891. const
  892. __BORDER_LENGTH = 534;
  893. var
  894. tpaActive, tpaInactive: TPointArray;
  895. bdsActive, bdsInactive: TBox;
  896. begin
  897. findColors(tpaActive, 6774863, 247, 229, 547, 379); // active box border color
  898. findColors(tpaInactive, 6906451, 247, 229, 547, 379); // inactive box border color
  899.  
  900. if length(tpaActive) = 0 then
  901. findColors(tpaActive, 9867393, 247, 229, 547, 375); // active box border color when mouse is hovering
  902.  
  903. if length(tpaInactive) = 0 then
  904. findColors(tpaInactive, 9867393, 247, 229, 547, 375); // inactive box border color when mouse is hovering
  905.  
  906. if (length(tpaActive) = __BORDER_LENGTH) then
  907. begin
  908. result := true;
  909. print('__setInputBoxes(): Set username and password boxes', TDebug.SUB);
  910.  
  911. bdsActive := tpaActive.getBounds();
  912. bdsInactive := tpaInactive.getBounds();
  913.  
  914. // sets the username box as the box that's closer to the top of the screen
  915. if (bdsActive.y1 < bdsInactive.y1) then
  916. begin
  917. __boxUsername := bdsActive;
  918. __boxPassword := bdsInactive;
  919. end else
  920. begin
  921. __boxUsername := bdsInactive;
  922. __boxPassword := bdsActive;
  923. end;
  924. end;
  925. end;
  926. {$ENDIF}
  927.  
  928. {*
  929. __enterLoginInfo
  930. ----------------
  931.  
  932. .. code-block:: pascal
  933.  
  934. function __enterLoginInfo(const inputBox: TBox; const info: string; clickBox: boolean = true; pressEnter: boolean = true): boolean;
  935.  
  936. Types the player's info (username/password) into the input box. It can optionally
  937. click the box to make it active, and press enter after typing.
  938.  
  939. .. note::
  940.  
  941. - by The SRL Development Team
  942. - Last updated: 14 March 2015 by The Mayor
  943.  
  944. Example:
  945.  
  946. .. code-block:: pascal
  947.  
  948. __enterLoginInfo(__boxUsername, players[currentPlayer].loginName);
  949. *}
  950. {$IFNDEF CODEINSIGHT}
  951. function __enterLoginInfo(inputBox: TBox; const info: string; clickBox: boolean = true; pressEnter: boolean = true): boolean;
  952. var
  953. TPA: TPointArray;
  954. p: TPoint;
  955. c: integer;
  956. t : LongWord;
  957. begin
  958. t := (getSystemTime() + 30000);
  959. inputBox.offset(point(8, 0));
  960.  
  961. repeat
  962. if (isLoggedIn() or lobby.isOpen()) then exit(true);
  963.  
  964. if findColors(TPA, __LOGIN_COLOR_TEXT, inputBox) then
  965. begin
  966. sortTPAFrom(TPA, point(inputBox.x2, (inputBox.y1 + inputBox.y2 div 2)));
  967. p := point(TPA[0].x + 20, TPA[0].y);
  968.  
  969. if (not pointInBox(p, inputBox)) then
  970. p := point(inputBox.x2 - 12, p.y);
  971.  
  972. if clickBox or (not findColors(TPA, 6774863, inputBox)) then
  973. mouse(p.rand(3), MOUSE_LEFT);
  974. end else
  975. if findColors(TPA, 6774863, inputBox) or (not clickBox) then
  976. break()
  977. else
  978. mouseBox(inputBox, MOUSE_LEFT);
  979.  
  980. c := 0;
  981. while (countColor(__LOGIN_COLOR_TEXT, inputBox) > 0) and (c < 20) do
  982. begin
  983. inc(c);
  984. typeByte(VK_BACK);
  985. wait(50 + random(50));
  986. end;
  987.  
  988. until(getSystemTime() > t);
  989.  
  990. wait(100 + random(200));
  991. typeSend(info, pressEnter);
  992. result := true;
  993. end;
  994. {$ENDIF}
  995.  
  996. {*
  997. __respondToPopup
  998. ----------------
  999.  
  1000. .. code-block:: pascal
  1001.  
  1002. procedure TPlayer.__respondToPopup(errorMessage: TVariantArray; tries: integer; out reachedMax: boolean);
  1003.  
  1004. Internal procedure which responds to the login popup message. If the the max
  1005. number of attempts has been reached, it will perform the appropriate action
  1006. (action is index 3 of the passed errorMessage array). If not, it will wait
  1007. the appropriate amount time (time is index 1 of errorMessage array).
  1008.  
  1009. .. note::
  1010.  
  1011. - by The Mayor
  1012. - Last updated: 19 March 2015 by The Mayor
  1013.  
  1014. Example:
  1015.  
  1016. .. code-block:: pascal
  1017.  
  1018. *}
  1019. {$IFNDEF CODEINSIGHT}
  1020. procedure TPlayer.__respondToPopup(errorMessage: TVariantArray; tries: integer; out reachedMax: boolean);
  1021. begin
  1022. typeByte(VK_ESCAPE);
  1023.  
  1024. if (tries > errorMessage[2]) then
  1025. begin
  1026. print('Responding with action: ' + errorMessage[3], TDebug.SUB);
  1027.  
  1028. case errorMessage[3] of
  1029. 'Terminate': terminateScript();
  1030. 'Set_World': self.world := 0;
  1031.  
  1032. 'Next_Player_F':
  1033. begin
  1034. players.next(false, false);
  1035. self := players[currentPlayer];
  1036. end;
  1037.  
  1038. 'Next_Player_T':
  1039. begin
  1040. players.next(true, false);
  1041. self := players[currentPlayer];
  1042. end;
  1043.  
  1044. 'Set_Member':
  1045. begin
  1046. self.isMember := true;
  1047. self.world := 0;
  1048. end;
  1049.  
  1050. 'Set_Non-Member':
  1051. begin
  1052. self.isMember := false;
  1053. self.world := 0;
  1054. end;
  1055.  
  1056. 'Reload_Client':
  1057. begin
  1058. if (@SRL_Events[EVENT_RS_UPDATE] <> nil) then
  1059. begin
  1060. print('RS Update: Going to call EVENT_RS_UPDATE procedure', TDebug.WARNING);
  1061. SRL_Events[EVENT_RS_UPDATE]();
  1062. end;
  1063. end;
  1064. end;
  1065.  
  1066. if (players.getActive() < 1) then
  1067. print('No other active players, terminating script', TDebug.FATAL);
  1068.  
  1069. reachedMax := true;
  1070. end;
  1071.  
  1072. if (errorMessage[1] > 0) then
  1073. begin
  1074. print('Waiting ' + toStr(errorMessage[1]) + 'ms before next attempt', TDebug.SUB);
  1075. wait(errorMessage[1] + random(2000, 4000));
  1076. end;
  1077. end;
  1078. {$ENDIF}
  1079.  
  1080. {*
  1081. __getPopupMessage
  1082. -----------------
  1083.  
  1084. .. code-block:: pascal
  1085.  
  1086. function __getPopupMessage(): string;
  1087.  
  1088. Internal function which looks for the login popup box. If found, it will isolate
  1089. the message text, and return it as the result.
  1090.  
  1091. .. note::
  1092.  
  1093. - by The Mayor
  1094. - Last updated: 15 March 2015 by The Mayor
  1095.  
  1096. Example:
  1097.  
  1098. .. code-block:: pascal
  1099.  
  1100. *}
  1101. {$IFNDEF CODEINSIGHT}
  1102. function __getPopupMessage(): string;
  1103. var
  1104. TPA: TPointArray;
  1105. ATPA: T2DPointArray;
  1106. b: TBox;
  1107. yDiff: integer;
  1108. begin
  1109. if findColorsTolerance(TPA, 3286022, getClientBounds(), 12) then
  1110. if (length(TPA) > 1000) then
  1111. begin
  1112. ATPA := TPA.cluster(8);
  1113. ATPA.filterBetween(1, 1000);
  1114. if (length(ATPA) < 1) then exit();
  1115. ATPA.sortBySize(true);
  1116.  
  1117. b := ATPA[0].getBounds();
  1118.  
  1119. if findColorsTolerance(TPA, 16504921, b, 30) then
  1120. begin
  1121. yDiff := b.Y2 - TPA.getBounds().Y1; // Limit Y2 to the top of the blue buttons
  1122. b.edit(7, 85, -7, -yDiff);
  1123.  
  1124. if inRange(b.getWidth(), 200, 260) and (b.getHeight() > 24) then
  1125. result := trim(tesseract_GetText(b, TESS_FILTER_SMALL_CHARS_2));
  1126. end;
  1127. end;
  1128. end;
  1129. {$ENDIF}
  1130.  
  1131. // Temp procedure to close the NXT reminder (by Thomas) fixed 12th April 17
  1132. procedure __nxtReminder();
  1133. var
  1134. b: TBox;
  1135. p: TPoint;
  1136. TPA: TPointArray;
  1137. ATPA: T2DPointArray;
  1138. button_color: TColorData := [1087209, 19, [2, [0.12, 0.54, 0.00]]];
  1139. begin
  1140. button_color.gatherIn(TPA, getClientBounds());
  1141. ATPA := TPA.cluster(1);
  1142. if length(ATPA) then
  1143. begin
  1144. ATPA.sortBySize();
  1145. writeLn(length(ATPA[0]));
  1146. if inRange(length(ATPA[0]), 2000, 2500) then
  1147. begin
  1148. b := ATPA[0].getBounds();
  1149. p := ATPA[0].getMiddle();
  1150. if inRange(b.getWidth(), 100, 200) and inRange(b.getHeight(), 10, 30) then
  1151. mouse(point(p.x + randomRange( - 25, 25), p.y + 30), MOUSE_LEFT);
  1152. end;
  1153. end
  1154. end;
  1155.  
  1156. {*
  1157. __handleLoginPopup
  1158. ------------------
  1159.  
  1160. .. code-block:: pascal
  1161.  
  1162. function TPlayer.__handleLoginPopup(tries: integer; inLobby: boolean; out reachedMax: boolean): boolean;
  1163.  
  1164. Waits for the login popup message to appear (or logged in successfully). If a
  1165. popup message is found, it will pass the details array to __respondToPopup();
  1166. The inLobby boolean should be true if it is handling popups from the lobby.
  1167.  
  1168. .. note::
  1169.  
  1170. - by The Mayor
  1171. - Last updated: 23 March 2015 by The Mayor
  1172.  
  1173. Example:
  1174.  
  1175. .. code-block:: pascal
  1176.  
  1177. *}
  1178. {$IFNDEF CODEINSIGHT}
  1179. function TPlayer.__handleLoginPopup(tries: integer; inLobby: boolean; out reachedMax: boolean): boolean;
  1180. var
  1181. p: TPoint;
  1182. i: integer;
  1183. timeOut: TTimeMarker;
  1184. popupMessage: string;
  1185. errorMessage: TVariantArray;
  1186. messages: array [0..17] of TVariantArray;
  1187. begin
  1188. timeOut.start();
  1189.  
  1190. repeat // Wait until the popup appears, or we hit the lobby/isLoggedIn
  1191. case inLobby of
  1192. true: if isLoggedIn() then exit(true);
  1193. false: if (lobby.isOpen() or isLoggedIn()) then exit(true);
  1194. end;
  1195.  
  1196. popupMessage := __getPopupMessage();
  1197.  
  1198. if (timeOut.getTime() > 60000) then
  1199. begin
  1200. print('Took too long to find login popup or login - respawning SMART');
  1201. popupMessage := 'session has now ended'; // Trick it to reload
  1202. end;
  1203.  
  1204. if (timeOut.getTime() > 15000) then // If nothing after 15s, check we actually
  1205. case inLobby of // clicked the Login button
  1206. true: if lobby.findPlayButton(p) then exit(false);
  1207. false: if __setInputBoxes() then exit(false);
  1208. end;
  1209.  
  1210. __nxtReminder();
  1211.  
  1212. wait(random(500, 750));
  1213. until (length(popupMessage) > 0);
  1214.  
  1215. messages := [
  1216. {Popup Text Wait time MaxTries Action}
  1217. ['Unknown login popup', 0, 2, 'Next_Player_F'],
  1218. ['Invalid username or password', 0, 2, 'Next_Player_F'],
  1219. ['Your account has been disabled', 0, 0, 'Next_Player_F'],
  1220. ['Your ban will be lifted in', 0, 0, 'Next_Player_F'],
  1221. ['Your account has been involved in', 0, 0, 'Next_Player_F'],
  1222. ['Too many incorrect logins', 5 * 60000, 2, 'Next_Player_F'],
  1223. ['Your account has not logged out', 15000, 5, 'Next_Player_T'],
  1224. ['You need a member''s account', 0, 1, 'Set_Non-Member'],
  1225. ['Player in member-only area', 0, 0, 'Set_Member'],
  1226. ['Error connecting', 20000, 4, 'Terminate'],
  1227. ['Unable to connect', 20000, 4, 'Terminate'],
  1228. ['Runescape has been updated', 0, 0, 'Reload_Client'],
  1229. ['Client token changed', 0, 0, 'Reload_Client'],
  1230. ['session has now ended', 0, 0, 'Reload_Client'],
  1231. ['Our systems are currently unavailable', 3 * 60000, 8, 'Reload_Client'],
  1232. ['Login limit exceeded', 20000, 8, 'Set_World'],
  1233. ['You must have a total skill level of', 0, 0, 'Set_World'],
  1234. ['Cannot connect to world', 10000, 0, 'Set_World']];
  1235.  
  1236. for i := 0 to high(messages) do
  1237. if (pos(messages[i][0], popupMessage) > 0) then
  1238. begin
  1239. errorMessage := messages[i];
  1240. print('Login message: ' + errorMessage[0], TDebug.SUB);
  1241. break();
  1242. end;
  1243.  
  1244. if length(errorMessage) < 1 then
  1245. begin
  1246. print('Unknown login popup message: ' + popupMessage, TDebug.WARNING);
  1247. takeScreenshot('unknown_login_popup.png');
  1248. print('PLEASE report this in the SRL-6 bugs section: https://villavu.com/forum/project.php?projectid=10', TDebug.HINT);
  1249. errorMessage := ['Unknown login popup', 0, 3, 'Next_Player_F'];
  1250. end;
  1251.  
  1252. self.__respondToPopup(errorMessage, tries, reachedMax);
  1253. end;
  1254. {$ENDIF}
  1255.  
  1256.  
  1257. (*
  1258. loginToLobby
  1259. ------------
  1260.  
  1261. .. code-block:: pascal
  1262.  
  1263. function TPlayer.loginToLobby(): boolean;
  1264.  
  1265. Logs the TPlayer into to the lobby. Returns true when the lobby screen is
  1266. visible.
  1267.  
  1268. .. note::
  1269.  
  1270. - by The SRL Developers Team
  1271. - Last updated: 23 May 2015 by The Mayor
  1272.  
  1273. Example:
  1274.  
  1275. .. code-block:: pascal
  1276.  
  1277. players[currentPlayer].loginToLobby();
  1278. *)
  1279. function TPlayer.loginToLobby(): boolean;
  1280. var
  1281. tries: integer = 1;
  1282. reachedMaxTries: boolean;
  1283. begin
  1284. print('TPlayer.loginToLobby(): ', TDebug.HEADER);
  1285. __areDynamicInterfacesSet := false;
  1286.  
  1287. if (not self.isActive) then
  1288. begin
  1289. print('TPlayer.loginToLobby(): Player ' + self.nickname + ' is not active...', TDebug.FOOTER);
  1290. exit(false);
  1291. end;
  1292.  
  1293. if lobby.isOpen() then
  1294. begin
  1295. print('TPlayer.loginToLobby(): Player ' + self.nickname + ' is already in lobby.', TDebug.FOOTER);
  1296. exit(true);
  1297. end;
  1298.  
  1299. if (not __setInputBoxes()) then
  1300. begin
  1301. print('TPlayer.loginToLobby(): Failed to find username and/or password box', TDebug.FOOTER);
  1302. exit(false);
  1303. end;
  1304.  
  1305. repeat
  1306. if (isLoggedIn() or lobby.isOpen()) then
  1307. begin
  1308. result := true;
  1309. break;
  1310. end;
  1311.  
  1312. print('Login Attempt ' + toStr(tries) + ': ' + capitalize(self.loginName) + ' (' + capitalize(self.displayName) + ')');
  1313.  
  1314. print('Entering username...', TDebug.SUB);
  1315. __enterLoginInfo(__boxUsername, self.loginName, true, true);
  1316. wait(500 + random(200));
  1317.  
  1318. print('Entering password...', TDebug.SUB);
  1319. __enterLoginInfo(__boxPassword, self.password, false, true);
  1320. wait(800 + random(300));
  1321.  
  1322. result := self.__handleLoginPopup(inc(tries), false, reachedMaxTries);
  1323.  
  1324. if reachedMaxTries then tries := 1; //'reachedMaxTries' is passed down from __respondToPopup()
  1325. until result;
  1326.  
  1327. if (not disableIPScreenshots) then takeScreenshot('IP_address.png');
  1328.  
  1329. print('TPlayer.loginToLobby(): ' + toStr(result), TDebug.FOOTER);
  1330. end;
  1331.  
  1332. (*
  1333. login
  1334. -----
  1335.  
  1336. .. code-block:: pascal
  1337.  
  1338. function TPlayer.login(): boolean;
  1339.  
  1340. Returns true if the TPlayer is logged in to the game. Works from both the login
  1341. screen and the lobby.
  1342.  
  1343. .. note::
  1344.  
  1345. - by The SRL Developers Team
  1346. - Last updated: 19 March 2015 by The Mayor
  1347.  
  1348. Example:
  1349.  
  1350. .. code-block:: pascal
  1351.  
  1352. players[currentPlayer].login();
  1353. *)
  1354. function TPlayer.login(): boolean;
  1355. var
  1356. tries: integer;
  1357. p: TPoint;
  1358. skipPlay, reachedMaxTries: boolean;
  1359. begin
  1360. print('TPlayer.login()', TDebug.HEADER);
  1361.  
  1362. repeat
  1363. if isLoggedIn() then
  1364. begin
  1365. print('Already logged in');
  1366. result := true;
  1367. break;
  1368. end;
  1369.  
  1370. if self.loginToLobby() then
  1371. begin
  1372. if (self.world <> -1) then
  1373. if (self.world = 0) then
  1374. lobbyWorlds.selectRandomWorld(self.isMember)
  1375. else if lobby.quickSelectWorld(self.world) then
  1376. skipPlay := true
  1377. else
  1378. lobbyWorlds.selectWorld(self.world);
  1379.  
  1380. if (not skipPlay) then
  1381. begin
  1382. lobby.findPlayButton(p);
  1383. mouse(p.rand(randomRange(-50, 50), randomRange(-10, 10)), MOUSE_LEFT);
  1384. end;
  1385.  
  1386. result := self.__handleLoginPopup(inc(tries), true, reachedMaxTries);
  1387.  
  1388. if reachedMaxTries then tries := 1;
  1389. end;
  1390.  
  1391. until result;
  1392.  
  1393. if self.worked.paused then
  1394. self.worked.start();
  1395.  
  1396. if (SRL_Events[EVENT_LOGIN] <> nil) then
  1397. SRL_Events[EVENT_LOGIN]();
  1398.  
  1399. print('TPlayer.login(): ' + toStr(result), TDebug.FOOTER);
  1400. end;
  1401.  
  1402. (*
  1403. logout
  1404. ------
  1405.  
  1406. .. code-block:: pascal
  1407.  
  1408. function TPlayer.logout(): boolean;
  1409.  
  1410. Returns true if the TPlayer is logged out to the login screen
  1411.  
  1412. .. note::
  1413.  
  1414. - by Coh3n
  1415. - Last updated: 23 July 2013 by Coh3n
  1416.  
  1417. Example:
  1418.  
  1419. .. code-block:: pascal
  1420.  
  1421. players[currentPlayer].logout();
  1422. *)
  1423. function TPlayer.logout(): boolean;
  1424. var
  1425. t: LongWord;
  1426. p: TPoint;
  1427. begin
  1428. if (not isLoggedIn()) then
  1429. exit(true);
  1430.  
  1431. print('TPlayer.logout()', TDebug.HEADER);
  1432.  
  1433. if (SRL_Events[EVENT_LOGOUT] <> nil) then
  1434. begin
  1435. print('Calling SRL logout event');
  1436. SRL_Events[EVENT_LOGOUT]();
  1437. end;
  1438.  
  1439. if options.open() then
  1440. begin
  1441. options.selectOption(['Logout', 'ogout', 'gout']);
  1442.  
  1443. t := (getSystemTime() + (7000));
  1444.  
  1445. repeat
  1446. print('Waiting for login screen...');
  1447. result := (not isLoggedIn());
  1448. wait(700 + random(500));
  1449. until result or (getSystemTime() > t);
  1450.  
  1451. self.worked.pause();
  1452. end else
  1453. print('Failed to click logout text', TDebug.ERROR);
  1454.  
  1455. print('TPlayer.logout(): ' + toStr(result), TDebug.FOOTER);
  1456. end;
  1457.  
  1458. (*
  1459. exitToLobby
  1460. -----------
  1461.  
  1462. .. code-block:: pascal
  1463.  
  1464. function TPlayer.exitToLobby(): boolean;
  1465.  
  1466. Returns true if the TPlayer is logged out to the lobby
  1467.  
  1468. .. note::
  1469.  
  1470. - by Coh3n
  1471. - Last updated: 14 March 2015 by The Mayor
  1472.  
  1473. Example:
  1474.  
  1475. .. code-block:: pascal
  1476.  
  1477. players[currentPlayer].exitToLobby();
  1478. *)
  1479. function TPlayer.exitToLobby(): boolean;
  1480. begin
  1481. result := lobby._open();
  1482. end;
  1483.  
  1484. (*
  1485. leaveLobby
  1486. ----------
  1487.  
  1488. .. code-block:: pascal
  1489.  
  1490. function TPlayer.leaveLobby(): boolean;
  1491.  
  1492. Returns true if it returns to the login screen from the lobby.
  1493.  
  1494. .. note::
  1495.  
  1496. - by Coh3n
  1497. - Last updated: 3 March 2013 by Coh3n
  1498.  
  1499. Example:
  1500.  
  1501. .. code-block:: pascal
  1502.  
  1503. players[currentPlayer].leaveLobby();
  1504. *)
  1505. function TPlayer.leaveLobby(): boolean;
  1506. begin
  1507. result := lobby._leave();
  1508. end;
  1509.  
  1510. (*
  1511. switchToWorld
  1512. -------------
  1513.  
  1514. .. code-block:: pascal
  1515.  
  1516. function TPlayer.switchToWorld(newWorld: integer = 0): boolean;
  1517.  
  1518. Returns true if it switches the TPlayer to the worls **newWorld**
  1519. *(default = 0; random world)*
  1520.  
  1521.  
  1522. .. note::
  1523.  
  1524. - by Coh3n
  1525. - Last updated: 22 June 2013 by Coh3n
  1526.  
  1527. Example:
  1528.  
  1529. .. code-block:: pascal
  1530.  
  1531. players[currentPlayer].switchToWorld();
  1532. players[currentPlayer].switchToWorld(115);
  1533. *)
  1534. function TPlayer.switchToWorld(newWorld: integer = 0): boolean;
  1535. begin
  1536. result := false;
  1537.  
  1538. print('Switching to world ' + toStr(newWorld), TDebug.SUB);
  1539.  
  1540. if self.exitToLobby() then
  1541. begin
  1542. self.world := -1;
  1543.  
  1544. if (newWorld = 0) then
  1545. result := lobbyWorlds.selectRandomWorld(self.isMember)
  1546. else
  1547. result := lobbyWorlds.selectWorld(newWorld);
  1548.  
  1549. if result then
  1550. result := self.login();
  1551. end;
  1552. end;
  1553.  
  1554. {$f+}
Add Comment
Please, Sign In to add comment