GrandBossManager.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  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 net.sf.l2j.gameserver.instancemanager;
  16. import java.sql.Connection;
  17. import java.sql.PreparedStatement;
  18. import java.sql.ResultSet;
  19. import java.sql.SQLException;
  20. import java.util.Map;
  21. import java.util.logging.Logger;
  22. import javolution.util.FastMap;
  23. import net.sf.l2j.L2DatabaseFactory;
  24. import net.sf.l2j.gameserver.model.L2Character;
  25. import net.sf.l2j.gameserver.model.L2Object;
  26. import net.sf.l2j.gameserver.model.actor.instance.L2GrandBossInstance;
  27. import net.sf.l2j.gameserver.model.zone.type.L2BossZone;
  28. import net.sf.l2j.gameserver.templates.StatsSet;
  29. import net.sf.l2j.util.L2FastList;
  30. /**
  31. *
  32. * @author DaRkRaGe
  33. * Revised by Emperorc
  34. */
  35. public class GrandBossManager
  36. {
  37. /* =========================================================
  38. * This class handles all Grand Bosses:
  39. * <ul>
  40. * <li>22215-22217 Tyrannosaurus</li>
  41. * <li>25333-25338 Anakazel</li>
  42. * <li>29001 Queen Ant</li>
  43. * <li>29006 Core</li>
  44. * <li>29014 Orfen</li>
  45. * <li>29019 Antharas</li>
  46. * <li>29020 Baium</li>
  47. * <li>29022 Zaken</li>
  48. * <li>29028 Valakas</li>
  49. * <li>29045 Frintezza</li>
  50. * <li>29046-29047 Scarlet van Halisha</li>
  51. * </ul>
  52. *
  53. * It handles the saving of hp, mp, location, and status
  54. * of all Grand Bosses. It also manages the zones associated
  55. * with the Grand Bosses.
  56. * NOTE: The current version does NOT spawn the Grand Bosses,
  57. * it just stores and retrieves the values on reboot/startup,
  58. * for AI scripts to utilize as needed.
  59. */
  60. /**
  61. * DELETE FROM grandboss_list
  62. */
  63. private static final String DELETE_GRAND_BOSS_LIST = "DELETE FROM grandboss_list";
  64. /**
  65. * INSERT INTO grandboss_list (player_id,zone) VALUES (?,?)
  66. */
  67. private static final String INSERT_GRAND_BOSS_LIST = "INSERT INTO grandboss_list (player_id,zone) VALUES (?,?)";
  68. /**
  69. * UPDATE grandboss_data set loc_x = ?, loc_y = ?, loc_z = ?, heading = ?, respawn_time = ?, currentHP = ?, currentMP = ?, status = ? where boss_id = ?
  70. */
  71. private static final String UPDATE_GRAND_BOSS_DATA = "UPDATE grandboss_data set loc_x = ?, loc_y = ?, loc_z = ?, heading = ?, respawn_time = ?, currentHP = ?, currentMP = ?, status = ? where boss_id = ?";
  72. private static final String UPDATE_GRAND_BOSS_DATA2 = "UPDATE grandboss_data set status = ? where boss_id = ?";
  73. private static Logger _log = Logger.getLogger(GrandBossManager.class.getName());
  74. private static GrandBossManager _instance;
  75. protected static Map<Integer, L2GrandBossInstance> _bosses;
  76. protected static Map<Integer, StatsSet> _storedInfo;
  77. private Map<Integer, Integer> _bossStatus;
  78. private L2FastList<L2BossZone> _zones;
  79. public static final GrandBossManager getInstance()
  80. {
  81. if (_instance == null)
  82. {
  83. _log.info("Initializing GrandBossManager");
  84. _instance = new GrandBossManager();
  85. }
  86. return _instance;
  87. }
  88. public GrandBossManager()
  89. {
  90. init();
  91. }
  92. private void init()
  93. {
  94. _zones = new L2FastList<L2BossZone>();
  95. _bosses = new FastMap<Integer, L2GrandBossInstance>();
  96. _storedInfo = new FastMap<Integer, StatsSet>();
  97. _bossStatus = new FastMap<Integer, Integer>();
  98. Connection con = null;
  99. try
  100. {
  101. con = L2DatabaseFactory.getInstance().getConnection();
  102. PreparedStatement statement = con.prepareStatement("SELECT * from grandboss_data ORDER BY boss_id");
  103. ResultSet rset = statement.executeQuery();
  104. while (rset.next())
  105. {
  106. //Read all info from DB, and store it for AI to read and decide what to do
  107. //faster than accessing DB in real time
  108. StatsSet info = new StatsSet();
  109. int bossId = rset.getInt("boss_id");
  110. info.set("loc_x", rset.getInt("loc_x"));
  111. info.set("loc_y", rset.getInt("loc_y"));
  112. info.set("loc_z", rset.getInt("loc_z"));
  113. info.set("heading", rset.getInt("heading"));
  114. info.set("respawn_time", rset.getLong("respawn_time"));
  115. double HP = rset.getDouble("currentHP"); //jython doesn't recognize doubles
  116. int true_HP = (int) HP; //so use java's ability to type cast
  117. info.set("currentHP", true_HP); //to convert double to int
  118. double MP = rset.getDouble("currentMP");
  119. int true_MP = (int) MP;
  120. info.set("currentMP", true_MP);
  121. _bossStatus.put(bossId, rset.getInt("status"));
  122. _storedInfo.put(bossId, info);
  123. info = null;
  124. }
  125. _log.info("GrandBossManager: Loaded " + _storedInfo.size() + " Instances");
  126. rset.close();
  127. statement.close();
  128. }
  129. catch (SQLException e)
  130. {
  131. _log.warning("GrandBossManager: Could not load grandboss_data table");
  132. }
  133. catch (Exception e)
  134. {
  135. e.printStackTrace();
  136. }
  137. finally
  138. {
  139. try
  140. {
  141. con.close();
  142. }
  143. catch (Exception e)
  144. {
  145. e.printStackTrace();
  146. }
  147. }
  148. }
  149. /*
  150. * Zone Functions
  151. */
  152. public void initZones()
  153. {
  154. Connection con = null;
  155. FastMap<Integer, L2FastList<Integer>> zones = new FastMap<Integer, L2FastList<Integer>>();
  156. if (_zones == null)
  157. {
  158. _log.warning("GrandBossManager: Could not read Grand Boss zone data");
  159. return;
  160. }
  161. for (L2BossZone zone : _zones)
  162. {
  163. if (zone == null)
  164. continue;
  165. zones.put(zone.getId(), new L2FastList<Integer>());
  166. }
  167. try
  168. {
  169. con = L2DatabaseFactory.getInstance().getConnection();
  170. PreparedStatement statement = con.prepareStatement("SELECT * from grandboss_list ORDER BY player_id");
  171. ResultSet rset = statement.executeQuery();
  172. while (rset.next())
  173. {
  174. int id = rset.getInt("player_id");
  175. int zone_id = rset.getInt("zone");
  176. zones.get(zone_id).add(id);
  177. }
  178. rset.close();
  179. statement.close();
  180. _log.info("GrandBossManager: Initialized " + _zones.size() + " Grand Boss Zones");
  181. }
  182. catch (SQLException e)
  183. {
  184. _log.warning("GrandBossManager: Could not load grandboss_list table");
  185. e.getMessage();
  186. }
  187. catch (Exception e)
  188. {
  189. e.printStackTrace();
  190. }
  191. finally
  192. {
  193. try
  194. {
  195. con.close();
  196. }
  197. catch (Exception e)
  198. {
  199. }
  200. }
  201. for (L2BossZone zone : _zones)
  202. {
  203. if (zone == null)
  204. continue;
  205. zone.setAllowedPlayers(zones.get(zone.getId()));
  206. }
  207. zones.clear();
  208. }
  209. public void addZone(L2BossZone zone)
  210. {
  211. if (_zones != null)
  212. {
  213. _zones.add(zone);
  214. }
  215. }
  216. public final L2BossZone getZone(L2Character character)
  217. {
  218. if (_zones != null)
  219. for (L2BossZone temp : _zones)
  220. {
  221. if (temp.isCharacterInZone(character))
  222. {
  223. return temp;
  224. }
  225. }
  226. return null;
  227. }
  228. public final L2BossZone getZone(int x, int y, int z)
  229. {
  230. if (_zones != null)
  231. for (L2BossZone temp : _zones)
  232. {
  233. if (temp.isInsideZone(x, y, z))
  234. {
  235. return temp;
  236. }
  237. }
  238. return null;
  239. }
  240. public boolean checkIfInZone(String zoneType, L2Object obj)
  241. {
  242. L2BossZone temp = getZone(obj.getX(), obj.getY(), obj.getZ());
  243. if (temp == null)
  244. {
  245. return false;
  246. }
  247. return temp.getZoneName().equalsIgnoreCase(zoneType);
  248. }
  249. /*
  250. * The rest
  251. */
  252. public int getBossStatus(int bossId)
  253. {
  254. return _bossStatus.get(bossId);
  255. }
  256. public void setBossStatus(int bossId, int status)
  257. {
  258. _bossStatus.remove(bossId);
  259. _bossStatus.put(bossId, status);
  260. }
  261. /*
  262. * Adds a L2GrandBossInstance to the list of bosses.
  263. */
  264. public void addBoss(L2GrandBossInstance boss)
  265. {
  266. if (boss != null)
  267. {
  268. if (_bosses.containsKey(boss.getNpcId()))
  269. _bosses.remove(boss.getNpcId());
  270. _bosses.put(boss.getNpcId(), boss);
  271. }
  272. }
  273. public L2GrandBossInstance getBoss(int bossId)
  274. {
  275. return _bosses.get(bossId);
  276. }
  277. public StatsSet getStatsSet(int bossId)
  278. {
  279. return _storedInfo.get(bossId);
  280. }
  281. public void setStatsSet(int bossId, StatsSet info)
  282. {
  283. if (_storedInfo.containsKey(bossId))
  284. _storedInfo.remove(bossId);
  285. _storedInfo.put(bossId, info);
  286. }
  287. private void storeToDb()
  288. {
  289. Connection con = null;
  290. PreparedStatement statement = null;
  291. try
  292. {
  293. con = L2DatabaseFactory.getInstance().getConnection();
  294. statement = con.prepareStatement(DELETE_GRAND_BOSS_LIST);
  295. statement.executeUpdate();
  296. statement.close();
  297. for (L2BossZone zone : _zones)
  298. {
  299. if (zone == null)
  300. continue;
  301. Integer id = zone.getId();
  302. L2FastList<Integer> list = zone.getAllowedPlayers();
  303. if (list == null || list.isEmpty())
  304. continue;
  305. for (Integer player : list)
  306. {
  307. statement = con.prepareStatement(INSERT_GRAND_BOSS_LIST);
  308. statement.setInt(1, player);
  309. statement.setInt(2, id);
  310. statement.executeUpdate();
  311. statement.close();
  312. }
  313. }
  314. for (Integer bossId : _storedInfo.keySet())
  315. {
  316. L2GrandBossInstance boss = _bosses.get(bossId);
  317. StatsSet info = _storedInfo.get(bossId);
  318. if (boss == null || info == null)
  319. {
  320. statement = con.prepareStatement(UPDATE_GRAND_BOSS_DATA2);
  321. statement.setInt(1, _bossStatus.get(bossId));
  322. statement.setInt(2, bossId);
  323. }
  324. else
  325. {
  326. statement = con.prepareStatement(UPDATE_GRAND_BOSS_DATA);
  327. statement.setInt(1, boss.getX());
  328. statement.setInt(2, boss.getY());
  329. statement.setInt(3, boss.getZ());
  330. statement.setInt(4, boss.getHeading());
  331. statement.setLong(5, info.getLong("respawn_time"));
  332. double hp = boss.getCurrentHp();
  333. double mp = boss.getCurrentMp();
  334. if (boss.isDead())
  335. {
  336. hp = boss.getMaxHp();
  337. mp = boss.getMaxMp();
  338. }
  339. statement.setDouble(6, hp);
  340. statement.setDouble(7, mp);
  341. statement.setInt(8, _bossStatus.get(bossId));
  342. statement.setInt(9, bossId);
  343. }
  344. statement.executeUpdate();
  345. statement.close();
  346. }
  347. }
  348. catch (SQLException e)
  349. {
  350. _log.warning("GrandBossManager: Couldn't store grandbosses to database:" + e);
  351. }
  352. finally
  353. {
  354. try
  355. {
  356. con.close();
  357. }
  358. catch (Exception e)
  359. {
  360. e.printStackTrace();
  361. }
  362. }
  363. }
  364. /**
  365. * Saves all Grand Boss info and then clears all info from memory,
  366. * including all schedules.
  367. */
  368. public void cleanUp()
  369. {
  370. storeToDb();
  371. _bosses.clear();
  372. _storedInfo.clear();
  373. _bossStatus.clear();
  374. _zones.clear();
  375. }
  376. }