Advertisement
Guest User

Untitled

a guest
Jun 13th, 2011
445
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.30 KB | None | 0 0
  1. package freeCast;
  2.  
  3. # This plugin is licensed under the GNU GPL
  4. # Copyright 2008 by DInvalid
  5. # Portions Copyright 2005 by kaliwanagan
  6. # --------------------------------------------------
  7. # Experimental! Use on your own risk!
  8. # How to install this thing..:
  9. #
  10. # The plugin will activate if:
  11. # you have the skill free cast at level 1 or higher, and
  12. # config is set:
  13. # runFromTargetFree 1
  14. # runFromTargetFree_min 7
  15. # runFromTargetFree_mid 9
  16. # runFromTargetFree_max 12
  17. #
  18.  
  19. use strict;
  20. use Plugins;
  21. use Globals;
  22. use Translation qw(T TF);
  23. use Log qw(message warning error);
  24. use AI;
  25. use skill;
  26. use Misc;
  27. use Network;
  28. use Network::Send;
  29. use Utils;
  30. use Math::Trig;
  31. use Utils::Benchmark;
  32. use Utils::PathFinding;
  33.  
  34.  
  35. Plugins::register('Free Cast', 'experimental sage free cast support', \&Unload);
  36. my $hook1 = Plugins::addHook('AI_post', \&call);
  37. my $ID;
  38. my $target;
  39. my %timeout;
  40. my ($myPos, $monsterPos,$monsterDist);
  41.  
  42. ##
  43. # round($number)
  44. #
  45. # Returns the rounded number
  46. sub round {
  47. my($number) = shift;
  48. return int($number + .5 * ($number <=> 0));
  49. }
  50.  
  51.  
  52. sub Unload {
  53. Plugins::delHook('AI_post', $hook1);
  54. }
  55.  
  56. sub call {
  57. my $i = AI::findAction("attack");
  58. if (defined $i) {
  59. my $args = AI::args($i);
  60. $ID = $args->{ID};
  61. $target = Actor::get($ID);
  62. $myPos = $char->{pos_to};
  63. $monsterPos = $target->{pos_to};
  64. $monsterDist = round(distance($myPos, $monsterPos));
  65.  
  66.  
  67. }
  68. if (AI::action eq "skill_use") {
  69. my $args = AI::args(AI::action);
  70. my $s = $args->{skillHandle};
  71. if ($s eq "MG_FIREBOLT" || $s eq "MG_COLDBOLT" || $s eq "MG_LIGHTNINGBOLT" || $s eq "MG_THUNDERSTORM") {
  72. cast();
  73. }
  74. }
  75. }
  76.  
  77. sub cast {
  78. if (($char->{skills}{SA_FREECAST}{lv}) && main::timeOut(\%timeout)){
  79.  
  80. #message "Cast!\n";
  81. my ($realMyPos, $realMonsterPos, $realMonsterDist, $hitYou);
  82. my $realMyPos = calcPosition($char);
  83. my $realMonsterPos = calcPosition($target);
  84. my $realMonsterDist = round(distance($realMyPos, $realMonsterPos));
  85.  
  86. $myPos = $realMyPos;
  87. $monsterPos = $realMonsterPos;
  88. $hitYou = 0;
  89.  
  90. if ($config{'runFromTargetFree'} && ($realMonsterDist < $config{'runFromTargetFree_min'})) {
  91. #my $begin = time;
  92. my @blocks = calcRectArea($myPos->{x}, $myPos->{y},$config{'runFromTargetFree_mid'});
  93.  
  94. my $highest;
  95. foreach (@blocks) {
  96. my $dist = ord(substr($field->{dstMap}, $_->{y} * $field->{width} + $_->{x}));
  97. if (!defined $highest || $dist > $highest) {
  98. $highest = $dist;
  99. }
  100. }
  101. my $pathfinding = new PathFinding;
  102. use constant AVOID_WALLS => 4;
  103. for (my $i = 0; $i < @blocks; $i++) {
  104. # We want to avoid walls (so we don't get cornered), if possible
  105. my $dist = ord(substr($field->{dstMap}, $blocks[$i]{y} * $field->{width} + $blocks[$i]{x}));
  106. if ($highest >= AVOID_WALLS && $dist < AVOID_WALLS) {
  107. delete $blocks[$i];
  108. next;
  109. }
  110.  
  111. $pathfinding->reset(
  112. field => $field,
  113. start => $myPos,
  114. dest => $blocks[$i]);
  115. my $ret = $pathfinding->runcount;
  116. if ($ret <= 0 || $ret > $config{'runFromTargetFree_min'} * 2) {
  117. delete $blocks[$i];
  118. next;
  119. }
  120.  
  121. delete $blocks[$i] unless (checkLineSnipable($blocks[$i], $realMonsterPos) || checkLineWalkable($blocks[$i], $realMonsterPos));
  122. }
  123.  
  124. my $largestDist;
  125. my $best_spot;
  126. foreach (@blocks) {
  127. next unless defined $_;
  128. my $dist = distance($monsterPos, $_);
  129. if (!defined $largestDist || $dist > $largestDist) {
  130. $largestDist = $dist;
  131. $best_spot = $_;
  132. }
  133. }
  134.  
  135. $char->move($best_spot->{x}, $best_spot->{y}, $ID) if ($best_spot);
  136.  
  137. } elsif ($config{'runFromTargetFree'} && ($realMonsterDist > $config{'runFromTargetFree_max'})) {
  138. my $radius = $config{runFromTargetFree_max}-1;
  139. my @blocks = calcRectArea2($realMonsterPos->{x}, $realMonsterPos->{y},
  140. $radius,
  141. $config{runFromTargetFree_mid});
  142.  
  143. my $best_spot;
  144. my $best_dist;
  145. for my $spot (@blocks) {
  146. if (
  147. (($config{attackCanSnipe} && checkLineSnipable($spot, $realMonsterPos)) || checkLineWalkable($spot, $realMonsterPos))
  148. && $field->isWalkable($spot->{x}, $spot->{y})
  149. ) {
  150. my $dist = distance($realMyPos, $spot);
  151. if (!defined($best_dist) || $dist < $best_dist) {
  152. $best_dist = $dist;
  153. $best_spot = $spot;
  154. }
  155. }
  156. }
  157.  
  158. $char->move($best_spot->{x}, $best_spot->{y}, $ID) if ($best_spot);
  159.  
  160. }
  161.  
  162. }
  163. $timeout{time} = time;
  164. $timeout{timeout} = 1;
  165. }
  166.  
  167. return 1;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement