ClanHallSiegeEngine.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  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.entity.clanhall;
  20. import java.sql.Connection;
  21. import java.sql.PreparedStatement;
  22. import java.sql.ResultSet;
  23. import java.util.ArrayList;
  24. import java.util.Calendar;
  25. import java.util.List;
  26. import java.util.Map;
  27. import java.util.concurrent.ConcurrentHashMap;
  28. import java.util.concurrent.ScheduledFuture;
  29. import java.util.logging.Logger;
  30. import com.l2jserver.Config;
  31. import com.l2jserver.commons.database.pool.impl.ConnectionFactory;
  32. import com.l2jserver.gameserver.ThreadPoolManager;
  33. import com.l2jserver.gameserver.data.sql.impl.ClanTable;
  34. import com.l2jserver.gameserver.instancemanager.CHSiegeManager;
  35. import com.l2jserver.gameserver.instancemanager.MapRegionManager;
  36. import com.l2jserver.gameserver.model.L2Clan;
  37. import com.l2jserver.gameserver.model.L2SiegeClan;
  38. import com.l2jserver.gameserver.model.L2SiegeClan.SiegeClanType;
  39. import com.l2jserver.gameserver.model.L2Spawn;
  40. import com.l2jserver.gameserver.model.L2World;
  41. import com.l2jserver.gameserver.model.Location;
  42. import com.l2jserver.gameserver.model.actor.L2Character;
  43. import com.l2jserver.gameserver.model.actor.L2Npc;
  44. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  45. import com.l2jserver.gameserver.model.entity.Siegable;
  46. import com.l2jserver.gameserver.model.quest.Quest;
  47. import com.l2jserver.gameserver.network.NpcStringId;
  48. import com.l2jserver.gameserver.network.SystemMessageId;
  49. import com.l2jserver.gameserver.network.serverpackets.NpcSay;
  50. import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
  51. import com.l2jserver.gameserver.util.Broadcast;
  52. /**
  53. * @author BiggBoss
  54. */
  55. public abstract class ClanHallSiegeEngine extends Quest implements Siegable
  56. {
  57. private static final String SQL_LOAD_ATTACKERS = "SELECT attacker_id FROM clanhall_siege_attackers WHERE clanhall_id = ?";
  58. private static final String SQL_SAVE_ATTACKERS = "INSERT INTO clanhall_siege_attackers VALUES (?,?)";
  59. private static final String SQL_LOAD_GUARDS = "SELECT * FROM clanhall_siege_guards WHERE clanHallId = ?";
  60. public static final int FORTRESS_RESSISTANCE = 21;
  61. public static final int DEVASTATED_CASTLE = 34;
  62. public static final int BANDIT_STRONGHOLD = 35;
  63. public static final int RAINBOW_SPRINGS = 62;
  64. public static final int BEAST_FARM = 63;
  65. public static final int FORTRESS_OF_DEAD = 64;
  66. protected final Logger _log;
  67. private final Map<Integer, L2SiegeClan> _attackers = new ConcurrentHashMap<>();
  68. private List<L2Spawn> _guards;
  69. public SiegableHall _hall;
  70. public ScheduledFuture<?> _siegeTask;
  71. public boolean _missionAccomplished = false;
  72. public ClanHallSiegeEngine(String name, String descr, final int hallId)
  73. {
  74. super(-1, name, descr);
  75. _log = Logger.getLogger(getClass().getName());
  76. _hall = CHSiegeManager.getInstance().getSiegableHall(hallId);
  77. _hall.setSiege(this);
  78. _siegeTask = ThreadPoolManager.getInstance().scheduleGeneral(new PrepareOwner(), _hall.getNextSiegeTime() - System.currentTimeMillis() - 3600000);
  79. _log.config(_hall.getName() + " siege scheduled for: " + getSiegeDate().getTime());
  80. loadAttackers();
  81. }
  82. public void loadAttackers()
  83. {
  84. try (Connection con = ConnectionFactory.getInstance().getConnection();
  85. PreparedStatement ps = con.prepareStatement(SQL_LOAD_ATTACKERS))
  86. {
  87. ps.setInt(1, _hall.getId());
  88. try (ResultSet rset = ps.executeQuery())
  89. {
  90. while (rset.next())
  91. {
  92. final int id = rset.getInt("attacker_id");
  93. L2SiegeClan clan = new L2SiegeClan(id, SiegeClanType.ATTACKER);
  94. _attackers.put(id, clan);
  95. }
  96. }
  97. }
  98. catch (Exception e)
  99. {
  100. _log.warning(getName() + ": Could not load siege attackers!:");
  101. }
  102. }
  103. public final void saveAttackers()
  104. {
  105. try (Connection con = ConnectionFactory.getInstance().getConnection();
  106. PreparedStatement ps = con.prepareStatement("DELETE FROM clanhall_siege_attackers WHERE clanhall_id = ?"))
  107. {
  108. ps.setInt(1, _hall.getId());
  109. ps.execute();
  110. if (_attackers.size() > 0)
  111. {
  112. try (PreparedStatement insert = con.prepareStatement(SQL_SAVE_ATTACKERS))
  113. {
  114. for (L2SiegeClan clan : _attackers.values())
  115. {
  116. insert.setInt(1, _hall.getId());
  117. insert.setInt(2, clan.getClanId());
  118. insert.execute();
  119. insert.clearParameters();
  120. }
  121. }
  122. }
  123. _log.config(getName() + ": Sucessfully saved attackers down to database!");
  124. }
  125. catch (Exception e)
  126. {
  127. _log.warning(getName() + ": Couldnt save attacker list!");
  128. }
  129. }
  130. public final void loadGuards()
  131. {
  132. if (_guards == null)
  133. {
  134. _guards = new ArrayList<>();
  135. try (Connection con = ConnectionFactory.getInstance().getConnection();
  136. PreparedStatement ps = con.prepareStatement(SQL_LOAD_GUARDS))
  137. {
  138. ps.setInt(1, _hall.getId());
  139. try (ResultSet rset = ps.executeQuery())
  140. {
  141. while (rset.next())
  142. {
  143. final L2Spawn spawn = new L2Spawn(rset.getInt("npcId"));
  144. spawn.setX(rset.getInt("x"));
  145. spawn.setY(rset.getInt("y"));
  146. spawn.setZ(rset.getInt("z"));
  147. spawn.setHeading(rset.getInt("heading"));
  148. spawn.setRespawnDelay(rset.getInt("respawnDelay"));
  149. spawn.setAmount(1);
  150. _guards.add(spawn);
  151. }
  152. }
  153. }
  154. catch (Exception e)
  155. {
  156. _log.warning(getName() + ": Couldnt load siege guards!:");
  157. }
  158. }
  159. }
  160. private final void spawnSiegeGuards()
  161. {
  162. for (L2Spawn guard : _guards)
  163. {
  164. guard.init();
  165. }
  166. }
  167. private final void unSpawnSiegeGuards()
  168. {
  169. if (_guards != null)
  170. {
  171. for (L2Spawn guard : _guards)
  172. {
  173. guard.stopRespawn();
  174. if (guard.getLastSpawn() != null)
  175. {
  176. guard.getLastSpawn().deleteMe();
  177. }
  178. }
  179. }
  180. }
  181. @Override
  182. public List<L2Npc> getFlag(L2Clan clan)
  183. {
  184. List<L2Npc> result = null;
  185. L2SiegeClan sClan = getAttackerClan(clan);
  186. if (sClan != null)
  187. {
  188. result = sClan.getFlag();
  189. }
  190. return result;
  191. }
  192. public final Map<Integer, L2SiegeClan> getAttackers()
  193. {
  194. return _attackers;
  195. }
  196. @Override
  197. public boolean checkIsAttacker(L2Clan clan)
  198. {
  199. if (clan == null)
  200. {
  201. return false;
  202. }
  203. return _attackers.containsKey(clan.getId());
  204. }
  205. @Override
  206. public boolean checkIsDefender(L2Clan clan)
  207. {
  208. return false;
  209. }
  210. @Override
  211. public L2SiegeClan getAttackerClan(int clanId)
  212. {
  213. return _attackers.get(clanId);
  214. }
  215. @Override
  216. public L2SiegeClan getAttackerClan(L2Clan clan)
  217. {
  218. return getAttackerClan(clan.getId());
  219. }
  220. @Override
  221. public List<L2SiegeClan> getAttackerClans()
  222. {
  223. return new ArrayList<>(_attackers.values());
  224. }
  225. @Override
  226. public List<L2PcInstance> getAttackersInZone()
  227. {
  228. final List<L2PcInstance> attackers = new ArrayList<>();
  229. for (L2PcInstance pc : _hall.getSiegeZone().getPlayersInside())
  230. {
  231. final L2Clan clan = pc.getClan();
  232. if ((clan != null) && _attackers.containsKey(clan.getId()))
  233. {
  234. attackers.add(pc);
  235. }
  236. }
  237. return attackers;
  238. }
  239. @Override
  240. public L2SiegeClan getDefenderClan(int clanId)
  241. {
  242. return null;
  243. }
  244. @Override
  245. public L2SiegeClan getDefenderClan(L2Clan clan)
  246. {
  247. return null;
  248. }
  249. @Override
  250. public List<L2SiegeClan> getDefenderClans()
  251. {
  252. return null;
  253. }
  254. public void prepareOwner()
  255. {
  256. if (_hall.getOwnerId() > 0)
  257. {
  258. final L2SiegeClan clan = new L2SiegeClan(_hall.getOwnerId(), SiegeClanType.ATTACKER);
  259. _attackers.put(clan.getClanId(), new L2SiegeClan(clan.getClanId(), SiegeClanType.ATTACKER));
  260. }
  261. _hall.free();
  262. _hall.banishForeigners();
  263. SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.REGISTRATION_TERM_FOR_S1_ENDED);
  264. msg.addString(getName());
  265. Broadcast.toAllOnlinePlayers(msg);
  266. _hall.updateSiegeStatus(SiegeStatus.WAITING_BATTLE);
  267. _siegeTask = ThreadPoolManager.getInstance().scheduleGeneral(new SiegeStarts(), 3600000);
  268. }
  269. @Override
  270. public void startSiege()
  271. {
  272. if ((_attackers.size() < 1) && (_hall.getId() != 21)) // Fortress of resistance don't have attacker list
  273. {
  274. onSiegeEnds();
  275. _attackers.clear();
  276. _hall.updateNextSiege();
  277. _siegeTask = ThreadPoolManager.getInstance().scheduleGeneral(new PrepareOwner(), _hall.getSiegeDate().getTimeInMillis());
  278. _hall.updateSiegeStatus(SiegeStatus.WAITING_BATTLE);
  279. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.SIEGE_OF_S1_HAS_BEEN_CANCELED_DUE_TO_LACK_OF_INTEREST);
  280. sm.addString(_hall.getName());
  281. Broadcast.toAllOnlinePlayers(sm);
  282. return;
  283. }
  284. _hall.spawnDoor();
  285. loadGuards();
  286. spawnSiegeGuards();
  287. _hall.updateSiegeZone(true);
  288. final byte state = 1;
  289. for (L2SiegeClan sClan : _attackers.values())
  290. {
  291. final L2Clan clan = ClanTable.getInstance().getClan(sClan.getClanId());
  292. if (clan == null)
  293. {
  294. continue;
  295. }
  296. for (L2PcInstance pc : clan.getOnlineMembers(0))
  297. {
  298. pc.setSiegeState(state);
  299. pc.broadcastUserInfo();
  300. pc.setIsInHideoutSiege(true);
  301. }
  302. }
  303. _hall.updateSiegeStatus(SiegeStatus.RUNNING);
  304. onSiegeStarts();
  305. _siegeTask = ThreadPoolManager.getInstance().scheduleGeneral(new SiegeEnds(), _hall.getSiegeLenght());
  306. }
  307. @Override
  308. public void endSiege()
  309. {
  310. SystemMessage end = SystemMessage.getSystemMessage(SystemMessageId.SIEGE_OF_S1_HAS_ENDED);
  311. end.addString(_hall.getName());
  312. Broadcast.toAllOnlinePlayers(end);
  313. L2Clan winner = getWinner();
  314. SystemMessage finalMsg = null;
  315. if (_missionAccomplished && (winner != null))
  316. {
  317. _hall.setOwner(winner);
  318. winner.setHideoutId(_hall.getId());
  319. finalMsg = SystemMessage.getSystemMessage(SystemMessageId.CLAN_S1_VICTORIOUS_OVER_S2_S_SIEGE);
  320. finalMsg.addString(winner.getName());
  321. finalMsg.addString(_hall.getName());
  322. Broadcast.toAllOnlinePlayers(finalMsg);
  323. }
  324. else
  325. {
  326. finalMsg = SystemMessage.getSystemMessage(SystemMessageId.SIEGE_S1_DRAW);
  327. finalMsg.addString(_hall.getName());
  328. Broadcast.toAllOnlinePlayers(finalMsg);
  329. }
  330. _missionAccomplished = false;
  331. _hall.updateSiegeZone(false);
  332. _hall.updateNextSiege();
  333. _hall.spawnDoor(false);
  334. _hall.banishForeigners();
  335. final byte state = 0;
  336. for (L2SiegeClan sClan : _attackers.values())
  337. {
  338. final L2Clan clan = ClanTable.getInstance().getClan(sClan.getClanId());
  339. if (clan == null)
  340. {
  341. continue;
  342. }
  343. for (L2PcInstance player : clan.getOnlineMembers(0))
  344. {
  345. player.setSiegeState(state);
  346. player.broadcastUserInfo();
  347. player.setIsInHideoutSiege(false);
  348. }
  349. }
  350. // Update pvp flag for winners when siege zone becomes inactive
  351. for (L2Character chr : _hall.getSiegeZone().getCharactersInside())
  352. {
  353. if ((chr != null) && chr.isPlayer())
  354. {
  355. chr.getActingPlayer().startPvPFlag();
  356. }
  357. }
  358. _attackers.clear();
  359. onSiegeEnds();
  360. _siegeTask = ThreadPoolManager.getInstance().scheduleGeneral(new PrepareOwner(), _hall.getNextSiegeTime() - System.currentTimeMillis() - 3600000);
  361. _log.config("Siege of " + _hall.getName() + " scheduled for: " + _hall.getSiegeDate().getTime());
  362. _hall.updateSiegeStatus(SiegeStatus.REGISTERING);
  363. unSpawnSiegeGuards();
  364. }
  365. @Override
  366. public void updateSiege()
  367. {
  368. cancelSiegeTask();
  369. _siegeTask = ThreadPoolManager.getInstance().scheduleGeneral(new PrepareOwner(), _hall.getNextSiegeTime() - 3600000);
  370. _log.config(_hall.getName() + " siege scheduled for: " + _hall.getSiegeDate().getTime().toString());
  371. }
  372. public void cancelSiegeTask()
  373. {
  374. if (_siegeTask != null)
  375. {
  376. _siegeTask.cancel(false);
  377. }
  378. }
  379. @Override
  380. public Calendar getSiegeDate()
  381. {
  382. return _hall.getSiegeDate();
  383. }
  384. @Override
  385. public boolean giveFame()
  386. {
  387. return Config.CHS_ENABLE_FAME;
  388. }
  389. @Override
  390. public int getFameAmount()
  391. {
  392. return Config.CHS_FAME_AMOUNT;
  393. }
  394. @Override
  395. public int getFameFrequency()
  396. {
  397. return Config.CHS_FAME_FREQUENCY;
  398. }
  399. public final void broadcastNpcSay(final L2Npc npc, final int type, final NpcStringId messageId)
  400. {
  401. final NpcSay npcSay = new NpcSay(npc.getObjectId(), type, npc.getId(), messageId);
  402. final int sourceRegion = MapRegionManager.getInstance().getMapRegionLocId(npc);
  403. for (L2PcInstance pc : L2World.getInstance().getPlayers())
  404. {
  405. if ((pc != null) && (MapRegionManager.getInstance().getMapRegionLocId(pc) == sourceRegion))
  406. {
  407. pc.sendPacket(npcSay);
  408. }
  409. }
  410. }
  411. public Location getInnerSpawnLoc(L2PcInstance player)
  412. {
  413. return null;
  414. }
  415. public boolean canPlantFlag()
  416. {
  417. return true;
  418. }
  419. public boolean doorIsAutoAttackable()
  420. {
  421. return true;
  422. }
  423. public void onSiegeStarts()
  424. {
  425. }
  426. public void onSiegeEnds()
  427. {
  428. }
  429. public abstract L2Clan getWinner();
  430. public class PrepareOwner implements Runnable
  431. {
  432. @Override
  433. public void run()
  434. {
  435. prepareOwner();
  436. }
  437. }
  438. public class SiegeStarts implements Runnable
  439. {
  440. @Override
  441. public void run()
  442. {
  443. startSiege();
  444. }
  445. }
  446. public class SiegeEnds implements Runnable
  447. {
  448. @Override
  449. public void run()
  450. {
  451. endSiege();
  452. }
  453. }
  454. }