Siege.java 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377
  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.model.entity;
  16. import java.sql.PreparedStatement;
  17. import java.sql.ResultSet;
  18. import java.util.Calendar;
  19. import java.util.List;
  20. import java.util.logging.Logger;
  21. import javolution.util.FastList;
  22. import net.sf.l2j.L2DatabaseFactory;
  23. import net.sf.l2j.gameserver.Announcements;
  24. import net.sf.l2j.gameserver.ThreadPoolManager;
  25. import net.sf.l2j.gameserver.datatables.ClanTable;
  26. import net.sf.l2j.gameserver.datatables.MapRegionTable;
  27. import net.sf.l2j.gameserver.datatables.NpcTable;
  28. import net.sf.l2j.gameserver.idfactory.IdFactory;
  29. import net.sf.l2j.gameserver.instancemanager.MercTicketManager;
  30. import net.sf.l2j.gameserver.instancemanager.SiegeGuardManager;
  31. import net.sf.l2j.gameserver.instancemanager.SiegeManager;
  32. import net.sf.l2j.gameserver.instancemanager.SiegeManager.SiegeSpawn;
  33. import net.sf.l2j.gameserver.model.L2Character;
  34. import net.sf.l2j.gameserver.model.L2Clan;
  35. import net.sf.l2j.gameserver.model.L2Object;
  36. import net.sf.l2j.gameserver.model.L2SiegeClan;
  37. import net.sf.l2j.gameserver.model.L2Spawn;
  38. import net.sf.l2j.gameserver.model.L2World;
  39. import net.sf.l2j.gameserver.model.L2SiegeClan.SiegeClanType;
  40. import net.sf.l2j.gameserver.model.actor.instance.L2ControlTowerInstance;
  41. import net.sf.l2j.gameserver.model.actor.instance.L2NpcInstance;
  42. import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
  43. import net.sf.l2j.gameserver.network.SystemMessageId;
  44. import net.sf.l2j.gameserver.serverpackets.RelationChanged;
  45. import net.sf.l2j.gameserver.serverpackets.SiegeInfo;
  46. import net.sf.l2j.gameserver.serverpackets.SystemMessage;
  47. import net.sf.l2j.gameserver.serverpackets.UserInfo;
  48. import net.sf.l2j.gameserver.templates.L2NpcTemplate;
  49. public class Siege
  50. {
  51. protected static final Logger _log = Logger.getLogger(Siege.class.getName());
  52. // ==========================================================================================
  53. // Message to add/check
  54. // id=17 msg=[Castle siege has begun.] c3_attr1=[SystemMsg_k.17]
  55. // id=18 msg=[Castle siege is over.] c3_attr1=[SystemMsg_k.18]
  56. // id=288 msg=[The castle gate has been broken down.]
  57. // id=291 msg=[Clan $s1 is victorious over $s2's castle siege!]
  58. // id=292 msg=[$s1 has announced the castle siege time.]
  59. // - id=293 msg=[The registration term for $s1 has ended.]
  60. // - id=358 msg=[$s1 hour(s) until castle siege conclusion.]
  61. // - id=359 msg=[$s1 minute(s) until castle siege conclusion.]
  62. // - id=360 msg=[Castle siege $s1 second(s) left!]
  63. // id=640 msg=[You have failed to refuse castle defense aid.]
  64. // id=641 msg=[You have failed to approve castle defense aid.]
  65. // id=644 msg=[You are not yet registered for the castle siege.]
  66. // - id=645 msg=[Only clans with Level 4 and higher may register for a castle siege.]
  67. // id=646 msg=[You do not have the authority to modify the castle defender list.]
  68. // - id=688 msg=[The clan that owns the castle is automatically registered on the defending side.]
  69. // id=689 msg=[A clan that owns a castle cannot participate in another siege.]
  70. // id=690 msg=[You cannot register on the attacking side because you are part of an alliance with the clan that owns the castle.]
  71. // id=718 msg=[The castle gates cannot be opened and closed during a siege.]
  72. // - id=295 msg=[$s1's siege was canceled because there were no clans that participated.]
  73. // id=659 msg=[This is not the time for siege registration and so registrations cannot be accepted or rejected.]
  74. // - id=660 msg=[This is not the time for siege registration and so registration and cancellation cannot be done.]
  75. // id=663 msg=[The siege time has been declared for $s. It is not possible to change the time after a siege time has been declared. Do you want to continue?]
  76. // id=667 msg=[You are registering on the attacking side of the $s1 siege. Do you want to continue?]
  77. // id=668 msg=[You are registering on the defending side of the $s1 siege. Do you want to continue?]
  78. // id=669 msg=[You are canceling your application to participate in the $s1 siege battle. Do you want to continue?]
  79. // id=707 msg=[You cannot teleport to a village that is in a siege.]
  80. // - id=711 msg=[The siege of $s1 has started.]
  81. // - id=712 msg=[The siege of $s1 has finished.]
  82. // id=844 msg=[The siege to conquer $s1 has begun.]
  83. // - id=845 msg=[The deadline to register for the siege of $s1 has passed.]
  84. // - id=846 msg=[The siege of $s1 has been canceled due to lack of interest.]
  85. // - id=856 msg=[The siege of $s1 has ended in a draw.]
  86. // id=285 msg=[Clan $s1 has succeeded in engraving the ruler!]
  87. // - id=287 msg=[The opponent clan has begun to engrave the ruler.]
  88. public static enum TeleportWhoType {
  89. All, Attacker, DefenderNotOwner, Owner, Spectator
  90. }
  91. // ===============================================================
  92. // Schedule task
  93. public class ScheduleEndSiegeTask implements Runnable
  94. {
  95. private Castle _castleInst;
  96. public ScheduleEndSiegeTask(Castle pCastle)
  97. {
  98. _castleInst = pCastle;
  99. }
  100. public void run()
  101. {
  102. if (!getIsInProgress()) return;
  103. try
  104. {
  105. long timeRemaining = _siegeEndDate.getTimeInMillis()
  106. - Calendar.getInstance().getTimeInMillis();
  107. if (timeRemaining > 3600000)
  108. {
  109. ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleEndSiegeTask(_castleInst),
  110. timeRemaining - 3600000); // Prepare task for 1 hr left.
  111. }
  112. else if ((timeRemaining <= 3600000) && (timeRemaining > 600000))
  113. {
  114. announceToPlayer(Math.round(timeRemaining / 60000) + " minute(s) until "
  115. + getCastle().getName() + " siege conclusion.", true);
  116. ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleEndSiegeTask(_castleInst),
  117. timeRemaining - 600000); // Prepare task for 10 minute left.
  118. }
  119. else if ((timeRemaining <= 600000) && (timeRemaining > 300000))
  120. {
  121. announceToPlayer(Math.round(timeRemaining / 60000) + " minute(s) until "
  122. + getCastle().getName() + " siege conclusion.", true);
  123. ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleEndSiegeTask(_castleInst),
  124. timeRemaining - 300000); // Prepare task for 5 minute left.
  125. }
  126. else if ((timeRemaining <= 300000) && (timeRemaining > 10000))
  127. {
  128. announceToPlayer(Math.round(timeRemaining / 60000) + " minute(s) until "
  129. + getCastle().getName() + " siege conclusion.", true);
  130. ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleEndSiegeTask(_castleInst),
  131. timeRemaining - 10000); // Prepare task for 10 seconds count down
  132. }
  133. else if ((timeRemaining <= 10000) && (timeRemaining > 0))
  134. {
  135. announceToPlayer(getCastle().getName() + " siege "
  136. + Math.round(timeRemaining / 1000) + " second(s) left!", true);
  137. ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleEndSiegeTask(_castleInst),
  138. timeRemaining); // Prepare task for second count down
  139. }
  140. else
  141. {
  142. _castleInst.getSiege().endSiege();
  143. }
  144. }
  145. catch (Throwable t)
  146. {
  147. }
  148. }
  149. }
  150. public class ScheduleStartSiegeTask implements Runnable
  151. {
  152. private Castle _castleInst;
  153. public ScheduleStartSiegeTask(Castle pCastle)
  154. {
  155. _castleInst = pCastle;
  156. }
  157. public void run()
  158. {
  159. if (getIsInProgress()) return;
  160. try
  161. {
  162. long timeRemaining = getSiegeDate().getTimeInMillis()
  163. - Calendar.getInstance().getTimeInMillis();
  164. if (timeRemaining > 86400000)
  165. {
  166. ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleStartSiegeTask(_castleInst),
  167. timeRemaining - 86400000); // Prepare task for 24 before siege start to end registration
  168. }
  169. else if ((timeRemaining <= 86400000) && (timeRemaining > 13600000))
  170. {
  171. announceToPlayer("The registration term for " + getCastle().getName()
  172. + " has ended.", false);
  173. _isRegistrationOver = true;
  174. clearSiegeWaitingClan();
  175. ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleStartSiegeTask(_castleInst),
  176. timeRemaining - 13600000); // Prepare task for 1 hr left before siege start.
  177. }
  178. else if ((timeRemaining <= 13600000) && (timeRemaining > 600000))
  179. {
  180. announceToPlayer(Math.round(timeRemaining / 60000) + " minute(s) until "
  181. + getCastle().getName() + " siege begin.", false);
  182. ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleStartSiegeTask(_castleInst),
  183. timeRemaining - 600000); // Prepare task for 10 minute left.
  184. }
  185. else if ((timeRemaining <= 600000) && (timeRemaining > 300000))
  186. {
  187. announceToPlayer(Math.round(timeRemaining / 60000) + " minute(s) until "
  188. + getCastle().getName() + " siege begin.", false);
  189. ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleStartSiegeTask(_castleInst),
  190. timeRemaining - 300000); // Prepare task for 5 minute left.
  191. }
  192. else if ((timeRemaining <= 300000) && (timeRemaining > 10000))
  193. {
  194. announceToPlayer(Math.round(timeRemaining / 60000) + " minute(s) until "
  195. + getCastle().getName() + " siege begin.", false);
  196. ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleStartSiegeTask(_castleInst),
  197. timeRemaining - 10000); // Prepare task for 10 seconds count down
  198. }
  199. else if ((timeRemaining <= 10000) && (timeRemaining > 0))
  200. {
  201. announceToPlayer(getCastle().getName() + " siege "
  202. + Math.round(timeRemaining / 1000) + " second(s) to start!", false);
  203. ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleStartSiegeTask(_castleInst),
  204. timeRemaining); // Prepare task for second count down
  205. }
  206. else
  207. {
  208. _castleInst.getSiege().startSiege();
  209. }
  210. }
  211. catch (Throwable t)
  212. {
  213. }
  214. }
  215. }
  216. // =========================================================
  217. // Data Field
  218. // Attacker and Defender
  219. private List<L2SiegeClan> _attackerClans = new FastList<L2SiegeClan>(); // L2SiegeClan
  220. private List<L2SiegeClan> _defenderClans = new FastList<L2SiegeClan>(); // L2SiegeClan
  221. private List<L2SiegeClan> _defenderWaitingClans = new FastList<L2SiegeClan>(); // L2SiegeClan
  222. private int _defenderRespawnDelayPenalty;
  223. // Castle setting
  224. private List<L2ControlTowerInstance> _controlTowers = new FastList<L2ControlTowerInstance>();
  225. private Castle[] _castle;
  226. private boolean _isInProgress = false;
  227. private boolean _isNormalSide = true; // true = Atk is Atk, false = Atk is Def
  228. protected boolean _isRegistrationOver = false;
  229. protected Calendar _siegeEndDate;
  230. private SiegeGuardManager _siegeGuardManager;
  231. protected Calendar _siegeRegistrationEndDate;
  232. // =========================================================
  233. // Constructor
  234. public Siege(Castle[] castle)
  235. {
  236. _castle = castle;
  237. _siegeGuardManager = new SiegeGuardManager(getCastle());
  238. startAutoTask();
  239. }
  240. // =========================================================
  241. // Siege phases
  242. /**
  243. * When siege ends<BR><BR>
  244. */
  245. public void endSiege()
  246. {
  247. if (getIsInProgress())
  248. {
  249. announceToPlayer("The siege of " + getCastle().getName() + " has finished!", false);
  250. if (getCastle().getOwnerId() <= 0)
  251. announceToPlayer("The siege of " + getCastle().getName() + " has ended in a draw.",
  252. false);
  253. removeFlags(); // Removes all flags. Note: Remove flag before teleporting players
  254. teleportPlayer(Siege.TeleportWhoType.Attacker, MapRegionTable.TeleportWhereType.Town); // Teleport to the second closest town
  255. teleportPlayer(Siege.TeleportWhoType.DefenderNotOwner, MapRegionTable.TeleportWhereType.Town); // Teleport to the second closest town
  256. teleportPlayer(Siege.TeleportWhoType.Spectator, MapRegionTable.TeleportWhereType.Town); // Teleport to the second closest town
  257. _isInProgress = false; // Flag so that siege instance can be started
  258. updatePlayerSiegeStateFlags(true);
  259. saveCastleSiege(); // Save castle specific data
  260. clearSiegeClan(); // Clear siege clan from db
  261. removeControlTower(); // Remove all control tower from this castle
  262. _siegeGuardManager.unspawnSiegeGuard(); // Remove all spawned siege guard from this castle
  263. if (getCastle().getOwnerId() > 0) _siegeGuardManager.removeMercs();
  264. getCastle().spawnDoor(); // Respawn door to castle
  265. getCastle().getZone().updateZoneStatusForCharactersInside();
  266. }
  267. }
  268. private void removeDefender(L2SiegeClan sc)
  269. {
  270. if (sc != null) getDefenderClans().remove(sc);
  271. }
  272. private void removeAttacker(L2SiegeClan sc)
  273. {
  274. if (sc != null) getAttackerClans().remove(sc);
  275. }
  276. private void addDefender(L2SiegeClan sc, SiegeClanType type)
  277. {
  278. if(sc == null) return;
  279. sc.setType(type);
  280. getDefenderClans().add(sc);
  281. }
  282. private void addAttacker(L2SiegeClan sc)
  283. {
  284. if(sc == null) return;
  285. sc.setType(SiegeClanType.ATTACKER);
  286. getAttackerClans().add(sc);
  287. }
  288. /**
  289. * When control of castle changed during siege<BR><BR>
  290. */
  291. public void midVictory()
  292. {
  293. if (getIsInProgress()) // Siege still in progress
  294. {
  295. if (getCastle().getOwnerId() > 0) _siegeGuardManager.removeMercs(); // Remove all merc entry from db
  296. if (getDefenderClans().size() == 0 && // If defender doesn't exist (Pc vs Npc)
  297. getAttackerClans().size() == 1 // Only 1 attacker
  298. )
  299. {
  300. L2SiegeClan sc_newowner = getAttackerClan(getCastle().getOwnerId());
  301. removeAttacker(sc_newowner);
  302. addDefender(sc_newowner, SiegeClanType.OWNER);
  303. endSiege();
  304. return;
  305. }
  306. if (getCastle().getOwnerId() > 0) {
  307. int allyId = ClanTable.getInstance().getClan(getCastle().getOwnerId()).getAllyId();
  308. if (getDefenderClans().size() == 0) // If defender doesn't exist (Pc vs Npc)
  309. // and only an alliance attacks
  310. {
  311. // The player's clan is in an alliance
  312. if (allyId != 0)
  313. {
  314. boolean allinsamealliance = true;
  315. for (L2SiegeClan sc : getAttackerClans())
  316. {
  317. if(sc != null)
  318. {
  319. if(ClanTable.getInstance().getClan(sc.getClanId()).getAllyId() != allyId)
  320. allinsamealliance = false;
  321. }
  322. }
  323. if(allinsamealliance)
  324. {
  325. L2SiegeClan sc_newowner = getAttackerClan(getCastle().getOwnerId());
  326. removeAttacker(sc_newowner);
  327. addDefender(sc_newowner, SiegeClanType.OWNER);
  328. endSiege();
  329. return;
  330. }
  331. }
  332. }
  333. for (L2SiegeClan sc : getDefenderClans())
  334. {
  335. if(sc != null) {
  336. removeDefender(sc);
  337. addAttacker(sc);
  338. }
  339. }
  340. L2SiegeClan sc_newowner = getAttackerClan(getCastle().getOwnerId());
  341. removeAttacker(sc_newowner);
  342. addDefender(sc_newowner, SiegeClanType.OWNER);
  343. // The player's clan is in an alliance
  344. if (allyId != 0)
  345. {
  346. L2Clan[] clanList = ClanTable.getInstance().getClans();
  347. for (L2Clan clan : clanList) {
  348. if (clan.getAllyId() == allyId) {
  349. L2SiegeClan sc = getAttackerClan(clan.getClanId());
  350. if(sc != null) {
  351. removeAttacker(sc);
  352. addDefender(sc, SiegeClanType.DEFENDER);
  353. }
  354. }
  355. }
  356. }
  357. teleportPlayer(Siege.TeleportWhoType.Attacker, MapRegionTable.TeleportWhereType.SiegeFlag); // Teleport to the second closest town
  358. teleportPlayer(Siege.TeleportWhoType.Spectator, MapRegionTable.TeleportWhereType.Town); // Teleport to the second closest town
  359. removeDefenderFlags(); // Removes defenders' flags
  360. getCastle().removeUpgrade(); // Remove all castle upgrade
  361. getCastle().spawnDoor(true); // Respawn door to castle but make them weaker (50% hp)
  362. updatePlayerSiegeStateFlags(false);
  363. }
  364. }
  365. }
  366. /**
  367. * When siege starts<BR><BR>
  368. */
  369. public void startSiege()
  370. {
  371. if (!getIsInProgress())
  372. {
  373. if (getAttackerClans().size() <= 0)
  374. {
  375. SystemMessage sm;
  376. if (getCastle().getOwnerId() <= 0)
  377. sm = new SystemMessage(SystemMessageId.SIEGE_OF_S1_HAS_BEEN_CANCELED_DUE_TO_LACK_OF_INTEREST);
  378. else
  379. sm = new SystemMessage(SystemMessageId.S1_SIEGE_WAS_CANCELED_BECAUSE_NO_CLANS_PARTICIPATED);
  380. sm.addString(getCastle().getName());
  381. Announcements.getInstance().announceToAll(sm);
  382. return;
  383. }
  384. _isNormalSide = true; // Atk is now atk
  385. _isInProgress = true; // Flag so that same siege instance cannot be started again
  386. loadSiegeClan(); // Load siege clan from db
  387. updatePlayerSiegeStateFlags(false);
  388. teleportPlayer(Siege.TeleportWhoType.Attacker, MapRegionTable.TeleportWhereType.Town); // Teleport to the closest town
  389. //teleportPlayer(Siege.TeleportWhoType.Spectator, MapRegionTable.TeleportWhereType.Town); // Teleport to the second closest town
  390. spawnControlTower(getCastle().getCastleId()); // Spawn control tower
  391. getCastle().spawnDoor(); // Spawn door
  392. spawnSiegeGuard(); // Spawn siege guard
  393. MercTicketManager.getInstance().deleteTickets(getCastle().getCastleId()); // remove the tickets from the ground
  394. _defenderRespawnDelayPenalty = 0; // Reset respawn delay
  395. getCastle().getZone().updateZoneStatusForCharactersInside();
  396. // Schedule a task to prepare auto siege end
  397. _siegeEndDate = Calendar.getInstance();
  398. _siegeEndDate.add(Calendar.MINUTE, SiegeManager.getInstance().getSiegeLength());
  399. ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleEndSiegeTask(getCastle()), 1000); // Prepare auto end task
  400. announceToPlayer("The siege of " + getCastle().getName() + " has started!", false);
  401. }
  402. }
  403. // =========================================================
  404. // Method - Public
  405. /**
  406. * Announce to player.<BR><BR>
  407. * @param message The String of the message to send to player
  408. * @param inAreaOnly The boolean flag to show message to players in area only.
  409. */
  410. public void announceToPlayer(String message, boolean inAreaOnly)
  411. {
  412. if (inAreaOnly)
  413. {
  414. getCastle().getZone().announceToPlayers(message);
  415. return;
  416. }
  417. // Get all players
  418. for (L2PcInstance player : L2World.getInstance().getAllPlayers())
  419. {
  420. player.sendMessage(message);
  421. }
  422. }
  423. public void updatePlayerSiegeStateFlags(boolean clear)
  424. {
  425. L2Clan clan;
  426. for(L2SiegeClan siegeclan : getAttackerClans())
  427. {
  428. clan = ClanTable.getInstance().getClan(siegeclan.getClanId());
  429. for (L2PcInstance member : clan.getOnlineMembers(0))
  430. {
  431. if (clear) member.setSiegeState((byte)0);
  432. else member.setSiegeState((byte)1);
  433. member.sendPacket(new UserInfo(member));
  434. for (L2PcInstance player : member.getKnownList().getKnownPlayers().values()) {
  435. player.sendPacket(new RelationChanged(member, member.getRelation(player), member.isAutoAttackable(player)));
  436. }
  437. }
  438. }
  439. for(L2SiegeClan siegeclan : getDefenderClans())
  440. {
  441. clan = ClanTable.getInstance().getClan(siegeclan.getClanId());
  442. for (L2PcInstance member : clan.getOnlineMembers(0))
  443. {
  444. if (clear) member.setSiegeState((byte)0);
  445. else member.setSiegeState((byte)2);
  446. member.sendPacket(new UserInfo(member));
  447. for (L2PcInstance player : member.getKnownList().getKnownPlayers().values()) {
  448. player.sendPacket(new RelationChanged(member, member.getRelation(player), member.isAutoAttackable(player)));
  449. }
  450. }
  451. }
  452. }
  453. /**
  454. * Approve clan as defender for siege<BR><BR>
  455. * @param clanId The int of player's clan id
  456. */
  457. public void approveSiegeDefenderClan(int clanId)
  458. {
  459. if (clanId <= 0) return;
  460. saveSiegeClan(ClanTable.getInstance().getClan(clanId), 0, true);
  461. loadSiegeClan();
  462. }
  463. /** Return true if object is inside the zone */
  464. public boolean checkIfInZone(L2Object object)
  465. {
  466. return checkIfInZone(object.getX(), object.getY(), object.getZ());
  467. }
  468. /** Return true if object is inside the zone */
  469. public boolean checkIfInZone(int x, int y, int z)
  470. {
  471. return (getIsInProgress() && (getCastle().checkIfInZone(x, y, z))); // Castle zone during siege
  472. }
  473. /**
  474. * Return true if clan is attacker<BR><BR>
  475. * @param clan The L2Clan of the player
  476. */
  477. public boolean checkIsAttacker(L2Clan clan)
  478. {
  479. return (getAttackerClan(clan) != null);
  480. }
  481. /**
  482. * Return true if clan is defender<BR><BR>
  483. * @param clan The L2Clan of the player
  484. */
  485. public boolean checkIsDefender(L2Clan clan)
  486. {
  487. return (getDefenderClan(clan) != null);
  488. }
  489. /**
  490. * Return true if clan is defender waiting approval<BR><BR>
  491. * @param clan The L2Clan of the player
  492. */
  493. public boolean checkIsDefenderWaiting(L2Clan clan)
  494. {
  495. return (getDefenderWaitingClan(clan) != null);
  496. }
  497. /** Clear all registered siege clans from database for castle */
  498. public void clearSiegeClan()
  499. {
  500. java.sql.Connection con = null;
  501. try
  502. {
  503. con = L2DatabaseFactory.getInstance().getConnection();
  504. PreparedStatement statement = con.prepareStatement("DELETE FROM siege_clans WHERE castle_id=?");
  505. statement.setInt(1, getCastle().getCastleId());
  506. statement.execute();
  507. statement.close();
  508. if (getCastle().getOwnerId() > 0)
  509. {
  510. PreparedStatement statement2 = con.prepareStatement("DELETE FROM siege_clans WHERE clan_id=?");
  511. statement2.setInt(1, getCastle().getOwnerId());
  512. statement2.execute();
  513. statement2.close();
  514. }
  515. getAttackerClans().clear();
  516. getDefenderClans().clear();
  517. getDefenderWaitingClans().clear();
  518. }
  519. catch (Exception e)
  520. {
  521. _log.warning("Exception: clearSiegeClan(): " + e.getMessage());
  522. e.printStackTrace();
  523. }
  524. finally
  525. {
  526. try
  527. {
  528. con.close();
  529. }
  530. catch (Exception e)
  531. {
  532. }
  533. }
  534. }
  535. /** Clear all siege clans waiting for approval from database for castle */
  536. public void clearSiegeWaitingClan()
  537. {
  538. java.sql.Connection con = null;
  539. try
  540. {
  541. con = L2DatabaseFactory.getInstance().getConnection();
  542. PreparedStatement statement = con.prepareStatement("DELETE FROM siege_clans WHERE castle_id=? and type = 2");
  543. statement.setInt(1, getCastle().getCastleId());
  544. statement.execute();
  545. statement.close();
  546. getDefenderWaitingClans().clear();
  547. }
  548. catch (Exception e)
  549. {
  550. _log.warning("Exception: clearSiegeWaitingClan(): " + e.getMessage());
  551. e.printStackTrace();
  552. }
  553. finally
  554. {
  555. try
  556. {
  557. con.close();
  558. }
  559. catch (Exception e)
  560. {
  561. }
  562. }
  563. }
  564. /** Return list of L2PcInstance registered as attacker in the zone. */
  565. public List<L2PcInstance> getAttackersInZone()
  566. {
  567. List<L2PcInstance> players = new FastList<L2PcInstance>();
  568. L2Clan clan;
  569. for(L2SiegeClan siegeclan : getAttackerClans())
  570. {
  571. clan = ClanTable.getInstance().getClan(siegeclan.getClanId());
  572. for (L2PcInstance player : clan.getOnlineMembers(0))
  573. {
  574. if (checkIfInZone(player.getX(), player.getY(), player.getZ())) players.add(player);
  575. }
  576. }
  577. return players;
  578. }
  579. /** Return list of L2PcInstance registered as defender but not owner in the zone. */
  580. public List<L2PcInstance> getDefendersButNotOwnersInZone()
  581. {
  582. List<L2PcInstance> players = new FastList<L2PcInstance>();
  583. L2Clan clan;
  584. for(L2SiegeClan siegeclan : getDefenderClans())
  585. {
  586. clan = ClanTable.getInstance().getClan(siegeclan.getClanId());
  587. if (clan.getClanId() == getCastle().getOwnerId()) continue;
  588. for (L2PcInstance player : clan.getOnlineMembers(0))
  589. {
  590. if (checkIfInZone(player.getX(), player.getY(), player.getZ())) players.add(player);
  591. }
  592. }
  593. return players;
  594. }
  595. /** Return list of L2PcInstance in the zone. */
  596. public List<L2PcInstance> getPlayersInZone()
  597. {
  598. return getCastle().getZone().getAllPlayers();
  599. }
  600. /** Return list of L2PcInstance owning the castle in the zone. */
  601. public List<L2PcInstance> getOwnersInZone()
  602. {
  603. List<L2PcInstance> players = new FastList<L2PcInstance>();
  604. L2Clan clan;
  605. for(L2SiegeClan siegeclan : getDefenderClans())
  606. {
  607. clan = ClanTable.getInstance().getClan(siegeclan.getClanId());
  608. if (clan.getClanId() != getCastle().getOwnerId()) continue;
  609. for (L2PcInstance player : clan.getOnlineMembers(0))
  610. {
  611. if (checkIfInZone(player.getX(), player.getY(), player.getZ())) players.add(player);
  612. }
  613. }
  614. return players;
  615. }
  616. /** Return list of L2PcInstance not registered as attacker or defender in the zone. */
  617. public List<L2PcInstance> getSpectatorsInZone()
  618. {
  619. List<L2PcInstance> players = new FastList<L2PcInstance>();
  620. for (L2PcInstance player : L2World.getInstance().getAllPlayers())
  621. {
  622. // quick check from player states, which don't include siege number however
  623. if (!player.isInsideZone(L2Character.ZONE_SIEGE) || player.getSiegeState() != 0) continue;
  624. if ( checkIfInZone(player.getX(), player.getY(), player.getZ()))
  625. players.add(player);
  626. }
  627. return players;
  628. }
  629. /** Control Tower was skilled */
  630. public void killedCT(L2NpcInstance ct)
  631. {
  632. _defenderRespawnDelayPenalty += SiegeManager.getInstance().getControlTowerLosePenalty(); // Add respawn penalty to defenders for each control tower lose
  633. }
  634. /** Remove the flag that was killed */
  635. public void killedFlag(L2NpcInstance flag)
  636. {
  637. if (flag == null) return;
  638. for (int i = 0; i < getAttackerClans().size(); i++)
  639. {
  640. if (getAttackerClan(i).removeFlag(flag)) return;
  641. }
  642. }
  643. /** Display list of registered clans */
  644. public void listRegisterClan(L2PcInstance player)
  645. {
  646. player.sendPacket(new SiegeInfo(getCastle()));
  647. }
  648. /**
  649. * Register clan as attacker<BR><BR>
  650. * @param player The L2PcInstance of the player trying to register
  651. */
  652. public void registerAttacker(L2PcInstance player)
  653. {
  654. registerAttacker(player, false);
  655. }
  656. public void registerAttacker(L2PcInstance player, boolean force)
  657. {
  658. if(player.getClan() == null) return;
  659. int allyId = 0;
  660. if (getCastle().getOwnerId() != 0)
  661. allyId = ClanTable.getInstance().getClan(getCastle().getOwnerId()).getAllyId();
  662. if (allyId != 0)
  663. {
  664. if(player.getClan().getAllyId() == allyId && !force)
  665. {
  666. player.sendMessage("You cannot register as an attacker because your alliance owns the castle");
  667. return;
  668. }
  669. }
  670. if (force || checkIfCanRegister(player)) saveSiegeClan(player.getClan(), 1, false); // Save to database
  671. }
  672. /**
  673. * Register clan as defender<BR><BR>
  674. * @param player The L2PcInstance of the player trying to register
  675. */
  676. public void registerDefender(L2PcInstance player)
  677. {
  678. registerDefender(player, false);
  679. }
  680. public void registerDefender(L2PcInstance player, boolean force)
  681. {
  682. if (getCastle().getOwnerId() <= 0) player.sendMessage("You cannot register as a defender because "
  683. + getCastle().getName() + " is owned by NPC.");
  684. else if (force || checkIfCanRegister(player)) saveSiegeClan(player.getClan(), 2, false); // Save to database
  685. }
  686. /**
  687. * Remove clan from siege<BR><BR>
  688. * @param clanId The int of player's clan id
  689. */
  690. public void removeSiegeClan(int clanId)
  691. {
  692. if (clanId <= 0) return;
  693. java.sql.Connection con = null;
  694. try
  695. {
  696. con = L2DatabaseFactory.getInstance().getConnection();
  697. PreparedStatement statement = con.prepareStatement("DELETE FROM siege_clans WHERE castle_id=? and clan_id=?");
  698. statement.setInt(1, getCastle().getCastleId());
  699. statement.setInt(2, clanId);
  700. statement.execute();
  701. statement.close();
  702. loadSiegeClan();
  703. }
  704. catch (Exception e)
  705. {
  706. }
  707. finally
  708. {
  709. try
  710. {
  711. con.close();
  712. }
  713. catch (Exception e)
  714. {
  715. }
  716. }
  717. }
  718. /**
  719. * Remove clan from siege<BR><BR>
  720. * @param player The L2PcInstance of player/clan being removed
  721. */
  722. public void removeSiegeClan(L2Clan clan)
  723. {
  724. if (clan == null || clan.getHasCastle() == getCastle().getCastleId()
  725. || !SiegeManager.getInstance().checkIsRegistered(clan, getCastle().getCastleId())) return;
  726. removeSiegeClan(clan.getClanId());
  727. }
  728. /**
  729. * Remove clan from siege<BR><BR>
  730. * @param player The L2PcInstance of player/clan being removed
  731. */
  732. public void removeSiegeClan(L2PcInstance player)
  733. {
  734. removeSiegeClan(player.getClan());
  735. }
  736. /**
  737. * Start the auto tasks<BR><BR>
  738. */
  739. public void startAutoTask()
  740. {
  741. correctSiegeDateTime();
  742. _log.info("Siege of " + getCastle().getName() + ": "
  743. + getCastle().getSiegeDate().getTime());
  744. loadSiegeClan();
  745. // Schedule registration end
  746. _siegeRegistrationEndDate = Calendar.getInstance();
  747. _siegeRegistrationEndDate.setTimeInMillis(getCastle().getSiegeDate().getTimeInMillis());
  748. _siegeRegistrationEndDate.add(Calendar.DAY_OF_MONTH, -1);
  749. // Schedule siege auto start
  750. ThreadPoolManager.getInstance().scheduleGeneral(new Siege.ScheduleStartSiegeTask(getCastle()),
  751. 1000);
  752. }
  753. /**
  754. * Teleport players
  755. */
  756. public void teleportPlayer(TeleportWhoType teleportWho,
  757. MapRegionTable.TeleportWhereType teleportWhere)
  758. {
  759. List<L2PcInstance> players;
  760. switch (teleportWho)
  761. {
  762. case Owner:
  763. players = getOwnersInZone();
  764. break;
  765. case Attacker:
  766. players = getAttackersInZone();
  767. break;
  768. case DefenderNotOwner:
  769. players = getDefendersButNotOwnersInZone();
  770. break;
  771. case Spectator:
  772. players = getSpectatorsInZone();
  773. break;
  774. default:
  775. players = getPlayersInZone();
  776. }
  777. ;
  778. for (L2PcInstance player : players)
  779. {
  780. if (player.isGM() || player.isInJail()) continue;
  781. player.teleToLocation(teleportWhere);
  782. }
  783. }
  784. // =========================================================
  785. // Method - Private
  786. /**
  787. * Add clan as attacker<BR><BR>
  788. * @param clanId The int of clan's id
  789. */
  790. private void addAttacker(int clanId)
  791. {
  792. getAttackerClans().add(new L2SiegeClan(clanId, SiegeClanType.ATTACKER)); // Add registered attacker to attacker list
  793. }
  794. /**
  795. * Add clan as defender<BR><BR>
  796. * @param clanId The int of clan's id
  797. */
  798. private void addDefender(int clanId)
  799. {
  800. getDefenderClans().add(new L2SiegeClan(clanId, SiegeClanType.DEFENDER)); // Add registered defender to defender list
  801. }
  802. /**
  803. * <p>Add clan as defender with the specified type</p>
  804. * @param clanId The int of clan's id
  805. * @param type the type of the clan
  806. */
  807. private void addDefender(int clanId, SiegeClanType type)
  808. {
  809. getDefenderClans().add(new L2SiegeClan(clanId, type));
  810. }
  811. /**
  812. * Add clan as defender waiting approval<BR><BR>
  813. * @param clanId The int of clan's id
  814. */
  815. private void addDefenderWaiting(int clanId)
  816. {
  817. getDefenderWaitingClans().add(new L2SiegeClan(clanId, SiegeClanType.DEFENDER_PENDING)); // Add registered defender to defender list
  818. }
  819. /**
  820. * Return true if the player can register.<BR><BR>
  821. * @param player The L2PcInstance of the player trying to register
  822. */
  823. private boolean checkIfCanRegister(L2PcInstance player)
  824. {
  825. if (getIsRegistrationOver())
  826. player.sendMessage("The deadline to register for the siege of "
  827. + getCastle().getName() + " has passed.");
  828. else if (getIsInProgress())
  829. player.sendMessage("This is not the time for siege registration and so registration and cancellation cannot be done.");
  830. else if (player.getClan() == null || player.getClan().getLevel() < SiegeManager.getInstance().getSiegeClanMinLevel())
  831. player.sendMessage("Only clans with Level "
  832. + SiegeManager.getInstance().getSiegeClanMinLevel()
  833. + " and higher may register for a castle siege.");
  834. else if (player.getClan().getHasCastle() > 0)
  835. player.sendMessage("You cannot register because your clan already owns a castle.");
  836. else if (player.getClan().getClanId() == getCastle().getOwnerId())
  837. player.sendPacket(new SystemMessage(SystemMessageId.CLAN_THAT_OWNS_CASTLE_IS_AUTOMATICALLY_REGISTERED_DEFENDING));
  838. else if (SiegeManager.getInstance().checkIsRegistered(player.getClan(), getCastle().getCastleId()))
  839. player.sendPacket(new SystemMessage(SystemMessageId.ALREADY_REQUESTED_SIEGE_BATTLE));
  840. else if (checkIfAlreadyRegisteredForSameDay(player.getClan()))
  841. player.sendPacket(new SystemMessage(SystemMessageId.APPLICATION_DENIED_BECAUSE_ALREADY_SUBMITTED_A_REQUEST_FOR_ANOTHER_SIEGE_BATTLE));
  842. else return true;
  843. return false;
  844. }
  845. /**
  846. * Return true if the clan has already registered to a siege for the same day.<BR><BR>
  847. * @param clan The L2Clan of the player trying to register
  848. */
  849. public boolean checkIfAlreadyRegisteredForSameDay(L2Clan clan)
  850. {
  851. for (Siege siege : SiegeManager.getInstance().getSieges())
  852. {
  853. if (siege == this) continue;
  854. if (siege.getSiegeDate().get(Calendar.DAY_OF_WEEK) == this.getSiegeDate().get(Calendar.DAY_OF_WEEK))
  855. {
  856. if (siege.checkIsAttacker(clan)) return true;
  857. if (siege.checkIsDefender(clan)) return true;
  858. if (siege.checkIsDefenderWaiting(clan)) return true;
  859. }
  860. }
  861. return false;
  862. }
  863. /**
  864. * Return the correct siege date as Calendar.<BR><BR>
  865. * @param siegeDate The Calendar siege date and time
  866. */
  867. private void correctSiegeDateTime()
  868. {
  869. boolean corrected = false;
  870. if (getCastle().getSiegeDate().getTimeInMillis() < Calendar.getInstance().getTimeInMillis())
  871. {
  872. // Since siege has past reschedule it to the next one (14 days)
  873. // This is usually caused by server being down
  874. corrected = true;
  875. setNextSiegeDate();
  876. }
  877. if (getCastle().getSiegeDate().get(Calendar.DAY_OF_WEEK) != getCastle().getSiegeDayOfWeek())
  878. {
  879. corrected = true;
  880. getCastle().getSiegeDate().set(Calendar.DAY_OF_WEEK, getCastle().getSiegeDayOfWeek());
  881. }
  882. if (getCastle().getSiegeDate().get(Calendar.HOUR_OF_DAY) != getCastle().getSiegeHourOfDay())
  883. {
  884. corrected = true;
  885. getCastle().getSiegeDate().set(Calendar.HOUR_OF_DAY, getCastle().getSiegeHourOfDay());
  886. }
  887. getCastle().getSiegeDate().set(Calendar.MINUTE, 0);
  888. if (corrected) saveSiegeDate();
  889. }
  890. /** Load siege clans. */
  891. private void loadSiegeClan()
  892. {
  893. java.sql.Connection con = null;
  894. try
  895. {
  896. getAttackerClans().clear();
  897. getDefenderClans().clear();
  898. getDefenderWaitingClans().clear();
  899. // Add castle owner as defender (add owner first so that they are on the top of the defender list)
  900. if (getCastle().getOwnerId() > 0)
  901. addDefender(getCastle().getOwnerId(), SiegeClanType.OWNER);
  902. PreparedStatement statement = null;
  903. ResultSet rs = null;
  904. con = L2DatabaseFactory.getInstance().getConnection();
  905. statement = con.prepareStatement("SELECT clan_id,type FROM siege_clans where castle_id=?");
  906. statement.setInt(1, getCastle().getCastleId());
  907. rs = statement.executeQuery();
  908. int typeId;
  909. while (rs.next())
  910. {
  911. typeId = rs.getInt("type");
  912. if (typeId == 0) addDefender(rs.getInt("clan_id"));
  913. else if (typeId == 1) addAttacker(rs.getInt("clan_id"));
  914. else if (typeId == 2) addDefenderWaiting(rs.getInt("clan_id"));
  915. }
  916. statement.close();
  917. }
  918. catch (Exception e)
  919. {
  920. _log.warning("Exception: loadSiegeClan(): " + e.getMessage());
  921. e.printStackTrace();
  922. }
  923. finally
  924. {
  925. try
  926. {
  927. con.close();
  928. }
  929. catch (Exception e)
  930. {
  931. }
  932. }
  933. }
  934. /** Remove all control tower spawned. */
  935. private void removeControlTower()
  936. {
  937. if (_controlTowers != null)
  938. {
  939. // Remove all instance of control tower for this castle
  940. for (L2ControlTowerInstance ct : _controlTowers)
  941. {
  942. if (ct != null) ct.decayMe();
  943. }
  944. _controlTowers = null;
  945. }
  946. }
  947. /** Remove all flags. */
  948. private void removeFlags()
  949. {
  950. for (L2SiegeClan sc : getAttackerClans())
  951. {
  952. if (sc != null) sc.removeFlags();
  953. }
  954. for (L2SiegeClan sc : getDefenderClans())
  955. {
  956. if (sc != null) sc.removeFlags();
  957. }
  958. }
  959. /** Remove flags from defenders. */
  960. private void removeDefenderFlags()
  961. {
  962. for (L2SiegeClan sc : getDefenderClans())
  963. {
  964. if (sc != null) sc.removeFlags();
  965. }
  966. }
  967. /** Save castle siege related to database. */
  968. private void saveCastleSiege()
  969. {
  970. setNextSiegeDate(); // Set the next set date for 2 weeks from now
  971. saveSiegeDate(); // Save the new date
  972. startAutoTask(); // Prepare auto start siege and end registration
  973. }
  974. /** Save siege date to database. */
  975. private void saveSiegeDate()
  976. {
  977. java.sql.Connection con = null;
  978. try
  979. {
  980. con = L2DatabaseFactory.getInstance().getConnection();
  981. PreparedStatement statement = con.prepareStatement("Update castle set siegeDate = ? where id = ?");
  982. statement.setLong(1, getSiegeDate().getTimeInMillis());
  983. statement.setInt(2, getCastle().getCastleId());
  984. statement.execute();
  985. statement.close();
  986. }
  987. catch (Exception e)
  988. {
  989. _log.warning("Exception: saveSiegeDate(): " + e.getMessage());
  990. e.printStackTrace();
  991. }
  992. finally
  993. {
  994. try
  995. {
  996. con.close();
  997. }
  998. catch (Exception e)
  999. {
  1000. }
  1001. }
  1002. }
  1003. /**
  1004. * Save registration to database.<BR><BR>
  1005. * @param clan The L2Clan of player
  1006. * @param typeId -1 = owner 0 = defender, 1 = attacker, 2 = defender waiting
  1007. */
  1008. private void saveSiegeClan(L2Clan clan, int typeId, boolean isUpdateRegistration)
  1009. {
  1010. if (clan.getHasCastle() > 0) return;
  1011. java.sql.Connection con = null;
  1012. try
  1013. {
  1014. if (typeId == 0 || typeId == 2 || typeId == -1)
  1015. {
  1016. if (getDefenderClans().size() + getDefenderWaitingClans().size() >= SiegeManager.getInstance().getDefenderMaxClans())
  1017. return;
  1018. }
  1019. else
  1020. {
  1021. if (getAttackerClans().size() >= SiegeManager.getInstance().getAttackerMaxClans())
  1022. return;
  1023. }
  1024. con = L2DatabaseFactory.getInstance().getConnection();
  1025. PreparedStatement statement;
  1026. if (!isUpdateRegistration)
  1027. {
  1028. statement = con.prepareStatement("INSERT INTO siege_clans (clan_id,castle_id,type,castle_owner) values (?,?,?,0)");
  1029. statement.setInt(1, clan.getClanId());
  1030. statement.setInt(2, getCastle().getCastleId());
  1031. statement.setInt(3, typeId);
  1032. statement.execute();
  1033. statement.close();
  1034. }
  1035. else
  1036. {
  1037. statement = con.prepareStatement("Update siege_clans set type = ? where castle_id = ? and clan_id = ?");
  1038. statement.setInt(1, typeId);
  1039. statement.setInt(2, getCastle().getCastleId());
  1040. statement.setInt(3, clan.getClanId());
  1041. statement.execute();
  1042. statement.close();
  1043. }
  1044. if (typeId == 0 || typeId == -1)
  1045. {
  1046. addDefender(clan.getClanId());
  1047. announceToPlayer(clan.getName() + " has been registered to defend "
  1048. + getCastle().getName(), false);
  1049. }
  1050. else if (typeId == 1)
  1051. {
  1052. addAttacker(clan.getClanId());
  1053. announceToPlayer(clan.getName() + " has been registered to attack "
  1054. + getCastle().getName(), false);
  1055. }
  1056. else if (typeId == 2)
  1057. {
  1058. addDefenderWaiting(clan.getClanId());
  1059. announceToPlayer(clan.getName() + " has requested to defend " + getCastle().getName(),
  1060. false);
  1061. }
  1062. }
  1063. catch (Exception e)
  1064. {
  1065. _log.warning("Exception: saveSiegeClan(L2Clan clan, int typeId, boolean isUpdateRegistration): "
  1066. + e.getMessage());
  1067. e.printStackTrace();
  1068. }
  1069. finally
  1070. {
  1071. try
  1072. {
  1073. con.close();
  1074. }
  1075. catch (Exception e)
  1076. {
  1077. }
  1078. }
  1079. }
  1080. /** Set the date for the next siege. */
  1081. private void setNextSiegeDate()
  1082. {
  1083. while (getCastle().getSiegeDate().getTimeInMillis() < Calendar.getInstance().getTimeInMillis())
  1084. {
  1085. // Set next siege date if siege has passed
  1086. getCastle().getSiegeDate().add(Calendar.DAY_OF_MONTH, 14); // Schedule to happen in 14 days
  1087. }
  1088. _isRegistrationOver = false; // Allow registration for next siege
  1089. }
  1090. /** Spawn control tower. */
  1091. private void spawnControlTower(int Id)
  1092. {
  1093. //Set control tower array size if one does not exist
  1094. if (_controlTowers == null)
  1095. _controlTowers = new FastList<L2ControlTowerInstance>();
  1096. for (SiegeSpawn _sp: SiegeManager.getInstance().getControlTowerSpawnList(Id))
  1097. {
  1098. L2ControlTowerInstance ct;
  1099. L2NpcTemplate template = NpcTable.getInstance().getTemplate(_sp.getNpcId());
  1100. // TODO: Check/confirm if control towers have any special weapon resistances/vulnerabilities
  1101. // template.addVulnerability(Stats.BOW_WPN_VULN,0);
  1102. // template.addVulnerability(Stats.BLUNT_WPN_VULN,0);
  1103. // template.addVulnerability(Stats.DAGGER_WPN_VULN,0);
  1104. ct = new L2ControlTowerInstance(IdFactory.getInstance().getNextId(), template);
  1105. ct.setCurrentHpMp(_sp.getHp(), ct.getMaxMp());
  1106. ct.spawnMe(_sp.getLocation().getX(),_sp.getLocation().getY(),_sp.getLocation().getZ() + 20);
  1107. _controlTowers.add(ct);
  1108. }
  1109. }
  1110. /**
  1111. * Spawn siege guard.<BR><BR>
  1112. */
  1113. private void spawnSiegeGuard()
  1114. {
  1115. getSiegeGuardManager().spawnSiegeGuard();
  1116. // Register guard to the closest Control Tower
  1117. // When CT dies, so do all the guards that it controls
  1118. if (getSiegeGuardManager().getSiegeGuardSpawn().size() > 0 && _controlTowers.size() > 0)
  1119. {
  1120. L2ControlTowerInstance closestCt;
  1121. double distance, x, y, z;
  1122. double distanceClosest = 0;
  1123. for (L2Spawn spawn : getSiegeGuardManager().getSiegeGuardSpawn())
  1124. {
  1125. if (spawn == null) continue;
  1126. closestCt = null;
  1127. distanceClosest = 0;
  1128. for (L2ControlTowerInstance ct : _controlTowers)
  1129. {
  1130. if (ct == null) continue;
  1131. x = (spawn.getLocx() - ct.getX());
  1132. y = (spawn.getLocy() - ct.getY());
  1133. z = (spawn.getLocz() - ct.getZ());
  1134. distance = (x * x) + (y * y) + (z * z);
  1135. if (closestCt == null || distance < distanceClosest)
  1136. {
  1137. closestCt = ct;
  1138. distanceClosest = distance;
  1139. }
  1140. }
  1141. if (closestCt != null) closestCt.registerGuard(spawn);
  1142. }
  1143. }
  1144. }
  1145. public final L2SiegeClan getAttackerClan(L2Clan clan)
  1146. {
  1147. if (clan == null) return null;
  1148. return getAttackerClan(clan.getClanId());
  1149. }
  1150. public final L2SiegeClan getAttackerClan(int clanId)
  1151. {
  1152. for (L2SiegeClan sc : getAttackerClans())
  1153. if (sc != null && sc.getClanId() == clanId) return sc;
  1154. return null;
  1155. }
  1156. public final List<L2SiegeClan> getAttackerClans()
  1157. {
  1158. if (_isNormalSide) return _attackerClans;
  1159. return _defenderClans;
  1160. }
  1161. public final int getAttackerRespawnDelay()
  1162. {
  1163. return (SiegeManager.getInstance().getAttackerRespawnDelay());
  1164. }
  1165. public final Castle getCastle()
  1166. {
  1167. if (_castle == null || _castle.length <= 0) return null;
  1168. return _castle[0];
  1169. }
  1170. public final L2SiegeClan getDefenderClan(L2Clan clan)
  1171. {
  1172. if (clan == null) return null;
  1173. return getDefenderClan(clan.getClanId());
  1174. }
  1175. public final L2SiegeClan getDefenderClan(int clanId)
  1176. {
  1177. for (L2SiegeClan sc : getDefenderClans())
  1178. if (sc != null && sc.getClanId() == clanId) return sc;
  1179. return null;
  1180. }
  1181. public final List<L2SiegeClan> getDefenderClans()
  1182. {
  1183. if (_isNormalSide) return _defenderClans;
  1184. return _attackerClans;
  1185. }
  1186. public final L2SiegeClan getDefenderWaitingClan(L2Clan clan)
  1187. {
  1188. if (clan == null) return null;
  1189. return getDefenderWaitingClan(clan.getClanId());
  1190. }
  1191. public final L2SiegeClan getDefenderWaitingClan(int clanId)
  1192. {
  1193. for (L2SiegeClan sc : getDefenderWaitingClans())
  1194. if (sc != null && sc.getClanId() == clanId) return sc;
  1195. return null;
  1196. }
  1197. public final List<L2SiegeClan> getDefenderWaitingClans()
  1198. {
  1199. return _defenderWaitingClans;
  1200. }
  1201. public final int getDefenderRespawnDelay()
  1202. {
  1203. return (SiegeManager.getInstance().getDefenderRespawnDelay() + _defenderRespawnDelayPenalty);
  1204. }
  1205. public final boolean getIsInProgress()
  1206. {
  1207. return _isInProgress;
  1208. }
  1209. public final boolean getIsRegistrationOver()
  1210. {
  1211. return _isRegistrationOver;
  1212. }
  1213. public final Calendar getSiegeDate()
  1214. {
  1215. return getCastle().getSiegeDate();
  1216. }
  1217. public List<L2NpcInstance> getFlag(L2Clan clan)
  1218. {
  1219. if (clan != null)
  1220. {
  1221. L2SiegeClan sc = getAttackerClan(clan);
  1222. if (sc != null) return sc.getFlag();
  1223. }
  1224. return null;
  1225. }
  1226. public final SiegeGuardManager getSiegeGuardManager()
  1227. {
  1228. if (_siegeGuardManager == null)
  1229. {
  1230. _siegeGuardManager = new SiegeGuardManager(getCastle());
  1231. }
  1232. return _siegeGuardManager;
  1233. }
  1234. }