L2Territory.java 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /*
  2. * This program is free software: you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation, either version 3 of the License, or (at your option) any later
  5. * version.
  6. *
  7. * This program is distributed in the hope that it will be useful, but WITHOUT
  8. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  9. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  10. * details.
  11. *
  12. * You should have received a copy of the GNU General Public License along with
  13. * this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. package com.l2jserver.gameserver.model;
  16. import java.util.List;
  17. import java.util.logging.Logger;
  18. import javolution.util.FastList;
  19. import com.l2jserver.util.Rnd;
  20. /**
  21. * @version 0.1, 2005-03-12
  22. * @author Balancer
  23. */
  24. public class L2Territory
  25. {
  26. private static Logger _log = Logger.getLogger(L2Territory.class.getName());
  27. protected static class Point
  28. {
  29. protected int _x, _y, _zmin, _zmax, _proc;
  30. Point(int x, int y, int zmin, int zmax, int proc)
  31. {
  32. _x = x;
  33. _y = y;
  34. _zmin = zmin;
  35. _zmax = zmax;
  36. _proc = proc;
  37. }
  38. }
  39. private final List<Point> _points;
  40. private final int _terr;
  41. private int _xMin;
  42. private int _xMax;
  43. private int _yMin;
  44. private int _yMax;
  45. private int _zMin;
  46. private int _zMax;
  47. private int _procMax;
  48. public L2Territory(int terr)
  49. {
  50. _points = new FastList<>();
  51. _terr = terr;
  52. _xMin = 999999;
  53. _xMax = -999999;
  54. _yMin = 999999;
  55. _yMax = -999999;
  56. _zMin = 999999;
  57. _zMax = -999999;
  58. _procMax = 0;
  59. }
  60. public void add(int x, int y, int zmin, int zmax, int proc)
  61. {
  62. _points.add(new Point(x, y, zmin, zmax, proc));
  63. if (x < _xMin)
  64. {
  65. _xMin = x;
  66. }
  67. if (y < _yMin)
  68. {
  69. _yMin = y;
  70. }
  71. if (x > _xMax)
  72. {
  73. _xMax = x;
  74. }
  75. if (y > _yMax)
  76. {
  77. _yMax = y;
  78. }
  79. if (zmin < _zMin)
  80. {
  81. _zMin = zmin;
  82. }
  83. if (zmax > _zMax)
  84. {
  85. _zMax = zmax;
  86. }
  87. _procMax += proc;
  88. }
  89. public void print()
  90. {
  91. for (Point p : _points)
  92. {
  93. _log.info("(" + p._x + "," + p._y + ")");
  94. }
  95. }
  96. public boolean isIntersect(int x, int y, Point p1, Point p2)
  97. {
  98. double dy1 = p1._y - y;
  99. double dy2 = p2._y - y;
  100. if (Math.abs(Math.signum(dy1) - Math.signum(dy2)) <= 1e-6)
  101. {
  102. return false;
  103. }
  104. double dx1 = p1._x - x;
  105. double dx2 = p2._x - x;
  106. if ((dx1 >= 0) && (dx2 >= 0))
  107. {
  108. return true;
  109. }
  110. if ((dx1 < 0) && (dx2 < 0))
  111. {
  112. return false;
  113. }
  114. double dx0 = (dy1 * (p1._x - p2._x)) / (p1._y - p2._y);
  115. return dx0 <= dx1;
  116. }
  117. public boolean isInside(int x, int y)
  118. {
  119. int intersect_count = 0;
  120. for (int i = 0; i < _points.size(); i++)
  121. {
  122. Point p1 = _points.get(i > 0 ? i - 1 : _points.size() - 1);
  123. Point p2 = _points.get(i);
  124. if (isIntersect(x, y, p1, p2))
  125. {
  126. intersect_count++;
  127. }
  128. }
  129. return (intersect_count % 2) == 1;
  130. }
  131. public int[] getRandomPoint()
  132. {
  133. int[] p = new int[4];
  134. if (_procMax > 0)
  135. {
  136. int pos = 0;
  137. int rnd = Rnd.nextInt(_procMax);
  138. for (Point p1 : _points)
  139. {
  140. pos += p1._proc;
  141. if (rnd <= pos)
  142. {
  143. p[0] = p1._x;
  144. p[1] = p1._y;
  145. p[2] = p1._zmin;
  146. p[3] = p1._zmax;
  147. return p;
  148. }
  149. }
  150. }
  151. for (int i = 0; i < 100; i++)
  152. {
  153. p[0] = Rnd.get(_xMin, _xMax);
  154. p[1] = Rnd.get(_yMin, _yMax);
  155. if (isInside(p[0], p[1]))
  156. {
  157. double curdistance = 0;
  158. p[2] = _zMin + 100;
  159. p[3] = _zMax;
  160. for (Point p1 : _points)
  161. {
  162. double dx = p1._x - p[0];
  163. double dy = p1._y - p[1];
  164. double distance = Math.sqrt((dx * dx) + (dy * dy));
  165. if ((curdistance == 0) || (distance < curdistance))
  166. {
  167. curdistance = distance;
  168. p[2] = p1._zmin + 100;
  169. }
  170. }
  171. return p;
  172. }
  173. }
  174. _log.warning("Can't make point for territory " + _terr);
  175. return p;
  176. }
  177. public int getProcMax()
  178. {
  179. return _procMax;
  180. }
  181. }