L2Territory.java 3.9 KB

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