Advertisement
arna

wait4Party.pl

Oct 15th, 2012
1,579
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.96 KB | None | 0 0
  1. ########################################
  2. # Wait4Party v1.5 rev a -- Stick Together Team!
  3. # ©2008 by Contrad
  4. #
  5. # This software is open source, licensed under the GNU General Public
  6. # License, version 3.
  7. # Basically, this means that you're allowed to modify and/or distribute
  8. # this software. However, if you distribute modified versions, you MUST
  9. # also distribute the source code.
  10. # See <http://www.gnu.org/licenses/> for the full license.
  11. #
  12. # How to use :
  13. # <config.txt>
  14. # wait4party (<boolean flag>)
  15. # Wait4Party On or Off
  16. #
  17. # wait4party_sameMapOnly (<boolean flag>)
  18. # Only activate if the party member are in the same map
  19. #
  20. # wait4party_waitBySitting (<boolean flag>)
  21. # Don't search, just sit and wait
  22. #
  23. # wait4party_attackOnSearch (0|1|2)
  24. # 0 = No; 1 = Retaliate; 2 = Yes
  25. # Attacking monster when searching member
  26. #
  27. # wait4party_followSit (<boolean flag>)
  28. # Sitting when party is sitting. ATTENTION! Turn OFF 'followSitAuto' on slave or they'll sit forever!
  29. #
  30. # Jan 5, 2010 ~ Blackmail
  31. # use AI_pre hooks ^^
  32. # Add Features:
  33. # wait4party_ignore [<player names>]
  34. # ignore (comma-separated list of) player names if you lost them.
  35. #
  36. # wait4party_timeout [<seconds>]
  37. # If timeout is exceeded and party doesn't appear on screen, master will search for the missing party.
  38. #
  39. # wait4party_cast [<skills>]
  40. # Wait if party cast (comma-separated list of) skills.
  41. #
  42. # Sep 11, 2010 : add sub emulateCmdSit, fix wait4party_followSit
  43. # Oct 22, 2010 : change %field into $field
  44. ##
  45.  
  46. package wait4party;
  47.  
  48. use strict;
  49. # use warnings;
  50. # use Data::Dumper;
  51.  
  52. use Plugins;
  53. use Globals qw(%config @partyUsersID $playersList $accountID $char $field %ai_v @ai_seq @ai_seq_args %timeout $taskManager);
  54. use Utils qw(distance timeOut);
  55. use Utils::DataStructures qw(existsInList);
  56. use Log qw(message warning error debug);
  57. use Translation qw/T TF/;
  58.  
  59. use constant { NAME => 'wait4party' };
  60.  
  61. my %findParty;
  62. my %partySit;
  63. my @notAI = qw(storageAuto storageGet sellAuto buyAuto attack skill_use);
  64.  
  65. Plugins::register( NAME, 'Wait for party', \&unload, \&unload);
  66. my $hooks = Plugins::addHooks(
  67. ['AI_pre', \&waitForOthers, undef],
  68. ['is_casting', \&waitCast, undef]);
  69.  
  70. sub unload {
  71. Plugins::delHooks($hooks);
  72. undef %findParty;
  73. undef %partySit;
  74. undef @notAI;
  75. }
  76.  
  77. sub waitForOthers {
  78. return unless ($config{'wait4party'} && @partyUsersID);
  79.  
  80. my $actor;
  81. foreach (@partyUsersID) {
  82. next if (!$_ || $_ eq $accountID
  83. || ($config{'wait4party_ignore'} && existsInList("$config{'wait4party_ignore'}", "$char->{'party'}{'users'}{$_}{'name'}"))
  84. || ($findParty{ID} && $findParty{ID} ne $_)); # first lost first served
  85. $actor = $playersList->getByID($_);
  86.  
  87. # PARTY MISSING!!
  88. if(!$actor && $char->{'party'}{'users'}{$_}{'online'}) {
  89. # party Check
  90. my %party;
  91. $party{x} = $char->{party}{users}{$_}{pos}{x};
  92. $party{y} = $char->{party}{users}{$_}{pos}{y};
  93. ($party{map}) = $char->{party}{users}{$_}{map} =~ /([\s\S]*)\.gat/;
  94.  
  95. if ($party{map} ne $field->baseName() || !$party{'x'} || !$party{'y'}
  96. || ($party{'x'} == 0) || ($party{'y'} == 0)) {
  97. next if $config{'wait4party_sameMapOnly'};
  98. return unless timeOut($timeout{ai}{time},5);
  99.  
  100. delete $party{x};
  101. delete $party{y};
  102. }
  103.  
  104. next unless ($party{map} ne $field->baseName || exists $party{x});
  105.  
  106. # set %findParty when party dissappear from screen
  107. if (!$findParty{ID}) {
  108. $findParty{ID} = $_;
  109. $findParty{time} = time if !$findParty{time};
  110. $findParty{timeout} = $config{'wait4party_timeout'} if ($config{'wait4party_timeout'});
  111.  
  112. if ($config{'wait4party_waitBySitting'}) {
  113. message ("Party (".$char->{party}{users}{$_}{name}.") lost, wait by sitting.\n", "wait4party");
  114. } else {
  115. message ("Party (".$char->{party}{users}{$_}{name}.") lost.\n", "wait4party");
  116. }
  117.  
  118. }
  119.  
  120. # notAI
  121. return if AI::inQueue(@notAI);
  122. if ($config{'wait4party_waitBySitting'}) {
  123. emulateCmdSit() if (!$char->{sitting});
  124. return if (!$findParty{timeout}); # wait by sit forever..
  125. }
  126. return if ($findParty{timeout} && !timeOut(\%findParty));
  127.  
  128. # Search for Party
  129. if ((exists $ai_v{party} && distance(\%party, $ai_v{party}) > $config{followDistanceMax})
  130. || ($party{map} ne $ai_v{party}{map})
  131. || ($ai_v{party}{time} && timeOut($ai_v{party}{time}, 15) && distance(\%party, $char->{pos_to}) > $config{followDistanceMax})) {
  132. $ai_v{party}{x} = $party{x};
  133. $ai_v{party}{y} = $party{y};
  134. $ai_v{party}{map} = $party{map};
  135. $ai_v{party}{time} = time;
  136.  
  137. if ($ai_v{party}{map} ne $field->baseName) {
  138. message TF("Calculating route to find %s: %s\n", $char->{party}{users}{$_}{name}, $ai_v{party}{map}), NAME;
  139. } elsif (distance(\%party, $char->{pos_to}) > $config{followDistanceMax} ) {
  140. message TF("Calculating route to find %s: %s (%d %d)\n", $char->{party}{users}{$_}{name}, $ai_v{party}{map}, $ai_v{party}{x}, $ai_v{party}{y}), NAME;
  141. } else {
  142. return;
  143. }
  144.  
  145. AI::clear("move", "route", "mapRoute");
  146. AI::ai_route($ai_v{party}{map}, $ai_v{party}{x}, $ai_v{party}{y}, distFromGoal => $config{followDistanceMin}, attackOnRoute => $config{'wait4party_attackOnSearch'});
  147. return;
  148. }
  149.  
  150. # party found
  151. } elsif ($findParty{ID} eq $_) {
  152. %findParty = (); ## undef findParty!!
  153. if (!$char->{'party'}{'users'}{$_}{'online'}) {
  154. message TF("Party member %s is offline\n", $char->{party}{users}{$_}{name}), NAME;
  155. AI::clear("route");
  156. return;
  157. }
  158. Commands::cmdStand() if ($char->{sitting} && !$partySit{ID});
  159. message TF("Party member %s found!\n", $char->{party}{users}{$_}{name}), NAME;
  160.  
  161. ## party sit?
  162. } elsif ($actor && $config{'wait4party_followSit'} && !(AI::inQueue(@notAI)) && AI::action ne "sitAuto") {
  163. # Salah trigger??
  164. if ($actor->{sitting} && !$partySit{ID}) {
  165. emulateCmdSit() if (!$char->{sitting});
  166. message TF ("Party member %s sit\n", $actor->{name}), NAME;
  167. %partySit = ( 'ID' => $actor->{ID}, 'time' => time, 'timeout' => 10 );
  168.  
  169. } elsif ($partySit{ID} && $actor->{ID} eq $partySit{ID} && timeOut(\%partySit)) {
  170. if ($actor->{sitting}) {
  171. emulateCmdSit() if (!$char->{sitting});
  172. $partySit{'time'} = time;
  173. $partySit{'timeout'} = 5;
  174.  
  175. } elsif (!$actor->{sitting}) {
  176. Commands::cmdStand();
  177. message TF("Party member %s stand\n", $actor->{name}), NAME;
  178. %partySit = ();
  179. return;
  180. }
  181.  
  182. if (!$char->{'party'}{'users'}{$_}{'online'}) {
  183. Commands::cmdStand();
  184. message TF("Party member %s is offline\n", $actor->{name}), NAME;
  185. %partySit = ();
  186. return;
  187. }
  188. }
  189. }
  190. }
  191. return;
  192. }
  193.  
  194. sub waitCast {
  195. return unless ($config{'wait4party'}
  196. && $config{'wait4party_cast'}
  197. && @partyUsersID
  198. && AI::action eq "route" && !AI::inQueue("attack"));
  199.  
  200. my (undef,$actor) = @_;
  201. return unless existsInList($config{'wait4party_cast'}, $actor->{skill}->getName());
  202.  
  203. foreach (@partyUsersID) {
  204. next if (!$_ || $_ ne $actor->{sourceID} || $_ eq $accountID
  205. || ($config{'wait4party_ignore'} && existsInList("$config{'wait4party_ignore'}", "$char->{'party'}{'users'}{$_}{'name'}")));
  206. my $wait = int($actor->{castTime} * 0.001 + 1) + 1;
  207. message TF("Party member %s is casting %s, wait %d seconds\n",
  208. $char->{party}{users}{$_}{name}, $actor->{skill}->getName(), $wait), NAME;
  209.  
  210. # can't find better idea to suspend AI other than this
  211. AI::clear("clientSuspend");
  212. AI::ai_clientSuspend(0, $wait);
  213. return;
  214. }
  215. }
  216.  
  217. # Note:
  218. # Copied from Commands::cmdSit
  219. # change AI::ai_getAggresives() to AI::ai_getAggressives(1,1) -> react for party aggressive monster?
  220. sub emulateCmdSit {
  221. $ai_v{sitAuto_forcedBySitCommand} = 1;
  222. AI::clear("move", "route", "mapRoute");
  223. AI::clear("attack") unless AI::ai_getAggressives(1,1);
  224. require Task::SitStand;
  225. my $task = new Task::ErrorReport(
  226. task => new Task::SitStand(
  227. mode => 'sit',
  228. priority => Task::USER_PRIORITY
  229. )
  230. );
  231. $taskManager->add($task);
  232. $ai_v{sitAuto_forceStop} = 0;
  233. }
  234.  
  235. 1;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement