· 8 years ago · Mar 01, 2018, 12:42 PM
1### Eclipse Workspace Patch 1.0
2#P aCis_gameserver
3Index: java/net/sf/l2j/gameserver/model/L2Radar.java
4===================================================================
5--- java/net/sf/l2j/gameserver/model/L2Radar.java (revision 447)
6+++ java/net/sf/l2j/gameserver/model/L2Radar.java (working copy)
7@@ -3,6 +3,8 @@
8 import java.util.ArrayList;
9 import java.util.List;
10
11+import net.sf.l2j.commons.concurrent.ThreadPool;
12+
13 import net.sf.l2j.gameserver.model.actor.instance.Player;
14 import net.sf.l2j.gameserver.network.serverpackets.RadarControl;
15
16@@ -121,4 +123,35 @@
17 return true;
18 }
19 }
20+
21+ public class RadarOnPlayer implements Runnable
22+ {
23+ private final Player _myTarget, _me;
24+
25+ public RadarOnPlayer(Player target, Player me)
26+ {
27+ _me = me;
28+ _myTarget = target;
29+ }
30+
31+ @Override
32+ public void run()
33+ {
34+ try
35+ {
36+ if (_me == null || _me.isOnlineInt() == 0)
37+ return;
38+ _me.sendPacket(new RadarControl(1, 1, _me.getX(), _me.getY(), _me.getZ()));
39+ if (_myTarget == null || _myTarget.isOnlineInt() == 0 || !_myTarget._haveFlagCTF)
40+ {
41+ return;
42+ }
43+ _me.sendPacket(new RadarControl(0, 1, _myTarget.getX(), _myTarget.getY(), _myTarget.getZ()));
44+ ThreadPool.schedule(new RadarOnPlayer(_myTarget, _me), 15000);
45+ }
46+ catch (Throwable t)
47+ {
48+ }
49+ }
50+ }
51 }
52\ No newline at end of file
53Index: config/eventmanager.properties
54===================================================================
55--- config/eventmanager.properties (revision 448)
56+++ config/eventmanager.properties (working copy)
57@@ -4,4 +4,9 @@
58 # Enable TvT event and start time.
59 # Example TVTStartTime=20:00;21:00;22:00;
60 TVTEventEnabled = True
61-TVTStartTime = 00:00;02:00;04:00;06:00;08:00;10:00;12:00;14:00;16:00;18:00;20:00;22:00;
62+TVTStartTime = 00:00;04:00;08:00;12:00;16:00;20:00;
63+
64+# Enable CTF event and start time
65+# Example CTFStartTime=20:00;21:00;22:00;
66+CTFEventEnabled = True
67+CTFStartTime = 02:00;06:00;10:00;14:00;18:00;22:00;
68\ No newline at end of file
69Index: java/net/sf/l2j/gameserver/model/actor/instance/WeddingManagerNpc.java
70===================================================================
71--- java/net/sf/l2j/gameserver/model/actor/instance/WeddingManagerNpc.java (revision 447)
72+++ java/net/sf/l2j/gameserver/model/actor/instance/WeddingManagerNpc.java (working copy)
73@@ -6,6 +6,7 @@
74
75 import net.sf.l2j.Config;
76 import net.sf.l2j.gameserver.data.SkillTable.FrequentSkill;
77+import net.sf.l2j.gameserver.event.CTF;
78 import net.sf.l2j.gameserver.event.TvT;
79 import net.sf.l2j.gameserver.instancemanager.CastleManager;
80 import net.sf.l2j.gameserver.instancemanager.CoupleManager;
81@@ -118,9 +119,9 @@
82 return;
83 }
84
85- if (partner._inEventTvT && TvT.is_started())
86+ if (partner._inEventTvT && TvT.is_started() || partner._inEventCTF && CTF.is_started())
87 {
88- player.sendMessage("You may not use go to love in TvT.");
89+ player.sendMessage("As your partner is in event, you can't go to him/her.");
90 return;
91 }
92
93Index: java/net/sf/l2j/gameserver/network/clientpackets/AttackRequest.java
94===================================================================
95--- java/net/sf/l2j/gameserver/network/clientpackets/AttackRequest.java (revision 447)
96+++ java/net/sf/l2j/gameserver/network/clientpackets/AttackRequest.java (working copy)
97@@ -1,5 +1,6 @@
98 package net.sf.l2j.gameserver.network.clientpackets;
99
100+import net.sf.l2j.gameserver.event.CTF;
101 import net.sf.l2j.gameserver.event.TvT;
102 import net.sf.l2j.gameserver.model.World;
103 import net.sf.l2j.gameserver.model.WorldObject;
104@@ -52,7 +53,7 @@
105 return;
106
107 // During teleport phase, players cant do any attack
108- if ((TvT.is_teleport() && activeChar._inEventTvT))
109+ if ((TvT.is_teleport() && activeChar._inEventTvT) || (CTF.is_teleport() && activeChar._inEventCTF))
110 {
111 activeChar.sendPacket(ActionFailed.STATIC_PACKET);
112 return;
113@@ -79,6 +80,27 @@
114 }
115 }
116
117+ // No attacks to same team in Event
118+ if (CTF.is_started())
119+ {
120+ if (target instanceof Player)
121+ {
122+ if ((activeChar._inEventCTF && ((Player) target)._inEventCTF) && activeChar._teamNameCTF.equals(((Player) target)._teamNameCTF))
123+ {
124+ activeChar.sendPacket(ActionFailed.STATIC_PACKET);
125+ return;
126+ }
127+ }
128+ else if (target instanceof Servitor)
129+ {
130+ if ((activeChar._inEventCTF && ((Servitor) target).getOwner()._inEventCTF) && activeChar._teamNameCTF.equals(((Servitor) target).getOwner()._teamNameCTF))
131+ {
132+ activeChar.sendPacket(ActionFailed.STATIC_PACKET);
133+ return;
134+ }
135+ }
136+ }
137+
138 if (activeChar.getTarget() != target)
139 target.onAction(activeChar);
140 else
141Index: java/net/sf/l2j/gameserver/handler/itemhandlers/SummonItems.java
142===================================================================
143--- java/net/sf/l2j/gameserver/handler/itemhandlers/SummonItems.java (revision 447)
144+++ java/net/sf/l2j/gameserver/handler/itemhandlers/SummonItems.java (working copy)
145@@ -7,6 +7,7 @@
146 import net.sf.l2j.Config;
147 import net.sf.l2j.gameserver.data.NpcTable;
148 import net.sf.l2j.gameserver.data.xml.SummonItemData;
149+import net.sf.l2j.gameserver.event.CTF;
150 import net.sf.l2j.gameserver.event.TvT;
151 import net.sf.l2j.gameserver.handler.IItemHandler;
152 import net.sf.l2j.gameserver.model.L2Spawn;
153@@ -46,12 +46,11 @@
154 }
155+
156+ if (activeChar._inEventCTF && CTF.is_started() && !Config.CTF_ALLOW_SUMMON)
157+ return;
158+
159 if (activeChar.isInObserverMode())
160 return;
161
162Index: java/net/sf/l2j/gameserver/model/actor/Creature.java
163===================================================================
164--- java/net/sf/l2j/gameserver/model/actor/Creature.java (revision 448)
165+++ java/net/sf/l2j/gameserver/model/actor/Creature.java (working copy)
166@@ -16,6 +16,7 @@
167 import net.sf.l2j.gameserver.data.MapRegionTable;
168 import net.sf.l2j.gameserver.data.MapRegionTable.TeleportType;
169 import net.sf.l2j.gameserver.data.SkillTable.FrequentSkill;
170+import net.sf.l2j.gameserver.event.CTF;
171 import net.sf.l2j.gameserver.event.L2Event;
172 import net.sf.l2j.gameserver.event.TvT;
173 import net.sf.l2j.gameserver.geoengine.GeoEngine;
174@@ -163,6 +164,9 @@
175
176 private boolean _isRaid = false;
177
178+ public boolean _inEventTvT = false;
179+ public boolean _inEventCTF = false;
180+
181 /**
182 * Constructor of Creature.<BR>
183 * <BR>
184@@ -558,6 +562,13 @@
185 return;
186 }
187
188+ // during teleport phase, players can't do any attack
189+ if ((TvT.is_teleport() && _inEventTvT) || (CTF.is_teleport() && _inEventCTF))
190+ {
191+ sendPacket(ActionFailed.STATIC_PACKET);
192+ return;
193+ }
194+
195 stopEffectsOnAction();
196
197 // Get the active weapon item corresponding to the active weapon instance (always equipped in the right hand)
198@@ -1075,6 +1086,13 @@
199 return;
200 }
201
202+ // during teleport phase, players cant do any attack
203+ if ((TvT.is_teleport() && _inEventTvT) || (CTF.is_teleport() && _inEventCTF))
204+ {
205+ sendPacket(ActionFailed.STATIC_PACKET);
206+ return;
207+ }
208+
209 // Override casting type
210 if (skill.isSimultaneousCast() && !simultaneously)
211 simultaneously = true;
212@@ -3359,7 +3377,7 @@
213 ((Player) this).getClient().sendPacket(ActionFailed.STATIC_PACKET);
214 return;
215 }
216- else if ((TvT.is_sitForced() && ((Player) this)._inEventTvT))
217+ else if ((TvT.is_sitForced() && ((Player) this)._inEventTvT) || (CTF.is_sitForced() && ((Player) this)._inEventCTF))
218 {
219 ((Player) this).getClient().sendPacket(ActionFailed.STATIC_PACKET);
220 return;
221@@ -4138,8 +4156,10 @@
222 if (dst.isInFunEvent() && src.isInFunEvent())
223 {
224 if (src.isInStartedTVTEvent() && dst.isInStartedTVTEvent())
225- return false;
226- }
227+ return false;
228+ if (src.isInStartedCTFEvent() && dst.isInStartedCTFEvent())
229+ return false;
230+ }
231 }
232
233 return (MapRegionTable.getTown(target.getX(), target.getY(), target.getZ()) != null || attacker.isInsideZone(ZoneId.PEACE));
234Index: java/net/sf/l2j/gameserver/model/actor/Playable.java
235===================================================================
236--- java/net/sf/l2j/gameserver/model/actor/Playable.java (revision 447)
237+++ java/net/sf/l2j/gameserver/model/actor/Playable.java (working copy)
238@@ -1,6 +1,7 @@
239 package net.sf.l2j.gameserver.model.actor;
240
241 import net.sf.l2j.Config;
242+import net.sf.l2j.gameserver.event.CTF;
243 import net.sf.l2j.gameserver.event.TvT;
244 import net.sf.l2j.gameserver.model.L2Effect;
245 import net.sf.l2j.gameserver.model.L2Skill;
246@@ -121,14 +122,19 @@
247 stopCharmOfLuck(null);
248 }
249 else
250- {
251+ {
252 if ((this instanceof Player && ((Player) this)._inEventTvT && TvT.is_started()))
253 {
254 if (Config.TVT_REMOVE_BUFFS_ON_DIE)
255 stopAllEffectsExceptThoseThatLastThroughDeath();
256 }
257+ else if ((this instanceof Player && ((Player) this)._inEventCTF && CTF.is_started()))
258+ {
259+ if (Config.CTF_REMOVE_BUFFS_ON_DIE)
260+ stopAllEffects();
261+ }
262 else if (Config.LEAVE_BUFFS_ON_DIE)
263- stopAllEffectsExceptThoseThatLastThroughDeath();
264+ stopAllEffectsExceptThoseThatLastThroughDeath();
265 }
266
267 // Send the Server->Client packet StatusUpdate with current HP and MP to all other Player to inform
268Index: java/net/sf/l2j/gameserver/handler/VoicedCommandHandler.java
269===================================================================
270--- java/net/sf/l2j/gameserver/handler/VoicedCommandHandler.java (revision 449)
271+++ java/net/sf/l2j/gameserver/handler/VoicedCommandHandler.java (working copy)
272@@ -19,6 +19,7 @@
273
274 import net.sf.l2j.Config;
275 import net.sf.l2j.gameserver.handler.voicedcommandhandlers.BankingCmd;
276+import net.sf.l2j.gameserver.handler.voicedcommandhandlers.CTFCmd;
277 import net.sf.l2j.gameserver.handler.voicedcommandhandlers.GainXpSp;
278 import net.sf.l2j.gameserver.handler.voicedcommandhandlers.Online;
279 import net.sf.l2j.gameserver.handler.voicedcommandhandlers.TvTCmd;
280@@ -38,6 +39,10 @@
281 {
282 registerHandler(new BankingCmd());
283 }
284+ if (Config.CTF_COMMAND)
285+ {
286+ registerHandler(new CTFCmd());
287+ }
288 if (Config.TVT_COMMAND)
289 {
290 registerHandler(new TvTCmd());
291Index: java/net/sf/l2j/gameserver/model/actor/instance/Player.java
292===================================================================
293--- java/net/sf/l2j/gameserver/model/actor/instance/Player.java (revision 449)
294+++ java/net/sf/l2j/gameserver/model/actor/instance/Player.java (working copy)
295@@ -46,6 +46,8 @@
296 import net.sf.l2j.gameserver.data.xml.AdminData;
297 import net.sf.l2j.gameserver.data.xml.FishData;
298 import net.sf.l2j.gameserver.data.xml.HennaData;
299+import net.sf.l2j.gameserver.event.CTF;
300+import net.sf.l2j.gameserver.event.L2Event;
301 import net.sf.l2j.gameserver.event.TvT;
302 import net.sf.l2j.gameserver.geoengine.GeoEngine;
303 import net.sf.l2j.gameserver.handler.IItemHandler;
304@@ -505,6 +507,14 @@
305 public int _originalNameColorTvT = 0, _countTvTkills, _countTvTdies, _originalKarmaTvT;
306 /** The _in event tv t. */
307 public boolean _inEventTvT = false;
308+ /** CTF Engine parameters. */
309+ public String _teamNameCTF, _teamNameHaveFlagCTF, _originalTitleCTF;
310+ /** The _count ct fflags. */
311+ public int _originalNameColorCTF = 0, _originalKarmaCTF, _countCTFflags;
312+ /** The _have flag ctf. */
313+ public boolean _inEventCTF = false, _haveFlagCTF = false;
314+ /** The _pos checker ctf. */
315+ public Future<?> _posCheckerCTF = null;
316 /** Event Engine parameters. */
317 public int _originalNameColor, _countKills, _originalKarma, _eventKills;
318 /** The _in event. */
319@@ -2234,6 +2244,11 @@
320 }, 2500);
321 setIsParalyzed(true);
322 }
323+
324+ if (L2Event.active && eventSitForced)
325+ return;
326+ else if ((TvT.is_sitForced() && _inEventTvT) || (CTF.is_sitForced() && _inEventCTF))
327+ return;
328 }
329
330 /**
331@@ -3227,7 +3242,7 @@
332 }
333
334 // During teleport phase, players cant do any attack
335- if ((TvT.is_teleport() && _inEventTvT))
336+ if ((TvT.is_teleport() && _inEventTvT) || (CTF.is_teleport() && _inEventCTF))
337 {
338 sendPacket(ActionFailed.STATIC_PACKET);
339 return false;
340@@ -3254,7 +3269,7 @@
341 public void onAction(Player player)
342 {
343 // no Interaction with not participant to events
344- if (((TvT.is_started() || TvT.is_teleport()) && !Config.TVT_ALLOW_INTERFERENCE))
345+ if (((TvT.is_started() || TvT.is_teleport()) && !Config.TVT_ALLOW_INTERFERENCE) || ((CTF.is_started() || CTF.is_teleport()) && !Config.CTF_ALLOW_INTERFERENCE))
346 {
347 if ((_inEventTvT && !player._inEventTvT) || (!_inEventTvT && player._inEventTvT))
348 {
349@@ -3261,6 +3276,11 @@
350 player.sendPacket(ActionFailed.STATIC_PACKET);
351 return;
352 }
353+ else if ((_inEventCTF && !player._inEventCTF) || (!_inEventCTF && player._inEventCTF))
354+ {
355+ player.sendPacket(ActionFailed.STATIC_PACKET);
356+ return;
357+ }
358 }
359
360 // Set the target of the player
361@@ -3307,7 +3327,7 @@
362 {
363 if (player.isGM())
364 AdminEditChar.showCharacterInfo(player, this);
365- else if (((TvT.is_started() || TvT.is_teleport()) && !Config.TVT_ALLOW_INTERFERENCE))
366+ else if (((TvT.is_started() || TvT.is_teleport()) && !Config.TVT_ALLOW_INTERFERENCE) || ((CTF.is_started() || CTF.is_teleport()) && !Config.CTF_ALLOW_INTERFERENCE))
367 {
368 if ((_inEventTvT && !player._inEventTvT) || (!_inEventTvT && player._inEventTvT))
369 {
370@@ -3314,6 +3334,11 @@
371 player.sendPacket(ActionFailed.STATIC_PACKET);
372 return;
373 }
374+ else if ((_inEventCTF && !player._inEventCTF) || (!_inEventCTF && player._inEventCTF))
375+ {
376+ player.sendPacket(ActionFailed.STATIC_PACKET);
377+ return;
378+ }
379 }
380
381 super.onActionShift(player);
382@@ -3321,12 +3346,12 @@
383
384 /*
385 * (non-Javadoc)
386- * @see com.l2jfrozen.gameserver.model.actor.instance.L2PlayableInstance#isInFunEvent()
387+ * @see net.sf.l2j.gameserver.actor.Playable#isInFunEvent()
388 */
389 @Override
390 public boolean isInFunEvent()
391 {
392- return (atEvent || isInStartedTVTEvent());
393+ return (atEvent || isInStartedTVTEvent() || isInStartedCTFEvent());
394 }
395
396 public boolean isInStartedTVTEvent()
397@@ -3339,7 +3364,26 @@
398 return _inEventTvT;
399 }
400
401+ public boolean isInStartedCTFEvent()
402+ {
403+ return (CTF.is_started() && _inEventCTF);
404+ }
405+
406+ public boolean isRegisteredInCTFEvent()
407+ {
408+ return _inEventCTF;
409+ }
410+
411 /**
412+ * Checks if is registered in fun event.
413+ * @return true, if is registered in fun event
414+ */
415+ public boolean isRegisteredInFunEvent()
416+ {
417+ return (atEvent || (_inEventTvT) || (_inEventCTF));
418+ }
419+
420+ /**
421 * @param barPixels
422 * @return true if cp update should be done, false if not
423 */
424@@ -4136,6 +4180,24 @@
425 }, Config.TVT_REVIVE_DELAY);
426 }
427 }
428+ else if (_inEventCTF)
429+ {
430+ if (CTF.is_teleport() || CTF.is_started())
431+ {
432+ sendMessage("You will be revived and teleported to team flag in " + Config.CTF_REVIVE_DELAY / 1000 + " seconds!");
433+ if (_haveFlagCTF)
434+ removeCTFFlagOnDie();
435+ ThreadPool.schedule(new Runnable()
436+ {
437+ @Override
438+ public void run()
439+ {
440+ teleToLocation(CTF._teamsX.get(CTF._teams.indexOf(_teamNameCTF)), CTF._teamsY.get(CTF._teams.indexOf(_teamNameCTF)), CTF._teamsZ.get(CTF._teams.indexOf(_teamNameCTF)), 0);
441+ doRevive();
442+ }
443+ }, Config.CTF_REVIVE_DELAY);
444+ }
445+ }
446
447 // Clear resurrect xp calculation
448 setExpBeforeDeath(0);
449@@ -4209,8 +4271,25 @@
450 return true;
451 }
452
453+ /**
454+ * Removes the ctf flag on die.
455+ */
456+ public void removeCTFFlagOnDie()
457+ {
458+ CTF._flagsTaken.set(CTF._teams.indexOf(_teamNameHaveFlagCTF), false);
459+ CTF.spawnFlag(_teamNameHaveFlagCTF);
460+ CTF.removeFlagFromPlayer(this);
461+ broadcastUserInfo();
462+ _haveFlagCTF = false;
463+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, CTF.get_eventName(), "CTF: " + _teamNameHaveFlagCTF + "'s flag returned."));
464+ // Announcements.getInstance().gameAnnounceToAll(CTF.get_eventName() + "(CTF): " + _teamNameHaveFlagCTF + "'s flag returned.");
465+ }
466+
467 private void onDieDropItem(Creature killer)
468 {
469+ if (atEvent || (TvT.is_started() && _inEventTvT) || (CTF.is_started() && _inEventCTF))
470+ return;
471+
472 if (killer == null)
473 return;
474
475@@ -4277,9 +4356,6 @@
476 }
477 }
478 }
479-
480- if (atEvent || (TvT.is_started() && _inEventTvT) || pk == null)
481- return;
482 }
483
484 public void updateKarmaLoss(long exp)
485@@ -4311,7 +4387,7 @@
486 return;
487 }
488
489- if ((_inEventTvT && TvT.is_started()))
490+ if ((_inEventTvT && TvT.is_started()) || (_inEventCTF && CTF.is_started()))
491 return;
492
493 // Don't rank up the CW if it was a summon.
494@@ -4360,7 +4436,7 @@
495 }
496
497 // Check if it's pvp (cases : regular, wars, victim is PKer)
498- if (checkIfPvP(target) || (targetPlayer.getClan() != null && getClan() != null && getClan().isAtWarWith(targetPlayer.getClanId()) && targetPlayer.getClan().isAtWarWith(getClanId()) && targetPlayer.getPledgeType() != Clan.SUBUNIT_ACADEMY && getPledgeType() != Clan.SUBUNIT_ACADEMY) || (targetPlayer.getKarma() > 0 && Config.KARMA_AWARD_PK_KILL))
499+ if (checkIfPvP(target) || (targetPlayer.getClan() != null && getClan() != null && getClan().isAtWarWith(targetPlayer.getClanId()) && targetPlayer.getClan().isAtWarWith(getClanId()) && targetPlayer.getPledgeType() != Clan.SUBUNIT_ACADEMY && getPledgeType() != Clan.SUBUNIT_ACADEMY) || (targetPlayer.getKarma() > 0 && Config.KARMA_AWARD_PK_KILL) || !(_inEventTvT && TvT.is_started()) || !(_inEventCTF && CTF.is_started()))
500 {
501 if (target instanceof Player)
502 {
503@@ -4386,7 +4462,7 @@
504 }
505 }
506 // Otherwise, killer is considered as a PKer.
507- else if (targetPlayer.getKarma() == 0 && targetPlayer.getPvpFlag() == 0)
508+ else if (targetPlayer.getKarma() == 0 && targetPlayer.getPvpFlag() == 0 || !(_inEventTvT && TvT.is_started()) || !(_inEventCTF && CTF.is_started()))
509 {
510 // PK Points are increased only if you kill a player.
511 if (target instanceof Player)
512@@ -4531,7 +4607,7 @@
513
514 public void updatePvPStatus()
515 {
516- if ((TvT.is_started() && _inEventTvT))
517+ if ((TvT.is_started() && _inEventTvT) || (CTF.is_started() && _inEventCTF))
518 return;
519
520 if (isInsideZone(ZoneId.PVP))
521@@ -4554,7 +4630,7 @@
522 if (isInDuel() && player.getDuelId() == getDuelId())
523 return;
524
525- if ((TvT.is_started() && _inEventTvT && player._inEventTvT))
526+ if ((TvT.is_started() && _inEventTvT && player._inEventTvT) || (CTF.is_started() && _inEventCTF && player._inEventCTF))
527 return;
528
529 if ((!isInsideZone(ZoneId.PVP) || !target.isInsideZone(ZoneId.PVP)) && player.getKarma() == 0)
530@@ -4727,7 +4803,7 @@
531 // Calculate the Experience loss
532 long lostExp = 0;
533
534- if (!atEvent && !(_inEventTvT && TvT.is_started()) && lvl < Experience.MAX_LEVEL)
535+ if (!atEvent && !(_inEventTvT && TvT.is_started()) && !(_inEventCTF && CTF.is_started()) && lvl < Experience.MAX_LEVEL)
536 lostExp = Math.round((getStat().getExpForLevel(lvl + 1) - getStat().getExpForLevel(lvl)) * percentLost / 100);
537 else
538 lostExp = Math.round((getStat().getExpForLevel(Experience.MAX_LEVEL) - getStat().getExpForLevel(Experience.MAX_LEVEL - 1)) * percentLost / 100);
539@@ -7073,10 +7149,9 @@
540 if (player.isInFunEvent())
541 {
542 // checks for events
543- if ((_inEventTvT && player._inEventTvT && TvT.is_started() && !_teamNameTvT.equals(player._teamNameTvT)))
544- {
545+ if ((_inEventTvT && player._inEventTvT && TvT.is_started() && !_teamNameTvT.equals(player._teamNameTvT)) || (_inEventCTF && player._inEventCTF && CTF.is_started() && !_teamNameCTF.equals(player._teamNameCTF)))
546 return true;
547- }
548+
549 return false;
550 }
551 return false;
552@@ -7405,7 +7480,7 @@
553 }
554
555 // Check if a Forced ATTACK is in progress on non-attackable target
556- if (!target.isAutoAttackable(this) && !forceUse && !(_inEventTvT && TvT.is_started()))
557+ if (!target.isAutoAttackable(this) && !forceUse && !(_inEventTvT && TvT.is_started()) && !(_inEventCTF && CTF.is_started()))
558 {
559 switch (sklTargetType)
560 {
561@@ -7682,23 +7757,21 @@
562 */
563 public boolean checkPvpSkill(WorldObject target, L2Skill skill)
564 {
565- if (skill == null || target == null)
566- return false;
567-
568- if (!(target instanceof Playable))
569- return true;
570-
571 // Check if player and target are in events and on the same team.
572 if (target instanceof Player)
573 {
574- if (skill.isOffensive() && (_inEventTvT && ((Player) target)._inEventTvT && TvT.is_started() && !_teamNameTvT.equals(((Player) target)._teamNameTvT)))
575- {
576+ if (skill.isOffensive() && (_inEventTvT && ((Player) target)._inEventTvT && TvT.is_started() && !_teamNameTvT.equals(((Player) target)._teamNameTvT)) || (_inEventCTF && ((Player) target)._inEventCTF && CTF.is_started() && !_teamNameCTF.equals(((Player) target)._teamNameCTF)))
577 return true;
578- }
579 else if (isInFunEvent() && skill.isOffensive()) // same team return false
580 return false;
581 }
582
583+ if (skill == null || target == null)
584+ return false;
585+
586+ if (!(target instanceof Playable))
587+ return true;
588+
589 if (skill.isDebuff() || skill.isOffensive())
590 {
591 final Player targetPlayer = target.getActingPlayer();
592@@ -9171,6 +9244,13 @@
593 if (isMounted())
594 startFeed(_mountNpcId);
595
596+ if ((_inEventTvT && TvT.is_started() && Config.TVT_REVIVE_RECOVERY) || (_inEventCTF && CTF.is_started() && Config.CTF_REVIVE_RECOVERY))
597+ {
598+ getStatus().setCurrentHp(getMaxHp());
599+ getStatus().setCurrentMp(getMaxMp());
600+ getStatus().setCurrentCp(getMaxCp());
601+ }
602+
603 // Schedule a paralyzed task to wait for the animation to finish
604 ThreadPool.schedule(new Runnable()
605 {
606@@ -10097,7 +10177,9 @@
607 break;
608 case 2:
609 _punishLevel = PunishLevel.JAIL;
610- if (_inEventTvT)
611+ if (_inEventCTF)
612+ CTF.onDisconnect(this);
613+ else if (_inEventTvT)
614 TvT.onDisconnect(this);
615 break;
616 case 3:
617Index: java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java
618===================================================================
619--- java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java (revision 448)
620+++ java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java (working copy)
621@@ -21,6 +21,7 @@
622 import net.sf.l2j.gameserver.data.SkillTable.FrequentSkill;
623 import net.sf.l2j.gameserver.data.xml.AdminData;
624 import net.sf.l2j.gameserver.data.xml.AnnouncementData;
625+import net.sf.l2j.gameserver.event.CTF;
626 import net.sf.l2j.gameserver.event.TvT;
627 import net.sf.l2j.gameserver.instancemanager.CastleManager;
628 import net.sf.l2j.gameserver.instancemanager.ClanHallManager;
629@@ -236,6 +237,9 @@
630 if (TvT._savePlayers.contains(activeChar.getName()))
631 TvT.addDisconnectedPlayer(activeChar);
632
633+ if (CTF._savePlayers.contains(activeChar.getName()))
634+ CTF.addDisconnectedPlayer(activeChar);
635+
636 // Means that it's not ok multiBox situation, so logout
637 if (!activeChar.checkMultiBox())
638 {
639Index: java/net/sf/l2j/gameserver/network/L2GameClient.java
640===================================================================
641--- java/net/sf/l2j/gameserver/network/L2GameClient.java (revision 447)
642+++ java/net/sf/l2j/gameserver/network/L2GameClient.java (working copy)
643@@ -23,6 +23,7 @@
644 import net.sf.l2j.gameserver.LoginServerThread;
645 import net.sf.l2j.gameserver.data.PlayerNameTable;
646 import net.sf.l2j.gameserver.data.sql.ClanTable;
647+import net.sf.l2j.gameserver.event.CTF;
648 import net.sf.l2j.gameserver.event.L2Event;
649 import net.sf.l2j.gameserver.event.TvT;
650 import net.sf.l2j.gameserver.model.CharSelectInfoPackage;
651@@ -539,38 +540,60 @@
652
653 try
654 {
655+ Player player = L2GameClient.this.getActiveChar();
656 if (getActiveChar() != null && !isDetached())
657 {
658+ // we store all data from players who are disconnected while in an event in order to restore it in the next login
659+ if (player.atEvent)
660+ {
661+ EventData data = new EventData(player.eventX, player.eventY, player.eventZ, player.eventKarma, player.eventPvpKills, player.eventPkKills, player.eventTitle, player.kills, player.eventSitForced);
662+
663+ L2Event.connectionLossData.put(player.getName(), data);
664+ data = null;
665+ }
666+ else
667+ {
668+ if (player._inEventCTF)
669+ {
670+ CTF.onDisconnect(player);
671+ }
672+ else if (player._inEventTvT)
673+ {
674+ TvT.onDisconnect(player);
675+ }
676+ }
677+
678 setDetached(true);
679@@ -648,27 +671,31 @@
680 // we are going to manually save the char below thus we can force the cancel
681 if (_autoSaveInDB != null)
682 _autoSaveInDB.cancel(true);
683-
684+
685 Player player = L2GameClient.this.getActiveChar();
686 if (player != null) // this should only happen on connection loss
687 {
688 // we store all data from players who are disconnected while in an event in order to restore it in the next login
689- if(player.atEvent)
690+ if (player.atEvent)
691 {
692 EventData data = new EventData(player.eventX, player.eventY, player.eventZ, player.eventKarma, player.eventPvpKills, player.eventPkKills, player.eventTitle, player.kills, player.eventSitForced);
693-
694+
695 L2Event.connectionLossData.put(player.getName(), data);
696 data = null;
697 }
698 else
699- {
700- if(player._inEventTvT)
701+ {
702+ if (player._inEventCTF)
703 {
704+ CTF.onDisconnect(player);
705+ }
706+ else if (player._inEventTvT)
707+ {
708 TvT.onDisconnect(player);
709 }
710 }
711 }
712-
713+
714 if (getActiveChar() != null) // this should only happen on connection loss
715 {
716 if (getActiveChar().isLocked())
717Index: java/net/sf/l2j/gameserver/model/actor/Npc.java
718===================================================================
719--- java/net/sf/l2j/gameserver/model/actor/Npc.java (revision 447)
720+++ java/net/sf/l2j/gameserver/model/actor/Npc.java (working copy)
721@@ -74,8 +74,13 @@
722 public static final int INTERACTION_DISTANCE = 150;
723 private static final int SOCIAL_INTERVAL = 12000;
724
725 public boolean isEventMob = false;
726 public boolean _isEventMobTvT = false;
727+ public boolean _isEventMobCTF = false;
728+ public boolean _isCTF_throneSpawn = false;
729+ public boolean _isCTF_Flag = false;
730+ public String _CTF_FlagTeamName;
731
732 private L2Spawn _spawn;
733
734Index: java/net/sf/l2j/gameserver/network/clientpackets/RequestUnEquipItem.java
735===================================================================
736--- java/net/sf/l2j/gameserver/network/clientpackets/RequestUnEquipItem.java (revision 447)
737+++ java/net/sf/l2j/gameserver/network/clientpackets/RequestUnEquipItem.java (working copy)
738@@ -27,6 +27,12 @@
739 if (activeChar == null)
740 return;
741
742+ if (activeChar._haveFlagCTF)
743+ {
744+ activeChar.sendMessage("You can't unequip a CTF flag.");
745+ return;
746+ }
747+
748 ItemInstance item = activeChar.getInventory().getPaperdollItemByL2ItemId(_slot);
749 if (item == null)
750 return;
751Index: config/events.properties
752===================================================================
753--- config/events.properties (revision 448)
754+++ config/events.properties (working copy)
755@@ -329,72 +329,93 @@
756 # Remove Buffs on player die
757 TvTRemoveBuffsOnPlayerDie = False
758
759+#============================================================#
760+# Capture the Flag #
761+#============================================================#
762+# CTF(Capture the flag) Event: Two teams with one flag.
763+# Setting for Capture The Flag
764+# CTFEvenTeams = NO|BALANCE|SHUFFLE
765+# NO means: not even teams.
766+# BALANCE means: Players can only join team with lowest player count.
767+# SHUFFLE means: Players can only participate to tzhe event and not
768+# direct to a team. Teams will be schuffeled in teleporting teams.
769+CTFEvenTeams = SHUFFLE
770+# Players there not participated in ctf can target ctf participants?
771+CTFAllowInterference = False
772+# Ctf participants can use potions?
773+CTFAllowPotions = True
774+# Ctf participants can summon by item?
775+CTFAllowSummon = False
776+# Remove all effects of ctf participants on event start?
777+CTFOnStartRemoveAllEffects = False
778+# Unsummon pet of ctf participants on event start?
779+CTFOnStartUnsummonPet = True
780+# On revive participants regain full hp/mp/cp ?
781+CTFReviveRecovery = True
782+# Announce all team statistics
783+CTFAnnounceTeamStats = True
784+# Announce Reward
785+CTFAnnounceReward = False
786+# Enable voice command to register on tvt/ctf events
787+CTFCommand = True
788+# Delay on revive when dead, NOTE: 20000 equals to 20 seconds, minimum 1000 (1 second)
789+CTFReviveDelay = 10000
790+# Place an aura on participants team ?
791+CTFAura = False
792+# Enable event stats logger
793+CTFStatsLogger = True
794+# Spawn Team Offset to distribute players
795+CTFSpawnOffset = 300
796+# Enable healer classes into CTF
797+CTFAllowedHealerClasses = False
798+# Remove Buffs on player die
799+CTFRemoveBuffsOnPlayerDie = False
800+
801\ No newline at end of file
802Index: java/net/sf/l2j/gameserver/network/clientpackets/RequestRestart.java
803===================================================================
804--- java/net/sf/l2j/gameserver/network/clientpackets/RequestRestart.java (revision 447)
805+++ java/net/sf/l2j/gameserver/network/clientpackets/RequestRestart.java (working copy)
806@@ -51,6 +51,14 @@
807 return;
808 }
809
810+ // Check if player is in Event
811+ if (player._inEventCTF || player._inEventTvT)
812+ {
813+ player.sendMessage("You can't restart during Event.");
814+ sendPacket(RestartResponse.valueOf(false));
815+ return;
816+ }
817+
818 player.removeFromBossZone();
819
820 // Delete box from the world
821Index: java/net/sf/l2j/gameserver/network/serverpackets/Die.java
822===================================================================
823--- java/net/sf/l2j/gameserver/network/serverpackets/Die.java (revision 447)
824+++ java/net/sf/l2j/gameserver/network/serverpackets/Die.java (working copy)
825@@ -1,5 +1,6 @@
826 package net.sf.l2j.gameserver.network.serverpackets;
827
828+import net.sf.l2j.gameserver.event.CTF;
829 import net.sf.l2j.gameserver.event.TvT;
830 import net.sf.l2j.gameserver.instancemanager.CastleManager;
831 import net.sf.l2j.gameserver.model.actor.Attackable;
832@@ -31,7 +32,7 @@
833 Player player = (Player) cha;
834 _allowFixedRes = player.getAccessLevel().allowFixedRes();
835 _clan = player.getClan();
836- _canTeleport = !((TvT.is_started() && player._inEventTvT) || player.isInFunEvent() || player.isPendingRevive());
837+ _canTeleport = !((TvT.is_started() && player._inEventTvT) || (CTF.is_started() && player._inEventCTF) || player.isInFunEvent() || player.isPendingRevive());
838 }
839 else if (cha instanceof Attackable)
840 _sweepable = ((Attackable) cha).isSpoiled();
841Index: java/net/sf/l2j/gameserver/event/CTF.java
842===================================================================
843--- java/net/sf/l2j/gameserver/event/CTF.java (revision 0)
844+++ java/net/sf/l2j/gameserver/event/CTF.java (working copy)
845@@ -0,0 +1,3235 @@
846+/*
847+ * This program is free software: you can redistribute it and/or modify it under
848+ * the terms of the GNU General Public License as published by the Free Software
849+ * Foundation, either version 3 of the License, or (at your option) any later
850+ * version.
851+ *
852+ * This program is distributed in the hope that it will be useful, but WITHOUT
853+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
854+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
855+ * details.
856+ *
857+ * You should have received a copy of the GNU General Public License along with
858+ * this program. If not, see <http://www.gnu.org/licenses/>.
859+ */
860+package net.sf.l2j.gameserver.event;
861+
862+import java.sql.PreparedStatement;
863+import java.sql.ResultSet;
864+import java.util.List;
865+import java.util.Vector;
866+import java.util.logging.Level;
867+import java.util.logging.Logger;
868+
869+import net.sf.l2j.commons.concurrent.ThreadPool;
870+import net.sf.l2j.commons.random.Rnd;
871+
872+import net.sf.l2j.Config;
873+import net.sf.l2j.L2DatabaseFactory;
874+import net.sf.l2j.gameserver.data.ItemTable;
875+import net.sf.l2j.gameserver.data.NpcTable;
876+import net.sf.l2j.gameserver.data.SkillTable;
877+import net.sf.l2j.gameserver.data.SpawnTable;
878+import net.sf.l2j.gameserver.instancemanager.CastleManager;
879+import net.sf.l2j.gameserver.model.L2Effect;
880+import net.sf.l2j.gameserver.model.L2Radar;
881+import net.sf.l2j.gameserver.model.L2Spawn;
882+import net.sf.l2j.gameserver.model.World;
883+import net.sf.l2j.gameserver.model.actor.Summon;
884+import net.sf.l2j.gameserver.model.actor.instance.Player;
885+import net.sf.l2j.gameserver.model.actor.instance.Servitor;
886+import net.sf.l2j.gameserver.model.actor.template.NpcTemplate;
887+import net.sf.l2j.gameserver.model.base.ClassId;
888+import net.sf.l2j.gameserver.model.entity.Castle;
889+import net.sf.l2j.gameserver.model.group.Party;
890+import net.sf.l2j.gameserver.model.group.Party.MessageType;
891+import net.sf.l2j.gameserver.model.item.instance.ItemInstance;
892+import net.sf.l2j.gameserver.model.itemcontainer.Inventory;
893+import net.sf.l2j.gameserver.model.location.Location;
894+import net.sf.l2j.gameserver.model.olympiad.OlympiadManager;
895+import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
896+import net.sf.l2j.gameserver.network.serverpackets.CreatureSay;
897+import net.sf.l2j.gameserver.network.serverpackets.InventoryUpdate;
898+import net.sf.l2j.gameserver.network.serverpackets.ItemList;
899+import net.sf.l2j.gameserver.network.serverpackets.MagicSkillUse;
900+import net.sf.l2j.gameserver.network.serverpackets.NpcHtmlMessage;
901+import net.sf.l2j.gameserver.network.serverpackets.RadarControl;
902+import net.sf.l2j.gameserver.network.serverpackets.Ride;
903+import net.sf.l2j.gameserver.network.serverpackets.SocialAction;
904+import net.sf.l2j.gameserver.util.Broadcast;
905+
906+/**
907+ * The Class CTF.
908+ */
909+public class CTF implements EventTask
910+{
911+ /** The Constant _log. */
912+ protected static final Logger _log = Logger.getLogger(CTF.class.getName());
913+
914+ /** The _joining location name. */
915+ protected static String _eventName = new String(), _eventDesc = new String(), _joiningLocationName = new String();
916+
917+ /** The _npc spawn. */
918+ private static L2Spawn _npcSpawn;
919+
920+ /** The _in progress. */
921+ protected static boolean _joining = false, _teleport = false, _started = false, _aborted = false, _sitForced = false, _inProgress = false;
922+
923+ /** The _max players. */
924+ protected static int _npcId = 0, _npcX = 0, _npcY = 0, _npcZ = 0, _npcHeading = 0, _rewardId = 0, _rewardAmount = 0, _minlvl = 0, _maxlvl = 0, _joinTime = 0, _eventTime = 0, _minPlayers = 0, _maxPlayers = 0;
925+
926+ /** The _interval between matches. */
927+ protected static long _intervalBetweenMatches = 0;
928+
929+ /** The start event time. */
930+ private String startEventTime;
931+
932+ /** The _team event. */
933+ protected static boolean _teamEvent = true; // TODO to be integrated
934+
935+ /** The _players. */
936+ public static Vector<Player> _players = new Vector<>();
937+
938+ /** The _top team. */
939+ private static String _topTeam = new String();
940+
941+ /** The _players shuffle. */
942+ public static Vector<Player> _playersShuffle = new Vector<>();
943+
944+ /** The _save player teams. */
945+ public static Vector<String> _teams = new Vector<>(), _savePlayers = new Vector<>(), _savePlayerTeams = new Vector<>();
946+
947+ /** The _teams z. */
948+ public static Vector<Integer> _teamPlayersCount = new Vector<>(), _teamColors = new Vector<>(), _teamsX = new Vector<>(), _teamsY = new Vector<>(), _teamsZ = new Vector<>();
949+
950+ /** The _team points count. */
951+ public static Vector<Integer> _teamPointsCount = new Vector<>();
952+
953+ /** The _top score. */
954+ public static int _topScore = 0;
955+
956+ /** The _event offset. */
957+ public static int _eventCenterX = 0, _eventCenterY = 0, _eventCenterZ = 0, _eventOffset = 0;
958+
959+ /** The _ fla g_ i n_ han d_ ite m_ id. */
960+ private static int _FlagNPC = 50099, _FLAG_IN_HAND_ITEM_ID = 6718;
961+
962+ /** The _flags z. */
963+ public static Vector<Integer> _flagIds = new Vector<>(), _flagsX = new Vector<>(), _flagsY = new Vector<>(), _flagsZ = new Vector<>();
964+
965+ /** The _throne spawns. */
966+ public static Vector<L2Spawn> _flagSpawns = new Vector<>(), _throneSpawns = new Vector<>();
967+
968+ /** The _flags taken. */
969+ public static Vector<Boolean> _flagsTaken = new Vector<>();
970+
971+ /**
972+ * Instantiates a new cTF.
973+ */
974+ private CTF()
975+ {
976+ // nothing
977+ }
978+
979+ /**
980+ * Gets the new instance.
981+ * @return the new instance
982+ */
983+ public static CTF getNewInstance()
984+ {
985+ return new CTF();
986+ }
987+
988+ /**
989+ * Gets the _event name.
990+ * @return the _eventName
991+ */
992+ public static String get_eventName()
993+ {
994+ return _eventName;
995+ }
996+
997+ /**
998+ * Set_event name.
999+ * @param _eventName the _eventName to set
1000+ * @return true, if successful
1001+ */
1002+ public static boolean set_eventName(String _eventName)
1003+ {
1004+ if (!is_inProgress())
1005+ {
1006+ CTF._eventName = _eventName;
1007+ return true;
1008+ }
1009+ return false;
1010+ }
1011+
1012+ /**
1013+ * Gets the _event desc.
1014+ * @return the _eventDesc
1015+ */
1016+ public static String get_eventDesc()
1017+ {
1018+ return _eventDesc;
1019+ }
1020+
1021+ /**
1022+ * Set_event desc.
1023+ * @param _eventDesc the _eventDesc to set
1024+ * @return true, if successful
1025+ */
1026+ public static boolean set_eventDesc(String _eventDesc)
1027+ {
1028+ if (!is_inProgress())
1029+ {
1030+ CTF._eventDesc = _eventDesc;
1031+ return true;
1032+ }
1033+ return false;
1034+ }
1035+
1036+ /**
1037+ * Gets the _joining location name.
1038+ * @return the _joiningLocationName
1039+ */
1040+ public static String get_joiningLocationName()
1041+ {
1042+ return _joiningLocationName;
1043+ }
1044+
1045+ /**
1046+ * Set_joining location name.
1047+ * @param _joiningLocationName the _joiningLocationName to set
1048+ * @return true, if successful
1049+ */
1050+ public static boolean set_joiningLocationName(String _joiningLocationName)
1051+ {
1052+ if (!is_inProgress())
1053+ {
1054+ CTF._joiningLocationName = _joiningLocationName;
1055+ return true;
1056+ }
1057+ return false;
1058+ }
1059+
1060+ /**
1061+ * Gets the _npc id.
1062+ * @return the _npcId
1063+ */
1064+ public static int get_npcId()
1065+ {
1066+ return _npcId;
1067+ }
1068+
1069+ /**
1070+ * Set_npc id.
1071+ * @param _npcId the _npcId to set
1072+ * @return true, if successful
1073+ */
1074+ public static boolean set_npcId(int _npcId)
1075+ {
1076+ if (!is_inProgress())
1077+ {
1078+ CTF._npcId = _npcId;
1079+ return true;
1080+ }
1081+ return false;
1082+ }
1083+
1084+ /**
1085+ * Gets the _npc location.
1086+ * @return the _npc location
1087+ */
1088+ public static Location get_npcLocation()
1089+ {
1090+ Location npc_loc = new Location(_npcX, _npcY, _npcZ);
1091+
1092+ return npc_loc;
1093+ }
1094+
1095+ /**
1096+ * Gets the _reward id.
1097+ * @return the _rewardId
1098+ */
1099+ public static int get_rewardId()
1100+ {
1101+ return _rewardId;
1102+ }
1103+
1104+ /**
1105+ * Set_reward id.
1106+ * @param _rewardId the _rewardId to set
1107+ * @return true, if successful
1108+ */
1109+ public static boolean set_rewardId(int _rewardId)
1110+ {
1111+ if (!is_inProgress())
1112+ {
1113+ CTF._rewardId = _rewardId;
1114+ return true;
1115+ }
1116+ return false;
1117+ }
1118+
1119+ /**
1120+ * Gets the _reward amount.
1121+ * @return the _rewardAmount
1122+ */
1123+ public static int get_rewardAmount()
1124+ {
1125+ return _rewardAmount;
1126+ }
1127+
1128+ /**
1129+ * Set_reward amount.
1130+ * @param _rewardAmount the _rewardAmount to set
1131+ * @return true, if successful
1132+ */
1133+ public static boolean set_rewardAmount(int _rewardAmount)
1134+ {
1135+ if (!is_inProgress())
1136+ {
1137+ CTF._rewardAmount = _rewardAmount;
1138+ return true;
1139+ }
1140+ return false;
1141+ }
1142+
1143+ /**
1144+ * Gets the _minlvl.
1145+ * @return the _minlvl
1146+ */
1147+ public static int get_minlvl()
1148+ {
1149+ return _minlvl;
1150+ }
1151+
1152+ /**
1153+ * Set_minlvl.
1154+ * @param _minlvl the _minlvl to set
1155+ * @return true, if successful
1156+ */
1157+ public static boolean set_minlvl(int _minlvl)
1158+ {
1159+ if (!is_inProgress())
1160+ {
1161+ CTF._minlvl = _minlvl;
1162+ return true;
1163+ }
1164+ return false;
1165+ }
1166+
1167+ /**
1168+ * Gets the _maxlvl.
1169+ * @return the _maxlvl
1170+ */
1171+ public static int get_maxlvl()
1172+ {
1173+ return _maxlvl;
1174+ }
1175+
1176+ /**
1177+ * Set_maxlvl.
1178+ * @param _maxlvl the _maxlvl to set
1179+ * @return true, if successful
1180+ */
1181+ public static boolean set_maxlvl(int _maxlvl)
1182+ {
1183+ if (!is_inProgress())
1184+ {
1185+ CTF._maxlvl = _maxlvl;
1186+ return true;
1187+ }
1188+ return false;
1189+ }
1190+
1191+ /**
1192+ * Gets the _join time.
1193+ * @return the _joinTime
1194+ */
1195+ public static int get_joinTime()
1196+ {
1197+ return _joinTime;
1198+ }
1199+
1200+ /**
1201+ * Set_join time.
1202+ * @param _joinTime the _joinTime to set
1203+ * @return true, if successful
1204+ */
1205+ public static boolean set_joinTime(int _joinTime)
1206+ {
1207+ if (!is_inProgress())
1208+ {
1209+ CTF._joinTime = _joinTime;
1210+ return true;
1211+ }
1212+ return false;
1213+ }
1214+
1215+ /**
1216+ * Gets the _event time.
1217+ * @return the _eventTime
1218+ */
1219+ public static int get_eventTime()
1220+ {
1221+ return _eventTime;
1222+ }
1223+
1224+ /**
1225+ * Set_event time.
1226+ * @param _eventTime the _eventTime to set
1227+ * @return true, if successful
1228+ */
1229+ public static boolean set_eventTime(int _eventTime)
1230+ {
1231+ if (!is_inProgress())
1232+ {
1233+ CTF._eventTime = _eventTime;
1234+ return true;
1235+ }
1236+ return false;
1237+ }
1238+
1239+ /**
1240+ * Gets the _min players.
1241+ * @return the _minPlayers
1242+ */
1243+ public static int get_minPlayers()
1244+ {
1245+ return _minPlayers;
1246+ }
1247+
1248+ /**
1249+ * Set_min players.
1250+ * @param _minPlayers the _minPlayers to set
1251+ * @return true, if successful
1252+ */
1253+ public static boolean set_minPlayers(int _minPlayers)
1254+ {
1255+ if (!is_inProgress())
1256+ {
1257+ CTF._minPlayers = _minPlayers;
1258+ return true;
1259+ }
1260+ return false;
1261+ }
1262+
1263+ /**
1264+ * Gets the _max players.
1265+ * @return the _maxPlayers
1266+ */
1267+ public static int get_maxPlayers()
1268+ {
1269+ return _maxPlayers;
1270+ }
1271+
1272+ /**
1273+ * Set_max players.
1274+ * @param _maxPlayers the _maxPlayers to set
1275+ * @return true, if successful
1276+ */
1277+ public static boolean set_maxPlayers(int _maxPlayers)
1278+ {
1279+ if (!is_inProgress())
1280+ {
1281+ CTF._maxPlayers = _maxPlayers;
1282+ return true;
1283+ }
1284+ return false;
1285+ }
1286+
1287+ /**
1288+ * Gets the _interval between matchs.
1289+ * @return the _intervalBetweenMatches
1290+ */
1291+ public static long get_intervalBetweenMatches()
1292+ {
1293+ return _intervalBetweenMatches;
1294+ }
1295+
1296+ /**
1297+ * Set_interval between matchs.
1298+ * @param _intervalBetweenMatches the _intervalBetweenMatches to set
1299+ * @return true, if successful
1300+ */
1301+ public static boolean set_intervalBetweenMatches(long _intervalBetweenMatches)
1302+ {
1303+ if (!is_inProgress())
1304+ {
1305+ CTF._intervalBetweenMatches = _intervalBetweenMatches;
1306+ return true;
1307+ }
1308+ return false;
1309+ }
1310+
1311+ /**
1312+ * Gets the start event time.
1313+ * @return the startEventTime
1314+ */
1315+ public String getStartEventTime()
1316+ {
1317+ return startEventTime;
1318+ }
1319+
1320+ /**
1321+ * Sets the start event time.
1322+ * @param startEventTime the startEventTime to set
1323+ * @return true, if successful
1324+ */
1325+ public boolean setStartEventTime(String startEventTime)
1326+ {
1327+ if (!is_inProgress())
1328+ {
1329+ this.startEventTime = startEventTime;
1330+ return true;
1331+ }
1332+ return false;
1333+ }
1334+
1335+ /**
1336+ * Checks if is _joining.
1337+ * @return the _joining
1338+ */
1339+ public static boolean is_joining()
1340+ {
1341+ return _joining;
1342+ }
1343+
1344+ /**
1345+ * Checks if is _teleport.
1346+ * @return the _teleport
1347+ */
1348+ public static boolean is_teleport()
1349+ {
1350+ return _teleport;
1351+ }
1352+
1353+ /**
1354+ * Checks if is _started.
1355+ * @return the _started
1356+ */
1357+ public static boolean is_started()
1358+ {
1359+ return _started;
1360+ }
1361+
1362+ /**
1363+ * Checks if is _aborted.
1364+ * @return the _aborted
1365+ */
1366+ public static boolean is_aborted()
1367+ {
1368+ return _aborted;
1369+ }
1370+
1371+ /**
1372+ * Checks if is _sit forced.
1373+ * @return the _sitForced
1374+ */
1375+ public static boolean is_sitForced()
1376+ {
1377+ return _sitForced;
1378+ }
1379+
1380+ /**
1381+ * Checks if is _in progress.
1382+ * @return the _inProgress
1383+ */
1384+ public static boolean is_inProgress()
1385+ {
1386+ return _inProgress;
1387+ }
1388+
1389+ /**
1390+ * Check max level.
1391+ * @param maxlvl the maxlvl
1392+ * @return true, if successful
1393+ */
1394+ public static boolean checkMaxLevel(int maxlvl)
1395+ {
1396+ if (_minlvl >= maxlvl)
1397+ return false;
1398+
1399+ return true;
1400+ }
1401+
1402+ /**
1403+ * Check min level.
1404+ * @param minlvl the minlvl
1405+ * @return true, if successful
1406+ */
1407+ public static boolean checkMinLevel(int minlvl)
1408+ {
1409+ if (_maxlvl <= minlvl)
1410+ return false;
1411+
1412+ return true;
1413+ }
1414+
1415+ /**
1416+ * returns true if participated players is higher or equal then minimum needed players.
1417+ * @param players the players
1418+ * @return true, if successful
1419+ */
1420+ public static boolean checkMinPlayers(int players)
1421+ {
1422+ if (_minPlayers <= players)
1423+ return true;
1424+
1425+ return false;
1426+ }
1427+
1428+ /**
1429+ * returns true if max players is higher or equal then participated players.
1430+ * @param players the players
1431+ * @return true, if successful
1432+ */
1433+ public static boolean checkMaxPlayers(int players)
1434+ {
1435+ if (_maxPlayers > players)
1436+ return true;
1437+
1438+ return false;
1439+ }
1440+
1441+ /**
1442+ * Check start join ok.
1443+ * @return true, if successful
1444+ */
1445+ public static boolean checkStartJoinOk()
1446+ {
1447+ if (_started || _teleport || _joining || _eventName.equals("") || _joiningLocationName.equals("") || _eventDesc.equals("") || _npcId == 0 || _npcX == 0 || _npcY == 0 || _npcZ == 0 || _rewardId == 0 || _rewardAmount == 0)
1448+ return false;
1449+
1450+ if (_teamEvent)
1451+ {
1452+ if (!checkStartJoinTeamInfo())
1453+ return false;
1454+ }
1455+ else
1456+ {
1457+ if (!checkStartJoinPlayerInfo())
1458+ return false;
1459+ }
1460+
1461+ for (Castle castle : CastleManager.getInstance().getCastles())
1462+ {
1463+ if (castle != null && castle.getSiege() != null && castle.getSiege().isInProgress())
1464+ return false;
1465+ }
1466+
1467+ if (!checkOptionalEventStartJoinOk())
1468+ return false;
1469+
1470+ return true;
1471+ }
1472+
1473+ /**
1474+ * Check start join team info.
1475+ * @return true, if successful
1476+ */
1477+ private static boolean checkStartJoinTeamInfo()
1478+ {
1479+ if (_teams.size() < 2 || _teamsX.contains(0) || _teamsY.contains(0) || _teamsZ.contains(0))
1480+ return false;
1481+
1482+ return true;
1483+ }
1484+
1485+ /**
1486+ * Check start join player info.
1487+ * @return true, if successful
1488+ */
1489+ private static boolean checkStartJoinPlayerInfo()
1490+ {
1491+ // TODO be integrated
1492+ return true;
1493+ }
1494+
1495+ /**
1496+ * Check auto event start join ok.
1497+ * @return true, if successful
1498+ */
1499+ protected static boolean checkAutoEventStartJoinOk()
1500+ {
1501+ if (_joinTime == 0 || _eventTime == 0)
1502+ {
1503+ return false;
1504+ }
1505+
1506+ return true;
1507+ }
1508+
1509+ /**
1510+ * Check optional event start join ok.
1511+ * @return true, if successful
1512+ */
1513+ private static boolean checkOptionalEventStartJoinOk()
1514+ {
1515+ try
1516+ {
1517+ if (_flagsX.contains(0) || _flagsY.contains(0) || _flagsZ.contains(0) || _flagIds.contains(0))
1518+ return false;
1519+ if (_flagsX.size() < _teams.size() || _flagsY.size() < _teams.size() || _flagsZ.size() < _teams.size() || _flagIds.size() < _teams.size())
1520+ return false;
1521+ }
1522+ catch (ArrayIndexOutOfBoundsException e)
1523+ {
1524+ e.printStackTrace();
1525+ return false;
1526+ }
1527+
1528+ return true;
1529+ }
1530+
1531+ /**
1532+ * Sets the npc pos.
1533+ * @param activeChar the new npc pos
1534+ */
1535+ public static void setNpcPos(Player activeChar)
1536+ {
1537+ _npcX = activeChar.getX();
1538+ _npcY = activeChar.getY();
1539+ _npcZ = activeChar.getZ();
1540+ _npcHeading = activeChar.getHeading();
1541+ }
1542+
1543+ /**
1544+ * Spawn event npc.
1545+ */
1546+ private static void spawnEventNpc()
1547+ {
1548+ NpcTemplate tmpl = NpcTable.getInstance().getTemplate(_npcId);
1549+
1550+ try
1551+ {
1552+ _npcSpawn = new L2Spawn(tmpl);
1553+
1554+ _npcSpawn.setLoc(_npcX, _npcY, _npcZ, _npcHeading);
1555+ _npcSpawn.setRespawnDelay(1);
1556+
1557+ SpawnTable.getInstance().addNewSpawn(_npcSpawn, false);
1558+
1559+ _npcSpawn.setRespawnState(true);
1560+ _npcSpawn.doSpawn(false);
1561+ _npcSpawn.getNpc().getStatus().setCurrentHp(999999999);
1562+ _npcSpawn.getNpc().setTitle(_eventName);
1563+ _npcSpawn.getNpc()._isEventMobCTF = true;
1564+ _npcSpawn.getNpc().isAggressive();
1565+ _npcSpawn.getNpc().decayMe();
1566+ _npcSpawn.getNpc().spawnMe(_npcSpawn.getNpc().getX(), _npcSpawn.getNpc().getY(), _npcSpawn.getNpc().getZ());
1567+
1568+ _npcSpawn.getNpc().broadcastPacket(new MagicSkillUse(_npcSpawn.getNpc(), _npcSpawn.getNpc(), 1034, 1, 1, 1));
1569+ }
1570+ catch (Exception e)
1571+ {
1572+ e.printStackTrace();
1573+
1574+ _log.log(Level.SEVERE, _eventName + " Engine[spawnEventNpc(exception: " + e.getMessage());
1575+ }
1576+ }
1577+
1578+ /**
1579+ * Unspawn event npc.
1580+ */
1581+ private static void unspawnEventNpc()
1582+ {
1583+ if (_npcSpawn == null || _npcSpawn.getNpc() == null)
1584+ return;
1585+
1586+ _npcSpawn.getNpc().deleteMe();
1587+ _npcSpawn.setRespawnState(false);
1588+ SpawnTable.getInstance().deleteSpawn(_npcSpawn, true);
1589+ }
1590+
1591+ /**
1592+ * Start join.
1593+ * @return true, if successful
1594+ */
1595+ public static boolean startJoin()
1596+ {
1597+ if (!checkStartJoinOk())
1598+ {
1599+ if (Config.DEBUG)
1600+ _log.log(Level.WARNING, _eventName + " Engine[startJoin]: startJoinOk() = false");
1601+ return false;
1602+ }
1603+
1604+ _inProgress = true;
1605+ _joining = true;
1606+ spawnEventNpc();
1607+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: Event starting!"));
1608+ if (Config.CTF_ANNOUNCE_REWARD && ItemTable.getInstance().getTemplate(_rewardId) != null)
1609+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: Reward " + _rewardAmount + " " + ItemTable.getInstance().getTemplate(_rewardId).getName()));
1610+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: Recruiting levels " + _minlvl + " to " + _maxlvl));
1611+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: Joinable in " + _joiningLocationName + "."));
1612+
1613+ if (Config.CTF_COMMAND)
1614+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: Commands .ctfjoin .ctfleave .ctfinfo!"));
1615+
1616+ return true;
1617+ }
1618+
1619+ /**
1620+ * Start teleport.
1621+ * @return true, if successful
1622+ */
1623+ public static boolean startTeleport()
1624+ {
1625+ if (!_joining || _started || _teleport)
1626+ return false;
1627+
1628+ removeOfflinePlayers();
1629+
1630+ if (_teamEvent)
1631+ {
1632+ if (Config.CTF_EVEN_TEAMS.equals("SHUFFLE") && checkMinPlayers(_playersShuffle.size()))
1633+ {
1634+ shuffleTeams();
1635+ }
1636+ else if (Config.CTF_EVEN_TEAMS.equals("SHUFFLE") && !checkMinPlayers(_playersShuffle.size()))
1637+ {
1638+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: Not enough players for event. Min Requested: " + _minPlayers + ", Participating: " + _playersShuffle.size()));
1639+ if (Config.CTF_STATS_LOGGER)
1640+ _log.info(_eventName + ": Not enough players for event. Min Requested: " + _minPlayers + ", Participating: " + _playersShuffle.size());
1641+
1642+ return false;
1643+ }
1644+ }
1645+ else
1646+ {
1647+ if (!checkMinPlayers(_players.size()))
1648+ {
1649+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: Not enough players for event. Min Requested: " + _minPlayers + ", Participating: " + _players.size()));
1650+ if (Config.CTF_STATS_LOGGER)
1651+ _log.info(_eventName + ": Not enough players for event. Min Requested: " + _minPlayers + ", Participating: " + _players.size());
1652+ return false;
1653+ }
1654+ }
1655+
1656+ _joining = false;
1657+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: Teleport to team spot in 20 seconds!"));
1658+
1659+ setUserData();
1660+ ThreadPool.schedule(new Runnable()
1661+ {
1662+ @Override
1663+ public void run()
1664+ {
1665+ sit();
1666+ afterTeleportOperations();
1667+
1668+ synchronized (_players)
1669+ {
1670+ for (Player player : _players)
1671+ {
1672+ if (player != null)
1673+ {
1674+ if (Config.CTF_ON_START_UNSUMMON_PET)
1675+ {
1676+ // Remove Summon's buffs
1677+ if (player.getPet() != null)
1678+ {
1679+ Summon summon = player.getPet();
1680+ for (L2Effect e : summon.getAllEffects())
1681+ if (e != null)
1682+ e.exit(true);
1683+
1684+ if (summon instanceof Servitor)
1685+ summon.unSummon(player);
1686+ }
1687+ }
1688+
1689+ if (Config.CTF_ON_START_REMOVE_ALL_EFFECTS)
1690+ {
1691+ for (L2Effect e : player.getAllEffects())
1692+ {
1693+ if (e != null)
1694+ e.exit(true);
1695+ }
1696+ }
1697+
1698+ // Remove player from his party
1699+ if (player.getParty() != null)
1700+ {
1701+ Party party = player.getParty();
1702+ party.removePartyMember(player, MessageType.EXPELLED);
1703+ }
1704+
1705+ if (_teamEvent)
1706+ {
1707+ int offset = Config.CTF_SPAWN_OFFSET;
1708+ player.teleToLocation(_teamsX.get(_teams.indexOf(player._teamNameCTF)) + Rnd.get(offset), _teamsY.get(_teams.indexOf(player._teamNameCTF)) + Rnd.get(offset), _teamsZ.get(_teams.indexOf(player._teamNameCTF)), offset);
1709+ }
1710+ }
1711+ }
1712+ }
1713+
1714+ }
1715+ }, 10000);
1716+ _teleport = true;
1717+ return true;
1718+ }
1719+
1720+ /**
1721+ * After teleport operations.
1722+ */
1723+ protected static void afterTeleportOperations()
1724+ {
1725+ spawnAllFlags();
1726+ }
1727+
1728+ /**
1729+ * Start event.
1730+ * @return true, if successful
1731+ */
1732+ public static boolean startEvent()
1733+ {
1734+ if (!startEventOk())
1735+ {
1736+ if (Config.DEBUG)
1737+ _log.log(Level.WARNING, _eventName + " Engine[startEvent()]: startEventOk() = false");
1738+ return false;
1739+ }
1740+
1741+ _teleport = false;
1742+
1743+ sit();
1744+
1745+ afterStartOperations();
1746+
1747+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: Started. Go Capture the Flags!"));
1748+ _started = true;
1749+
1750+ return true;
1751+ }
1752+
1753+ /**
1754+ * After start operations.
1755+ */
1756+ private static void afterStartOperations()
1757+ {
1758+ synchronized (_players)
1759+ {
1760+ for (Player player : _players)
1761+ if (player != null)
1762+ {
1763+ player._teamNameHaveFlagCTF = null;
1764+ player._haveFlagCTF = false;
1765+ }
1766+ }
1767+ }
1768+
1769+ /**
1770+ * Restarts Event checks if event was aborted. and if true cancels restart task
1771+ */
1772+ public synchronized static void restartEvent()
1773+ {
1774+ _log.info(_eventName + ": Event has been restarted...");
1775+ _joining = false;
1776+ _started = false;
1777+ _inProgress = false;
1778+ _aborted = false;
1779+ long delay = _intervalBetweenMatches;
1780+
1781+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: joining period will be avaible again in " + _intervalBetweenMatches + " minutes!"));
1782+
1783+ waiter(delay);
1784+
1785+ try
1786+ {
1787+ if (!_aborted)
1788+ autoEvent(); // start a new event
1789+ else
1790+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: next event aborted!"));
1791+
1792+ }
1793+ catch (Exception e)
1794+ {
1795+ _log.log(Level.SEVERE, _eventName + ": Error While Trying to restart Event...", e);
1796+ e.printStackTrace();
1797+ }
1798+ }
1799+
1800+ /**
1801+ * Finish event.
1802+ */
1803+ public static void finishEvent()
1804+ {
1805+ if (!finishEventOk())
1806+ {
1807+ if (Config.DEBUG)
1808+ _log.log(Level.WARNING, _eventName + " Engine[finishEvent]: finishEventOk() = false");
1809+ return;
1810+ }
1811+
1812+ _started = false;
1813+ _aborted = false;
1814+ unspawnEventNpc();
1815+
1816+ afterFinishOperations();
1817+
1818+ if (_teamEvent)
1819+ {
1820+ processTopTeam();
1821+
1822+ if (_topScore != 0)
1823+ {
1824+ playKneelAnimation(_topTeam);
1825+
1826+ if (Config.CTF_ANNOUNCE_TEAM_STATS)
1827+ {
1828+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, " Team Statistics:"));
1829+ for (String team : _teams)
1830+ {
1831+ int _flags_ = teamPointsCount(team);
1832+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: Team " + team + " - Flags taken: " + _flags_));
1833+ }
1834+ }
1835+
1836+ if (_topTeam != null)
1837+ {
1838+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: Team " + _topTeam + " wins the match, with " + _topScore + " flags taken!"));
1839+ }
1840+ else
1841+ {
1842+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: The event finished with a TIE: " + _topScore + " flags taken by each team!"));
1843+ }
1844+ rewardTeam(_topTeam);
1845+
1846+ if (Config.CTF_STATS_LOGGER)
1847+ {
1848+ _log.info("**** " + _eventName + " ****");
1849+ _log.info(_eventName + " Team Statistics:");
1850+ for (String team : _teams)
1851+ {
1852+ int _flags_ = teamPointsCount(team);
1853+ _log.info("Team: " + team + " - Flags taken: " + _flags_);
1854+ }
1855+
1856+ _log.info(_eventName + ": Team " + _topTeam + " wins the match, with " + _topScore + " flags taken!");
1857+ }
1858+
1859+ }
1860+ else
1861+ {
1862+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: The event finished with a TIE: No team wins the match (nobody took flags)!"));
1863+
1864+ if (Config.CTF_STATS_LOGGER)
1865+ _log.info(_eventName + ": No team win the match (nobody took flags).");
1866+
1867+ rewardTeam(_topTeam);
1868+ }
1869+
1870+ }
1871+ else
1872+ {
1873+ processTopPlayer();
1874+ }
1875+
1876+ teleportFinish();
1877+ }
1878+
1879+ /**
1880+ * After finish operations.
1881+ */
1882+ private static void afterFinishOperations()
1883+ {
1884+ unspawnAllFlags();
1885+ }
1886+
1887+ /**
1888+ * Abort event.
1889+ */
1890+ public static void abortEvent()
1891+ {
1892+ if (!_joining && !_teleport && !_started)
1893+ return;
1894+
1895+ if (_joining && !_teleport && !_started)
1896+ {
1897+ unspawnEventNpc();
1898+ cleanCTF();
1899+ _joining = false;
1900+ _inProgress = false;
1901+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: Match aborted!"));
1902+ return;
1903+ }
1904+ _joining = false;
1905+ _teleport = false;
1906+ _started = false;
1907+ _aborted = true;
1908+ unspawnEventNpc();
1909+
1910+ afterFinish();
1911+
1912+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: Match aborted!"));
1913+ teleportFinish();
1914+ }
1915+
1916+ /**
1917+ * After finish.
1918+ */
1919+ private static void afterFinish()
1920+ {
1921+ unspawnAllFlags();
1922+ }
1923+
1924+ /**
1925+ * Teleport finish.
1926+ */
1927+ public static void teleportFinish()
1928+ {
1929+ sit();
1930+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: Teleport back to participation NPC in 10 seconds!"));
1931+
1932+ ThreadPool.schedule(new Runnable()
1933+ {
1934+ @Override
1935+ public void run()
1936+ {
1937+ synchronized (_players)
1938+ {
1939+ for (Player player : _players)
1940+ {
1941+ if (player != null)
1942+ {
1943+ if (player.isOnlineInt() != 0)
1944+ player.teleToLocation(_npcX, _npcY, _npcZ, 0);
1945+ else
1946+ {
1947+ try (java.sql.Connection con = L2DatabaseFactory.getInstance().getConnection();)
1948+ {
1949+ PreparedStatement statement = con.prepareStatement("UPDATE characters SET x=?, y=?, z=? WHERE char_name=?");
1950+ statement.setInt(1, _npcX);
1951+ statement.setInt(2, _npcY);
1952+ statement.setInt(3, _npcZ);
1953+ statement.setString(4, player.getName());
1954+ statement.execute();
1955+ statement.close();
1956+ }
1957+ catch (Exception e)
1958+ {
1959+ e.printStackTrace();
1960+
1961+ _log.log(Level.SEVERE, e.getMessage(), e);
1962+ }
1963+ }
1964+ }
1965+ }
1966+ }
1967+
1968+ sit();
1969+ cleanCTF();
1970+ }
1971+ }, 10000);
1972+ }
1973+
1974+ protected static class AutoEventTask implements Runnable
1975+ {
1976+ @Override
1977+ public void run()
1978+ {
1979+ _log.info("Starting " + _eventName + "!");
1980+ _log.info("Matchs Are Restarted At Every: " + getIntervalBetweenMatchs() + " Minutes.");
1981+ if (checkAutoEventStartJoinOk() && startJoin() && !_aborted)
1982+ {
1983+ if (_joinTime > 0)
1984+ waiter(_joinTime * 60 * 1000); // minutes for join event
1985+ else if (_joinTime <= 0)
1986+ {
1987+ _log.info(_eventName + ": join time <=0 aborting event.");
1988+ abortEvent();
1989+ return;
1990+ }
1991+ if (startTeleport() && !_aborted)
1992+ {
1993+ waiter(30 * 1000); // 30 sec wait time untill start fight after teleported
1994+ if (startEvent() && !_aborted)
1995+ {
1996+ _log.log(Level.WARNING, _eventName + ": waiting.....minutes for event time " + _eventTime);
1997+
1998+ waiter(_eventTime * 60 * 1000); // minutes for event time
1999+ finishEvent();
2000+
2001+ _log.info(_eventName + ": waiting... delay for final messages ");
2002+ waiter(60000);// just a give a delay delay for final messages
2003+ sendFinalMessages();
2004+
2005+ if (!_started && !_aborted)
2006+ { // if is not already started and it's not aborted
2007+ _log.info(_eventName + ": waiting.....delay for restart event " + _intervalBetweenMatches + " minutes.");
2008+ waiter(60000);// just a give a delay to next restart
2009+
2010+ try
2011+ {
2012+ if (!_aborted)
2013+ restartEvent();
2014+ }
2015+ catch (Exception e)
2016+ {
2017+ _log.log(Level.SEVERE, "Error while tying to Restart Event", e);
2018+ e.printStackTrace();
2019+ }
2020+ }
2021+ }
2022+ }
2023+ else if (!_aborted)
2024+ {
2025+ abortEvent();
2026+ restartEvent();
2027+ }
2028+ }
2029+ }
2030+ }
2031+
2032+ /**
2033+ * Auto event.
2034+ */
2035+ public static void autoEvent()
2036+ {
2037+ ThreadPool.execute(new AutoEventTask());
2038+ }
2039+
2040+ // start without restart
2041+ /**
2042+ * Event once start.
2043+ */
2044+ public static void eventOnceStart()
2045+ {
2046+
2047+ if (startJoin() && !_aborted)
2048+ {
2049+ if (_joinTime > 0)
2050+ waiter(_joinTime * 60 * 1000); // minutes for join event
2051+ else if (_joinTime <= 0)
2052+ {
2053+ abortEvent();
2054+ return;
2055+ }
2056+ if (startTeleport() && !_aborted)
2057+ {
2058+ waiter(1 * 60 * 1000); // 1 min wait time untill start fight after teleported
2059+ if (startEvent() && !_aborted)
2060+ {
2061+ waiter(_eventTime * 60 * 1000); // minutes for event time
2062+ finishEvent();
2063+ }
2064+ }
2065+ else if (!_aborted)
2066+ {
2067+ abortEvent();
2068+ }
2069+ }
2070+
2071+ }
2072+
2073+ /**
2074+ * Waiter.
2075+ * @param interval the interval
2076+ */
2077+ protected static void waiter(long interval)
2078+ {
2079+ long startWaiterTime = System.currentTimeMillis();
2080+ int seconds = (int) (interval / 1000);
2081+
2082+ while (startWaiterTime + interval > System.currentTimeMillis() && !_aborted)
2083+ {
2084+ seconds--; // Here because we don't want to see two time announce at the same time
2085+
2086+ if (_joining || _started || _teleport)
2087+ {
2088+ switch (seconds)
2089+ {
2090+ case 3600: // 1 hour left
2091+ removeOfflinePlayers();
2092+
2093+ if (_joining)
2094+ {
2095+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: Joinable in " + _joiningLocationName + "!"));
2096+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: " + seconds / 60 / 60 + " hours till registration close!"));
2097+ }
2098+ else if (_started)
2099+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: " + seconds / 60 / 60 + " hours till event finish!"));
2100+
2101+ break;
2102+ case 1800: // 30 minutes left
2103+ case 900: // 15 minutes left
2104+ case 600: // 10 minutes left
2105+ case 300: // 5 minutes left
2106+ case 240: // 4 minutes left
2107+ case 180: // 3 minutes left
2108+ case 120: // 2 minutes left
2109+ case 60: // 1 minute left
2110+ // removeOfflinePlayers();
2111+
2112+ if (_joining)
2113+ {
2114+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: Joinable in " + _joiningLocationName + "!"));
2115+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: " + seconds / 60 + " minutes till registration close!"));
2116+ }
2117+ else if (_started)
2118+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: " + seconds / 60 + " minutes till event finish!"));
2119+
2120+ break;
2121+ case 30: // 30 seconds left
2122+ case 15: // 15 seconds left
2123+ case 10: // 10 seconds left
2124+ removeOfflinePlayers();
2125+ case 3: // 3 seconds left
2126+ case 2: // 2 seconds left
2127+ case 1: // 1 seconds left
2128+
2129+ if (_joining)
2130+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: " + seconds + " seconds till registration close!"));
2131+ else if (_teleport)
2132+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: " + seconds + " seconds till start fight!"));
2133+ else if (_started)
2134+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: " + seconds + " seconds till event finish!"));
2135+
2136+ break;
2137+ }
2138+ }
2139+
2140+ long startOneSecondWaiterStartTime = System.currentTimeMillis();
2141+
2142+ // Only the try catch with Thread.sleep(1000) give bad countdown on high wait times
2143+ while (startOneSecondWaiterStartTime + 1000 > System.currentTimeMillis())
2144+ {
2145+ try
2146+ {
2147+ Thread.sleep(1);
2148+ }
2149+ catch (InterruptedException ie)
2150+ {
2151+ ie.printStackTrace();
2152+ }
2153+ }
2154+ }
2155+ }
2156+
2157+ /**
2158+ * Sit.
2159+ */
2160+ public static void sit()
2161+ {
2162+ if (_sitForced)
2163+ _sitForced = false;
2164+ else
2165+ _sitForced = true;
2166+
2167+ synchronized (_players)
2168+ {
2169+ for (Player player : _players)
2170+ {
2171+ if (player != null)
2172+ {
2173+ if (_sitForced)
2174+ {
2175+ player.stopMove(null);
2176+ player.abortAttack();
2177+ player.abortCast();
2178+
2179+ if (!player.isSitting())
2180+ player.sitDown();
2181+ }
2182+ else
2183+ {
2184+ if (player.isSitting())
2185+ player.standUp();
2186+ }
2187+ }
2188+ }
2189+ }
2190+
2191+ }
2192+
2193+ /**
2194+ * Removes the offline players.
2195+ */
2196+ public static void removeOfflinePlayers()
2197+ {
2198+ try
2199+ {
2200+ if (_playersShuffle == null || _playersShuffle.isEmpty())
2201+ return;
2202+ else if (_playersShuffle.size() > 0)
2203+ {
2204+ for (Player player : _playersShuffle)
2205+ {
2206+ if (player == null)
2207+ _playersShuffle.remove(player);
2208+ else if (player.isOnlineInt() == 0 || player.isInJail() || player.isInStoreMode())
2209+ removePlayer(player);
2210+ if (_playersShuffle.size() == 0 || _playersShuffle.isEmpty())
2211+ break;
2212+ }
2213+ }
2214+ }
2215+ catch (Exception e)
2216+ {
2217+ e.printStackTrace();
2218+
2219+ _log.log(Level.SEVERE, e.getMessage(), e);
2220+ return;
2221+ }
2222+ }
2223+
2224+ /**
2225+ * Start event ok.
2226+ * @return true, if successful
2227+ */
2228+ private static boolean startEventOk()
2229+ {
2230+ if (_joining || !_teleport || _started)
2231+ return false;
2232+
2233+ if (Config.CTF_EVEN_TEAMS.equals("NO") || Config.CTF_EVEN_TEAMS.equals("BALANCE"))
2234+ {
2235+ if (_teamPlayersCount.contains(0))
2236+ return false;
2237+ }
2238+ else if (Config.CTF_EVEN_TEAMS.equals("SHUFFLE"))
2239+ {
2240+ Vector<Player> playersShuffleTemp = new Vector<>();
2241+ int loopCount = 0;
2242+
2243+ loopCount = _playersShuffle.size();
2244+
2245+ for (int i = 0; i < loopCount; i++)
2246+ {
2247+ playersShuffleTemp.add(_playersShuffle.get(i));
2248+ }
2249+
2250+ _playersShuffle = playersShuffleTemp;
2251+ playersShuffleTemp.clear();
2252+ }
2253+ return true;
2254+ }
2255+
2256+ /**
2257+ * Finish event ok.
2258+ * @return true, if successful
2259+ */
2260+ private static boolean finishEventOk()
2261+ {
2262+ if (!_started)
2263+ return false;
2264+
2265+ return true;
2266+ }
2267+
2268+ /**
2269+ * Adds the player ok.
2270+ * @param teamName the team name
2271+ * @param eventPlayer the event player
2272+ * @return true, if successful
2273+ */
2274+ private static boolean addPlayerOk(String teamName, Player eventPlayer)
2275+ {
2276+ if (checkShufflePlayers(eventPlayer) || eventPlayer._inEventCTF)
2277+ {
2278+ eventPlayer.sendMessage("You already participated in the event!");
2279+ return false;
2280+ }
2281+
2282+ if (OlympiadManager.getInstance().isRegistered(eventPlayer) || eventPlayer.isInOlympiadMode())
2283+ {
2284+ eventPlayer.sendMessage("You already participated in Olympiad!");
2285+ return false;
2286+ }
2287+
2288+ if (eventPlayer._active_boxes > 1 && !Config.ALLOW_DUALBOX_EVENT)
2289+ {
2290+ List<String> players_in_boxes = eventPlayer.active_boxes_characters;
2291+
2292+ if (players_in_boxes != null && players_in_boxes.size() > 1)
2293+ for (String character_name : players_in_boxes)
2294+ {
2295+ Player player = World.getInstance().getPlayer(character_name);
2296+
2297+ if (player != null && player._inEventCTF)
2298+ {
2299+ eventPlayer.sendMessage("You already participated in event with another char!");
2300+ return false;
2301+ }
2302+ }
2303+ }
2304+
2305+ if (!Config.CTF_ALLOW_HEALER_CLASSES && (eventPlayer.getClassId() == ClassId.BISHOP || eventPlayer.getClassId() == ClassId.CARDINAL || eventPlayer.getClassId() == ClassId.ELVEN_ORACLE || eventPlayer.getClassId() == ClassId.ELVEN_ELDER || eventPlayer.getClassId() == ClassId.SHILLIEN_ORACLE || eventPlayer.getClassId() == ClassId.SHILLIEN_ELDER))
2306+ {
2307+ eventPlayer.sendMessage("You cant join with Healer Class!");
2308+ return false;
2309+ }
2310+
2311+ synchronized (_players)
2312+ {
2313+ for (Player player : _players)
2314+ {
2315+ if (player.getObjectId() == eventPlayer.getObjectId())
2316+ {
2317+ eventPlayer.sendMessage("You already participated in the event!");
2318+ return false;
2319+ }
2320+ else if (player.getName().equalsIgnoreCase(eventPlayer.getName()))
2321+ {
2322+ eventPlayer.sendMessage("You already participated in the event!");
2323+ return false;
2324+ }
2325+ }
2326+
2327+ if (_players.contains(eventPlayer))
2328+ {
2329+ eventPlayer.sendMessage("You already participated in the event!");
2330+ return false;
2331+ }
2332+ }
2333+
2334+ if (CTF._savePlayers.contains(eventPlayer.getName()))
2335+ {
2336+ eventPlayer.sendMessage("You already participated in another event!");
2337+ return false;
2338+ }
2339+
2340+ if (Config.CTF_EVEN_TEAMS.equals("NO"))
2341+ return true;
2342+
2343+ else if (Config.CTF_EVEN_TEAMS.equals("BALANCE"))
2344+ {
2345+ boolean allTeamsEqual = true;
2346+ int countBefore = -1;
2347+
2348+ for (int playersCount : _teamPlayersCount)
2349+ {
2350+ if (countBefore == -1)
2351+ countBefore = playersCount;
2352+
2353+ if (countBefore != playersCount)
2354+ {
2355+ allTeamsEqual = false;
2356+ break;
2357+ }
2358+
2359+ countBefore = playersCount;
2360+ }
2361+
2362+ if (allTeamsEqual)
2363+ return true;
2364+
2365+ countBefore = Integer.MAX_VALUE;
2366+
2367+ for (int teamPlayerCount : _teamPlayersCount)
2368+ {
2369+ if (teamPlayerCount < countBefore)
2370+ countBefore = teamPlayerCount;
2371+ }
2372+
2373+ Vector<String> joinableTeams = new Vector<>();
2374+
2375+ for (String team : _teams)
2376+ {
2377+ if (teamPlayersCount(team) == countBefore)
2378+ joinableTeams.add(team);
2379+ }
2380+
2381+ if (joinableTeams.contains(teamName))
2382+ return true;
2383+ }
2384+ else if (Config.CTF_EVEN_TEAMS.equals("SHUFFLE"))
2385+ return true;
2386+
2387+ eventPlayer.sendMessage("Too many players in team \"" + teamName + "\"");
2388+ return false;
2389+ }
2390+
2391+ /**
2392+ * Sets the user data.
2393+ */
2394+ public static void setUserData()
2395+ {
2396+ synchronized (_players)
2397+ {
2398+ for (Player player : _players)
2399+ {
2400+ player._originalNameColorCTF = player.getAppearance().getNameColor();
2401+ player._originalKarmaCTF = player.getKarma();
2402+ player._originalTitleCTF = player.getTitle();
2403+ player.getAppearance().setNameColor(_teamColors.get(_teams.indexOf(player._teamNameCTF)));
2404+ player.setKarma(0);
2405+ if (Config.CTF_AURA)
2406+ {
2407+ if (_teams.size() >= 2)
2408+ player.setTeam(_teams.indexOf(player._teamNameCTF) + 1);
2409+ }
2410+
2411+ if (player.isMounted())
2412+ {
2413+
2414+ if (player.setMount(0, 0, 0))
2415+ {
2416+ if (player.isFlying())
2417+ {
2418+ player.removeSkill(SkillTable.getInstance().getInfo(4289, 1));
2419+ }
2420+
2421+ Ride dismount = new Ride(player.getObjectId(), Ride.ACTION_DISMOUNT, 0);
2422+ player.broadcastPacket(dismount);
2423+ player.setMountObjectId(0);
2424+ }
2425+
2426+ }
2427+ player.broadcastUserInfo();
2428+ }
2429+ }
2430+
2431+ }
2432+
2433+ /**
2434+ * Dump data.
2435+ */
2436+ public static void dumpData()
2437+ {
2438+ _log.info("");
2439+ _log.info("");
2440+
2441+ if (!_joining && !_teleport && !_started)
2442+ {
2443+ _log.info("<<---------------------------------->>");
2444+ _log.info(">> " + _eventName + " Engine infos dump (INACTIVE) <<");
2445+ _log.info("<<--^----^^-----^----^^------^^----->>");
2446+ }
2447+ else if (_joining && !_teleport && !_started)
2448+ {
2449+ _log.info("<<--------------------------------->>");
2450+ _log.info(">> " + _eventName + " Engine infos dump (JOINING) <<");
2451+ _log.info("<<--^----^^-----^----^^------^----->>");
2452+ }
2453+ else if (!_joining && _teleport && !_started)
2454+ {
2455+ _log.info("<<---------------------------------->>");
2456+ _log.info(">> " + _eventName + " Engine infos dump (TELEPORT) <<");
2457+ _log.info("<<--^----^^-----^----^^------^^----->>");
2458+ }
2459+ else if (!_joining && !_teleport && _started)
2460+ {
2461+ _log.info("<<--------------------------------->>");
2462+ _log.info(">> " + _eventName + " Engine infos dump (STARTED) <<");
2463+ _log.info("<<--^----^^-----^----^^------^----->>");
2464+ }
2465+
2466+ _log.info("Name: " + _eventName);
2467+ _log.info("Desc: " + _eventDesc);
2468+ _log.info("Join location: " + _joiningLocationName);
2469+ _log.info("Min lvl: " + _minlvl);
2470+ _log.info("Max lvl: " + _maxlvl);
2471+ _log.info("");
2472+ _log.info("##########################");
2473+ _log.info("# _teams(Vector<String>) #");
2474+ _log.info("##########################");
2475+
2476+ for (String team : _teams)
2477+ _log.info(team + " Flags Taken :" + _teamPointsCount.get(_teams.indexOf(team)));
2478+
2479+ if (Config.CTF_EVEN_TEAMS.equals("SHUFFLE"))
2480+ {
2481+ _log.info("");
2482+ _log.info("#########################################");
2483+ _log.info("# _playersShuffle(Vector<L2PcInstance>) #");
2484+ _log.info("#########################################");
2485+
2486+ for (Player player : _playersShuffle)
2487+ {
2488+ if (player != null)
2489+ _log.info("Name: " + player.getName());
2490+ }
2491+ }
2492+
2493+ _log.info("");
2494+ _log.info("##################################");
2495+ _log.info("# _players(Vector<L2PcInstance>) #");
2496+ _log.info("##################################");
2497+
2498+ synchronized (_players)
2499+ {
2500+ for (Player player : _players)
2501+ {
2502+ if (player != null)
2503+ _log.info("Name: " + player.getName() + " Team: " + player._teamNameCTF + " Flags :" + player._countCTFflags);
2504+ }
2505+ }
2506+
2507+ _log.info("");
2508+ _log.info("#####################################################################");
2509+ _log.info("# _savePlayers(Vector<String>) and _savePlayerTeams(Vector<String>) #");
2510+ _log.info("#####################################################################");
2511+
2512+ for (String player : _savePlayers)
2513+ _log.info("Name: " + player + " Team: " + _savePlayerTeams.get(_savePlayers.indexOf(player)));
2514+
2515+ _log.info("");
2516+ _log.info("");
2517+
2518+ dumpLocalEventInfo();
2519+
2520+ }
2521+
2522+ /**
2523+ * Dump local event info.
2524+ */
2525+ private static void dumpLocalEventInfo()
2526+ {
2527+ _log.info("**********==CTF==************");
2528+ _log.info("CTF._teamPointsCount:" + _teamPointsCount.toString());
2529+ _log.info("CTF._flagIds:" + _flagIds.toString());
2530+ _log.info("CTF._flagSpawns:" + _flagSpawns.toString());
2531+ _log.info("CTF._throneSpawns:" + _throneSpawns.toString());
2532+ _log.info("CTF._flagsTaken:" + _flagsTaken.toString());
2533+ _log.info("CTF._flagsX:" + _flagsX.toString());
2534+ _log.info("CTF._flagsY:" + _flagsY.toString());
2535+ _log.info("CTF._flagsZ:" + _flagsZ.toString());
2536+ _log.info("************EOF**************\n");
2537+ _log.info("");
2538+ }
2539+
2540+ /**
2541+ * Load data.
2542+ */
2543+ public static void loadData()
2544+ {
2545+ _eventName = new String();
2546+ _eventDesc = new String();
2547+ _joiningLocationName = new String();
2548+ _savePlayers = new Vector<>();
2549+ synchronized (_players)
2550+ {
2551+ _players = new Vector<>();
2552+ }
2553+
2554+ _topTeam = new String();
2555+ _teams = new Vector<>();
2556+ _savePlayerTeams = new Vector<>();
2557+ _playersShuffle = new Vector<>();
2558+ _teamPlayersCount = new Vector<>();
2559+ _teamPointsCount = new Vector<>();
2560+ _teamColors = new Vector<>();
2561+ _teamsX = new Vector<>();
2562+ _teamsY = new Vector<>();
2563+ _teamsZ = new Vector<>();
2564+
2565+ _throneSpawns = new Vector<>();
2566+ _flagSpawns = new Vector<>();
2567+ _flagsTaken = new Vector<>();
2568+ _flagIds = new Vector<>();
2569+ _flagsX = new Vector<>();
2570+ _flagsY = new Vector<>();
2571+ _flagsZ = new Vector<>();
2572+
2573+ _joining = false;
2574+ _teleport = false;
2575+ _started = false;
2576+ _sitForced = false;
2577+ _aborted = false;
2578+ _inProgress = false;
2579+
2580+ _npcId = 0;
2581+ _npcX = 0;
2582+ _npcY = 0;
2583+ _npcZ = 0;
2584+ _npcHeading = 0;
2585+ _rewardId = 0;
2586+ _rewardAmount = 0;
2587+ _topScore = 0;
2588+ _minlvl = 0;
2589+ _maxlvl = 0;
2590+ _joinTime = 0;
2591+ _eventTime = 0;
2592+ _minPlayers = 0;
2593+ _maxPlayers = 0;
2594+ _intervalBetweenMatches = 0;
2595+
2596+ try (java.sql.Connection con = L2DatabaseFactory.getInstance().getConnection();)
2597+ {
2598+ PreparedStatement statement = con.prepareStatement("Select * from ctf");
2599+ ResultSet rs = statement.executeQuery();
2600+
2601+ int teams = 0;
2602+
2603+ while (rs.next())
2604+ {
2605+ _eventName = rs.getString("eventName");
2606+ _eventDesc = rs.getString("eventDesc");
2607+ _joiningLocationName = rs.getString("joiningLocation");
2608+ _minlvl = rs.getInt("minlvl");
2609+ _maxlvl = rs.getInt("maxlvl");
2610+ _npcId = rs.getInt("npcId");
2611+ _npcX = rs.getInt("npcX");
2612+ _npcY = rs.getInt("npcY");
2613+ _npcZ = rs.getInt("npcZ");
2614+ _npcHeading = rs.getInt("npcHeading");
2615+ _rewardId = rs.getInt("rewardId");
2616+ _rewardAmount = rs.getInt("rewardAmount");
2617+ teams = rs.getInt("teamsCount");
2618+ _joinTime = rs.getInt("joinTime");
2619+ _eventTime = rs.getInt("eventTime");
2620+ _minPlayers = rs.getInt("minPlayers");
2621+ _maxPlayers = rs.getInt("maxPlayers");
2622+ _intervalBetweenMatches = rs.getLong("delayForNextEvent");
2623+ }
2624+ statement.close();
2625+ rs.close();
2626+
2627+ int index = -1;
2628+ if (teams > 0)
2629+ index = 0;
2630+ while (index < teams && index > -1)
2631+ {
2632+ statement = con.prepareStatement("Select * from ctf_teams where teamId = ?");
2633+ statement.setInt(1, index);
2634+ rs = statement.executeQuery();
2635+ while (rs.next())
2636+ {
2637+ _teams.add(rs.getString("teamName"));
2638+ _teamPlayersCount.add(0);
2639+ _teamPointsCount.add(0);
2640+ _teamColors.add(0);
2641+ _teamsX.add(0);
2642+ _teamsY.add(0);
2643+ _teamsZ.add(0);
2644+ _teamsX.set(index, rs.getInt("teamX"));
2645+ _teamsY.set(index, rs.getInt("teamY"));
2646+ _teamsZ.set(index, rs.getInt("teamZ"));
2647+ _teamColors.set(index, rs.getInt("teamColor"));
2648+
2649+ _flagsX.add(0);
2650+ _flagsY.add(0);
2651+ _flagsZ.add(0);
2652+ _flagsX.set(index, rs.getInt("flagX"));
2653+ _flagsY.set(index, rs.getInt("flagY"));
2654+ _flagsZ.set(index, rs.getInt("flagZ"));
2655+ _flagSpawns.add(null);
2656+ _flagIds.add(_FlagNPC);
2657+ _flagsTaken.add(false);
2658+
2659+ }
2660+ index++;
2661+ statement.close();
2662+ rs.close();
2663+ }
2664+ }
2665+ catch (Exception e)
2666+ {
2667+ e.printStackTrace();
2668+
2669+ _log.log(Level.SEVERE, "Exception: loadData(): " + e.getMessage());
2670+ }
2671+ }
2672+
2673+ /**
2674+ * Save data.
2675+ */
2676+ public static void saveData()
2677+ {
2678+ try (java.sql.Connection con = L2DatabaseFactory.getInstance().getConnection())
2679+ {
2680+ PreparedStatement statement;
2681+
2682+ statement = con.prepareStatement("Delete from ctf");
2683+ statement.execute();
2684+ statement.close();
2685+
2686+ statement = con.prepareStatement("INSERT INTO ctf (eventName, eventDesc, joiningLocation, minlvl, maxlvl, npcId, npcX, npcY, npcZ, npcHeading, rewardId, rewardAmount, teamsCount, joinTime, eventTime, minPlayers, maxPlayers,delayForNextEvent) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
2687+ statement.setString(1, _eventName);
2688+ statement.setString(2, _eventDesc);
2689+ statement.setString(3, _joiningLocationName);
2690+ statement.setInt(4, _minlvl);
2691+ statement.setInt(5, _maxlvl);
2692+ statement.setInt(6, _npcId);
2693+ statement.setInt(7, _npcX);
2694+ statement.setInt(8, _npcY);
2695+ statement.setInt(9, _npcZ);
2696+ statement.setInt(10, _npcHeading);
2697+ statement.setInt(11, _rewardId);
2698+ statement.setInt(12, _rewardAmount);
2699+ statement.setInt(13, _teams.size());
2700+ statement.setInt(14, _joinTime);
2701+ statement.setInt(15, _eventTime);
2702+ statement.setInt(16, _minPlayers);
2703+ statement.setInt(17, _maxPlayers);
2704+ statement.setLong(18, _intervalBetweenMatches);
2705+ statement.execute();
2706+ statement.close();
2707+
2708+ statement = con.prepareStatement("Delete from ctf_teams");
2709+ statement.execute();
2710+ statement.close();
2711+
2712+ for (String teamName : _teams)
2713+ {
2714+ int index = _teams.indexOf(teamName);
2715+
2716+ if (index == -1)
2717+ return;
2718+ statement = con.prepareStatement("INSERT INTO ctf_teams (teamId ,teamName, teamX, teamY, teamZ, teamColor, flagX, flagY, flagZ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
2719+ statement.setInt(1, index);
2720+ statement.setString(2, teamName);
2721+ statement.setInt(3, _teamsX.get(index));
2722+ statement.setInt(4, _teamsY.get(index));
2723+ statement.setInt(5, _teamsZ.get(index));
2724+ statement.setInt(6, _teamColors.get(index));
2725+
2726+ statement.setInt(7, _flagsX.get(index));
2727+ statement.setInt(8, _flagsY.get(index));
2728+ statement.setInt(9, _flagsZ.get(index));
2729+
2730+ statement.execute();
2731+ statement.close();
2732+ }
2733+ }
2734+ catch (Exception e)
2735+ {
2736+ e.printStackTrace();
2737+
2738+ _log.log(Level.SEVERE, "Exception: saveData(): " + e.getMessage());
2739+ }
2740+ }
2741+
2742+ /**
2743+ * Show event html.
2744+ * @param eventPlayer the event player
2745+ * @param objectId the object id
2746+ */
2747+ public static void showEventHtml(Player eventPlayer, String objectId)
2748+ {
2749+ try
2750+ {
2751+ NpcHtmlMessage adminReply = new NpcHtmlMessage(5);
2752+
2753+ StringBuilder replyMSG = new StringBuilder("<html><title>CTF Event</title><body>");
2754+ replyMSG.append("<center><img src=\"L2UI_CH3.herotower_deco\" width=256 height=32></center><br>");
2755+ replyMSG.append("<center><font color=\"LEVEL\">Capture the Flag</font></center><br>");
2756+ replyMSG.append("<font color=\"00CCFF\"><b>Event Information</b></font><br1>");
2757+ replyMSG.append("Team vs team <font color=\"00FF00\">full buffs</font> event.<br1>");
2758+ replyMSG.append("Each team has a flag they got to protect.<br1>");
2759+ replyMSG.append("The team that captures the most number of flags wins.<br1>");
2760+ replyMSG.append("<font color=\"FF0000\">Teams will be reandomly generated!</font><br><br>");
2761+
2762+ if (!_started && !_joining)
2763+ {
2764+ replyMSG.append("<center>Wait till the admin/gm start the participation.</center><br>");
2765+ replyMSG.append("<center><img src=\"L2UI_CH3.herotower_deco\" width=256 height=32></center>");
2766+ }
2767+ else if (Config.CTF_EVEN_TEAMS.equals("SHUFFLE") && !checkMaxPlayers(_playersShuffle.size()))
2768+ {
2769+ if (!_started)
2770+ {
2771+ replyMSG.append("<center>Currently participated: <font color=\"00FF00\">" + _playersShuffle.size() + "</font></center><br>");
2772+ replyMSG.append("<center>Max players: <font color=\"00FF00\">" + _maxPlayers + "</font></center><br><br>");
2773+ replyMSG.append("<center><font color=\"FFFF00\">You can't participate to this event.</font></center><br>");
2774+ replyMSG.append("<center><img src=\"L2UI_CH3.herotower_deco\" width=256 height=32></center>");
2775+ }
2776+ }
2777+ else if (!_started && _joining && eventPlayer.getLevel() >= _minlvl && eventPlayer.getLevel() <= _maxlvl)
2778+ {
2779+ synchronized (_players)
2780+ {
2781+ if (_players.contains(eventPlayer) || _playersShuffle.contains(eventPlayer) || checkShufflePlayers(eventPlayer))
2782+ {
2783+ if (Config.CTF_EVEN_TEAMS.equals("SHUFFLE"))
2784+ replyMSG.append("<center><font color=\"3366CC\">You are already participating!</font></center><br>");
2785+ replyMSG.append("<center><font color=\"3366CC\">Wait till event start or remove your participation!</font><center><br>");
2786+ replyMSG.append("<center><button value=\"Remove\" action=\"bypass -h npc_" + objectId + "_ctf_player_leave\" width=75 height=21 back=\"L2UI_ch3.Btn1_normalOn\" fore=\"L2UI_ch3.Btn1_normal\"></center><br>");
2787+ replyMSG.append("<center>Joined Players: <font color=\"00FF00\">" + _playersShuffle.size() + "</font></center><br>");
2788+ replyMSG.append("<center><img src=\"L2UI_CH3.herotower_deco\" width=256 height=32></center>");
2789+ }
2790+ else if (Config.CTF_EVEN_TEAMS.equals("SHUFFLE"))
2791+ {
2792+ replyMSG.append("<center><font color=\"3366CC\">You want to participate in the event?</font></center><br>");
2793+ replyMSG.append("<center><td width=\"200\">Min lvl: <font color=\"00FF00\">" + _minlvl + "</font> Max lvl: <font color=\"00FF00\">" + _maxlvl + "</font></center></td><br><br>");
2794+ replyMSG.append("<center><button value=\"Join Event\" action=\"bypass -h npc_" + objectId + "_ctf_player_join eventShuffle\" width=75 height=21 back=\"L2UI_ch3.Btn1_normalOn\" fore=\"L2UI_ch3.Btn1_normal\"></center><br>");
2795+ replyMSG.append("<center>Joined Players:</font> <font color=\"LEVEL\">" + _playersShuffle.size() + "</center></font><br1>");
2796+ replyMSG.append("<center>Reward: <font color=\"LEVEL\">" + _rewardAmount + " " + ItemTable.getInstance().getTemplate(_rewardId).getName() + "</center></font><br>");
2797+ replyMSG.append("<center><img src=\"L2UI_CH3.herotower_deco\" width=256 height=32></center>");
2798+ }
2799+ }
2800+
2801+ }
2802+ else if (_started && !_joining)
2803+ {
2804+ replyMSG.append("<center>" + _eventName + " match is in progress.</center><br>");
2805+ replyMSG.append("<center><img src=\"L2UI_CH3.herotower_deco\" width=256 height=32></center>");
2806+ }
2807+ else if (eventPlayer.getLevel() < _minlvl || eventPlayer.getLevel() > _maxlvl)
2808+ {
2809+ replyMSG.append("Your lvl: <font color=\"00FF00\">" + eventPlayer.getLevel() + "</font><br>");
2810+ replyMSG.append("Min lvl: <font color=\"00FF00\">" + _minlvl + "</font> Max lvl: <font color=\"00FF00\">" + _maxlvl + "</font><br>");
2811+ replyMSG.append("<font color=\"FFFF00\">You can't participate to this event.</font><br>");
2812+ replyMSG.append("<center><img src=\"L2UI_CH3.herotower_deco\" width=256 height=32></center>");
2813+ }
2814+
2815+ replyMSG.append("</body></html>");
2816+ adminReply.setHtml(replyMSG.toString());
2817+ eventPlayer.sendPacket(adminReply);
2818+
2819+ // Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
2820+ eventPlayer.sendPacket(ActionFailed.STATIC_PACKET);
2821+ }
2822+ catch (Exception e)
2823+ {
2824+ e.printStackTrace();
2825+
2826+ _log.log(Level.SEVERE, _eventName + " Engine[showEventHtlm(" + eventPlayer.getName() + ", " + objectId + ")]: exception" + e.getMessage());
2827+ }
2828+ }
2829+
2830+ /**
2831+ * Adds the player.
2832+ * @param player the player
2833+ * @param teamName the team name
2834+ */
2835+ public static void addPlayer(Player player, String teamName)
2836+ {
2837+ if (!addPlayerOk(teamName, player))
2838+ return;
2839+
2840+ synchronized (_players)
2841+ {
2842+ if (Config.CTF_EVEN_TEAMS.equals("NO") || Config.CTF_EVEN_TEAMS.equals("BALANCE"))
2843+ {
2844+ player._teamNameCTF = teamName;
2845+ _players.add(player);
2846+ setTeamPlayersCount(teamName, teamPlayersCount(teamName) + 1);
2847+ }
2848+ else if (Config.CTF_EVEN_TEAMS.equals("SHUFFLE"))
2849+ _playersShuffle.add(player);
2850+ }
2851+
2852+ player._inEventCTF = true;
2853+ player._countCTFflags = 0;
2854+ player.sendMessage(_eventName + ": You successfully registered for the event.");
2855+ }
2856+
2857+ /**
2858+ * Removes the player.
2859+ * @param player the player
2860+ */
2861+ public static void removePlayer(Player player)
2862+ {
2863+ if (player._inEventCTF)
2864+ {
2865+ if (!_joining)
2866+ {
2867+ player.getAppearance().setNameColor(player._originalNameColorCTF);
2868+ player.setTitle(player._originalTitleCTF);
2869+ player.setKarma(player._originalKarmaCTF);
2870+ if (Config.CTF_AURA)
2871+ {
2872+ if (_teams.size() >= 2)
2873+ player.setTeam(0);// clear aura :P
2874+ }
2875+ player.broadcastUserInfo();
2876+ }
2877+
2878+ // after remove, all event data must be cleaned in player
2879+ player._originalNameColorCTF = 0;
2880+ player._originalTitleCTF = null;
2881+ player._originalKarmaCTF = 0;
2882+ player._teamNameCTF = new String();
2883+ player._countCTFflags = 0;
2884+ player._inEventCTF = false;
2885+
2886+ synchronized (_players)
2887+ {
2888+ if ((Config.CTF_EVEN_TEAMS.equals("NO") || Config.CTF_EVEN_TEAMS.equals("BALANCE")) && _players.contains(player))
2889+ {
2890+ setTeamPlayersCount(player._teamNameCTF, teamPlayersCount(player._teamNameCTF) - 1);
2891+ _players.remove(player);
2892+ }
2893+ else if (Config.CTF_EVEN_TEAMS.equals("SHUFFLE") && (!_playersShuffle.isEmpty() && _playersShuffle.contains(player)))
2894+ _playersShuffle.remove(player);
2895+ }
2896+
2897+ player.sendMessage("Your participation in the CTF event has been removed.");
2898+ }
2899+ }
2900+
2901+ /**
2902+ * Clean ctf.
2903+ */
2904+ public static void cleanCTF()
2905+ {
2906+ synchronized (_players)
2907+ {
2908+ for (Player player : _players)
2909+ {
2910+ if (player != null)
2911+ {
2912+ cleanEventPlayer(player);
2913+
2914+ removePlayer(player);
2915+ if (_savePlayers.contains(player.getName()))
2916+ _savePlayers.remove(player.getName());
2917+ player._inEventCTF = false;
2918+ }
2919+ }
2920+ }
2921+
2922+ if (_playersShuffle != null && !_playersShuffle.isEmpty())
2923+ {
2924+ for (Player player : _playersShuffle)
2925+ {
2926+ if (player != null)
2927+ player._inEventCTF = false;
2928+ }
2929+ }
2930+
2931+ _topScore = 0;
2932+ _topTeam = new String();
2933+ synchronized (_players)
2934+ {
2935+ _players = new Vector<>();
2936+ }
2937+
2938+ _playersShuffle = new Vector<>();
2939+ _savePlayers = new Vector<>();
2940+ _savePlayerTeams = new Vector<>();
2941+
2942+ _teamPointsCount = new Vector<>();
2943+ _teamPlayersCount = new Vector<>();
2944+
2945+ cleanLocalEventInfo();
2946+
2947+ _inProgress = false;
2948+
2949+ loadData();
2950+ }
2951+
2952+ /**
2953+ * Clean local event info.
2954+ */
2955+ private static void cleanLocalEventInfo()
2956+ {
2957+ _flagSpawns = new Vector<>();
2958+ _flagsTaken = new Vector<>();
2959+ }
2960+
2961+ /**
2962+ * Clean event player.
2963+ * @param player the player
2964+ */
2965+ private static void cleanEventPlayer(Player player)
2966+ {
2967+ if (player._haveFlagCTF)
2968+ removeFlagFromPlayer(player);
2969+ else
2970+ player.getInventory().destroyItemByItemId("", CTF._FLAG_IN_HAND_ITEM_ID, 1, player, null);
2971+ player._haveFlagCTF = false;
2972+ }
2973+
2974+ /**
2975+ * Adds the disconnected player.
2976+ * @param player the player
2977+ */
2978+ public static synchronized void addDisconnectedPlayer(Player player)
2979+ {
2980+ if ((Config.CTF_EVEN_TEAMS.equals("SHUFFLE") && (_teleport || _started)) || (Config.CTF_EVEN_TEAMS.equals("NO") || Config.CTF_EVEN_TEAMS.equals("BALANCE") && (_teleport || _started)))
2981+ {
2982+ if (Config.CTF_ON_START_REMOVE_ALL_EFFECTS)
2983+ {
2984+ player.stopAllEffects();
2985+ }
2986+
2987+ player._teamNameCTF = _savePlayerTeams.get(_savePlayers.indexOf(player.getName()));
2988+
2989+ synchronized (_players)
2990+ {
2991+ for (Player p : _players)
2992+ {
2993+ if (p == null)
2994+ {
2995+ continue;
2996+ }
2997+ // check by name incase player got new objectId
2998+ else if (p.getName().equals(player.getName()))
2999+ {
3000+ player._originalNameColorCTF = player.getAppearance().getNameColor();
3001+ player._originalTitleCTF = player.getTitle();
3002+ player._originalKarmaCTF = player.getKarma();
3003+ player._inEventCTF = true;
3004+ player._countCTFflags = p._countCTFflags;
3005+ _players.remove(p); // removing old object id from vector
3006+ _players.add(player); // adding new objectId to vector
3007+ break;
3008+ }
3009+ }
3010+ }
3011+
3012+ player.getAppearance().setNameColor(_teamColors.get(_teams.indexOf(player._teamNameCTF)));
3013+ player.setKarma(0);
3014+ if (Config.CTF_AURA)
3015+ {
3016+ if (_teams.size() >= 2)
3017+ player.setTeam(_teams.indexOf(player._teamNameCTF) + 1);
3018+ }
3019+ player.broadcastUserInfo();
3020+
3021+ int offset = Config.CTF_SPAWN_OFFSET;
3022+ player.teleToLocation(_teamsX.get(_teams.indexOf(player._teamNameCTF)) + Rnd.get(offset), _teamsY.get(_teams.indexOf(player._teamNameCTF)) + Rnd.get(offset), _teamsZ.get(_teams.indexOf(player._teamNameCTF)), offset);
3023+
3024+ afterAddDisconnectedPlayerOperations(player);
3025+
3026+ }
3027+ }
3028+
3029+ /**
3030+ * After add disconnected player operations.
3031+ * @param player the player
3032+ */
3033+ private static void afterAddDisconnectedPlayerOperations(Player player)
3034+ {
3035+ player._teamNameHaveFlagCTF = null;
3036+ player._haveFlagCTF = false;
3037+ checkRestoreFlags();
3038+ }
3039+
3040+ /**
3041+ * Shuffle teams.
3042+ */
3043+ public static void shuffleTeams()
3044+ {
3045+ int teamCount = 0, playersCount = 0;
3046+
3047+ synchronized (_players)
3048+ {
3049+ for (;;)
3050+ {
3051+ if (_playersShuffle.isEmpty())
3052+ break;
3053+
3054+ int playerToAddIndex = Rnd.nextInt(_playersShuffle.size());
3055+ Player player = null;
3056+ player = _playersShuffle.get(playerToAddIndex);
3057+
3058+ _players.add(player);
3059+ _players.get(playersCount)._teamNameCTF = _teams.get(teamCount);
3060+ _savePlayers.add(_players.get(playersCount).getName());
3061+ _savePlayerTeams.add(_teams.get(teamCount));
3062+ playersCount++;
3063+
3064+ if (teamCount == _teams.size() - 1)
3065+ teamCount = 0;
3066+ else
3067+ teamCount++;
3068+
3069+ _playersShuffle.remove(playerToAddIndex);
3070+ }
3071+ }
3072+
3073+ }
3074+
3075+ // Show looses and winners animations
3076+ /**
3077+ * Play kneel animation.
3078+ * @param teamName the team name
3079+ */
3080+ public static void playKneelAnimation(String teamName)
3081+ {
3082+ synchronized (_players)
3083+ {
3084+ for (Player player : _players)
3085+ {
3086+ if (player != null)
3087+ {
3088+ if (!player._teamNameCTF.equals(teamName))
3089+ {
3090+ player.broadcastPacket(new SocialAction(player, 7));
3091+ }
3092+ else if (player._teamNameCTF.equals(teamName))
3093+ {
3094+ player.broadcastPacket(new SocialAction(player, 3));
3095+ }
3096+ }
3097+ }
3098+ }
3099+
3100+ }
3101+
3102+ /**
3103+ * Reward team.
3104+ * @param teamName the team name
3105+ */
3106+ public static void rewardTeam(String teamName)
3107+ {
3108+ synchronized (_players)
3109+ {
3110+ for (Player player : _players)
3111+ {
3112+ if (player != null && (player.isOnlineInt() != 0) && (player._inEventCTF))
3113+ {
3114+ if (teamName != null && (player._teamNameCTF.equals(teamName)))
3115+ {
3116+
3117+ player.addItem(_eventName + " Event: " + _eventName, _rewardId, _rewardAmount, player, true);
3118+
3119+ NpcHtmlMessage nhm = new NpcHtmlMessage(5);
3120+ StringBuilder replyMSG = new StringBuilder("");
3121+
3122+ replyMSG.append("<html><body>");
3123+ replyMSG.append("<font color=\"FFFF00\">Your team wins the event. Congratulations!!<br>Look in your inventory for the reward.</font>");
3124+ replyMSG.append("</body></html>");
3125+
3126+ nhm.setHtml(replyMSG.toString());
3127+ player.sendPacket(nhm);
3128+
3129+ // Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
3130+ player.sendPacket(ActionFailed.STATIC_PACKET);
3131+
3132+ }
3133+ else if (teamName == null)
3134+ { // TIE
3135+
3136+ int minus_reward = 0;
3137+ if (_topScore != 0)
3138+ minus_reward = _rewardAmount / 2;
3139+ else // nobody took flags
3140+ minus_reward = _rewardAmount / 4;
3141+
3142+ player.addItem(_eventName + " Event: " + _eventName, _rewardId, minus_reward, player, true);
3143+
3144+ NpcHtmlMessage nhm = new NpcHtmlMessage(5);
3145+ StringBuilder replyMSG = new StringBuilder("");
3146+
3147+ replyMSG.append("<html><body>");
3148+ replyMSG.append("<font color=\"FFFF00\">Your team had a tie in the event.</font>");
3149+ replyMSG.append("</body></html>");
3150+
3151+ nhm.setHtml(replyMSG.toString());
3152+ player.sendPacket(nhm);
3153+
3154+ // Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
3155+ player.sendPacket(ActionFailed.STATIC_PACKET);
3156+
3157+ }
3158+ }
3159+ }
3160+ }
3161+ }
3162+
3163+ /**
3164+ * Process top player.
3165+ */
3166+ private static void processTopPlayer()
3167+ {
3168+ // nothing
3169+ }
3170+
3171+ /**
3172+ * Process top team.
3173+ */
3174+ private static void processTopTeam()
3175+ {
3176+ _topTeam = null;
3177+ for (String team : _teams)
3178+ {
3179+ if (teamPointsCount(team) == _topScore && _topScore > 0)
3180+ _topTeam = null;
3181+
3182+ if (teamPointsCount(team) > _topScore)
3183+ {
3184+ _topTeam = team;
3185+ _topScore = teamPointsCount(team);
3186+ }
3187+ }
3188+ }
3189+
3190+ /**
3191+ * Adds the team.
3192+ * @param teamName the team name
3193+ */
3194+ public static void addTeam(String teamName)
3195+ {
3196+ if (is_inProgress())
3197+ {
3198+ if (Config.DEBUG)
3199+ _log.log(Level.WARNING, _eventName + " Engine[addTeam(" + teamName + ")]: checkTeamOk() = false");
3200+ return;
3201+ }
3202+
3203+ if (teamName.equals(" "))
3204+ return;
3205+
3206+ _teams.add(teamName);
3207+ _teamPlayersCount.add(0);
3208+ _teamPointsCount.add(0);
3209+ _teamColors.add(0);
3210+ _teamsX.add(0);
3211+ _teamsY.add(0);
3212+ _teamsZ.add(0);
3213+
3214+ addTeamEventOperations(teamName);
3215+
3216+ }
3217+
3218+ /**
3219+ * Adds the team event operations.
3220+ * @param teamName the team name
3221+ */
3222+ private static void addTeamEventOperations(String teamName)
3223+ {
3224+ addOrSet(_teams.indexOf(teamName), null, false, _FlagNPC, 0, 0, 0);
3225+ }
3226+
3227+ /**
3228+ * Removes the team.
3229+ * @param teamName the team name
3230+ */
3231+ public static void removeTeam(String teamName)
3232+ {
3233+ if (is_inProgress() || _teams.isEmpty())
3234+ {
3235+ if (Config.DEBUG)
3236+ _log.log(Level.WARNING, _eventName + " Engine[removeTeam(" + teamName + ")]: checkTeamOk() = false");
3237+ return;
3238+ }
3239+
3240+ if (teamPlayersCount(teamName) > 0)
3241+ {
3242+ if (Config.DEBUG)
3243+ _log.log(Level.WARNING, _eventName + " Engine[removeTeam(" + teamName + ")]: teamPlayersCount(teamName) > 0");
3244+ return;
3245+ }
3246+
3247+ int index = _teams.indexOf(teamName);
3248+
3249+ if (index == -1)
3250+ return;
3251+
3252+ _teamsZ.remove(index);
3253+ _teamsY.remove(index);
3254+ _teamsX.remove(index);
3255+ _teamColors.remove(index);
3256+ _teamPointsCount.remove(index);
3257+ _teamPlayersCount.remove(index);
3258+ _teams.remove(index);
3259+
3260+ removeTeamEventItems(teamName);
3261+
3262+ }
3263+
3264+ /**
3265+ * Removes the team event items.
3266+ * @param teamName the team name
3267+ */
3268+ private static void removeTeamEventItems(String teamName)
3269+ {
3270+ int index = _teams.indexOf(teamName);
3271+
3272+ _flagSpawns.remove(index);
3273+ _flagsTaken.remove(index);
3274+ _flagIds.remove(index);
3275+ _flagsX.remove(index);
3276+ _flagsY.remove(index);
3277+ _flagsZ.remove(index);
3278+ }
3279+
3280+ /**
3281+ * Sets the team pos.
3282+ * @param teamName the team name
3283+ * @param activeChar the active char
3284+ */
3285+ public static void setTeamPos(String teamName, Player activeChar)
3286+ {
3287+ int index = _teams.indexOf(teamName);
3288+
3289+ if (index == -1)
3290+ return;
3291+
3292+ _teamsX.set(index, activeChar.getX());
3293+ _teamsY.set(index, activeChar.getY());
3294+ _teamsZ.set(index, activeChar.getZ());
3295+ }
3296+
3297+ /**
3298+ * Sets the team pos.
3299+ * @param teamName the team name
3300+ * @param x the x
3301+ * @param y the y
3302+ * @param z the z
3303+ */
3304+ public static void setTeamPos(String teamName, int x, int y, int z)
3305+ {
3306+ int index = _teams.indexOf(teamName);
3307+
3308+ if (index == -1)
3309+ return;
3310+
3311+ _teamsX.set(index, x);
3312+ _teamsY.set(index, y);
3313+ _teamsZ.set(index, z);
3314+ }
3315+
3316+ /**
3317+ * Sets the team color.
3318+ * @param teamName the team name
3319+ * @param color the color
3320+ */
3321+ public static void setTeamColor(String teamName, int color)
3322+ {
3323+ if (is_inProgress())
3324+ return;
3325+
3326+ int index = _teams.indexOf(teamName);
3327+
3328+ if (index == -1)
3329+ return;
3330+
3331+ _teamColors.set(index, color);
3332+ }
3333+
3334+ /**
3335+ * Team players count.
3336+ * @param teamName the team name
3337+ * @return the int
3338+ */
3339+ public static int teamPlayersCount(String teamName)
3340+ {
3341+ int index = _teams.indexOf(teamName);
3342+
3343+ if (index == -1)
3344+ return -1;
3345+
3346+ return _teamPlayersCount.get(index);
3347+ }
3348+
3349+ /**
3350+ * Sets the team players count.
3351+ * @param teamName the team name
3352+ * @param teamPlayersCount the team players count
3353+ */
3354+ public static void setTeamPlayersCount(String teamName, int teamPlayersCount)
3355+ {
3356+ int index = _teams.indexOf(teamName);
3357+
3358+ if (index == -1)
3359+ return;
3360+
3361+ _teamPlayersCount.set(index, teamPlayersCount);
3362+ }
3363+
3364+ /**
3365+ * Check shuffle players.
3366+ * @param eventPlayer the event player
3367+ * @return true, if successful
3368+ */
3369+ public static boolean checkShufflePlayers(Player eventPlayer)
3370+ {
3371+ try
3372+ {
3373+ for (Player player : _playersShuffle)
3374+ {
3375+ if (player == null || player.isOnlineInt() == 0)
3376+ {
3377+ _playersShuffle.remove(player);
3378+ eventPlayer._inEventCTF = false;
3379+ continue;
3380+ }
3381+ else if (player.getObjectId() == eventPlayer.getObjectId())
3382+ {
3383+ eventPlayer._inEventCTF = true;
3384+ eventPlayer._countCTFflags = 0;
3385+ return true;
3386+ }
3387+
3388+ // This 1 is incase player got new objectid after DC or reconnect
3389+ else if (player.getName().equals(eventPlayer.getName()))
3390+ {
3391+ _playersShuffle.remove(player);
3392+ _playersShuffle.add(eventPlayer);
3393+ eventPlayer._inEventCTF = true;
3394+ eventPlayer._countCTFflags = 0;
3395+ return true;
3396+ }
3397+ }
3398+ }
3399+ catch (Exception e)
3400+ {
3401+ e.printStackTrace();
3402+ }
3403+ return false;
3404+ }
3405+
3406+ /**
3407+ * just an announcer to send termination messages.
3408+ */
3409+ public static void sendFinalMessages()
3410+ {
3411+ if (!_started && !_aborted)
3412+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: Thank you For Participating At, " + _eventName + " Event."));
3413+ }
3414+
3415+ /**
3416+ * returns the interval between each event.
3417+ * @return the interval between matches
3418+ */
3419+ public static int getIntervalBetweenMatchs()
3420+ {
3421+ long actualTime = System.currentTimeMillis();
3422+ long totalTime = actualTime + _intervalBetweenMatches;
3423+ long interval = totalTime - actualTime;
3424+ int seconds = (int) (interval / 1000);
3425+
3426+ return seconds / 60;
3427+ }
3428+
3429+ @Override
3430+ public void run()
3431+ {
3432+ _log.info(_eventName + ": Event notification start");
3433+ eventOnceStart();
3434+ }
3435+
3436+ @Override
3437+ public String getEventIdentifier()
3438+ {
3439+ return _eventName;
3440+ }
3441+
3442+ @Override
3443+ public String getEventStartTime()
3444+ {
3445+ return startEventTime;
3446+ }
3447+
3448+ /**
3449+ * Sets the event start time.
3450+ * @param newTime the new event start time
3451+ */
3452+ public void setEventStartTime(String newTime)
3453+ {
3454+ startEventTime = newTime;
3455+ }
3456+
3457+ /**
3458+ * On disconnect.
3459+ * @param player the player
3460+ */
3461+ public static void onDisconnect(Player player)
3462+ {
3463+ if (player._inEventCTF)
3464+ {
3465+ removePlayer(player);
3466+ player.teleToLocation(_npcX, _npcY, _npcZ, 0);
3467+ }
3468+ }
3469+
3470+ /**
3471+ * Team points count.
3472+ * @param teamName the team name
3473+ * @return the int
3474+ */
3475+ public static int teamPointsCount(String teamName)
3476+ {
3477+ int index = _teams.indexOf(teamName);
3478+
3479+ if (index == -1)
3480+ return -1;
3481+
3482+ return _teamPointsCount.get(index);
3483+ }
3484+
3485+ /**
3486+ * Sets the team points count.
3487+ * @param teamName the team name
3488+ * @param teamPointCount the team point count
3489+ */
3490+ public static void setTeamPointsCount(String teamName, int teamPointCount)
3491+ {
3492+ int index = _teams.indexOf(teamName);
3493+
3494+ if (index == -1)
3495+ return;
3496+
3497+ _teamPointsCount.set(index, teamPointCount);
3498+ }
3499+
3500+ /**
3501+ * Gets the _event offset.
3502+ * @return the _eventOffset
3503+ */
3504+ public static int get_eventOffset()
3505+ {
3506+ return _eventOffset;
3507+ }
3508+
3509+ /**
3510+ * Set_event offset.
3511+ * @param _eventOffset the _eventOffset to set
3512+ * @return true, if successful
3513+ */
3514+ public static boolean set_eventOffset(int _eventOffset)
3515+ {
3516+ if (!is_inProgress())
3517+ {
3518+ CTF._eventOffset = _eventOffset;
3519+ return true;
3520+ }
3521+ return false;
3522+ }
3523+
3524+ /**
3525+ * Show flag html.
3526+ * @param eventPlayer the event player
3527+ * @param objectId the object id
3528+ * @param teamName the team name
3529+ */
3530+ public static void showFlagHtml(Player eventPlayer, String objectId, String teamName)
3531+ {
3532+ if (eventPlayer == null)
3533+ return;
3534+
3535+ try
3536+ {
3537+ NpcHtmlMessage adminReply = new NpcHtmlMessage(5);
3538+
3539+ StringBuilder replyMSG = new StringBuilder("<html><head><body><center>");
3540+ replyMSG.append("CTF Flag<br><br>");
3541+ replyMSG.append("<font color=\"00FF00\">" + teamName + "'s Flag</font><br1>");
3542+ if (eventPlayer._teamNameCTF != null && eventPlayer._teamNameCTF.equals(teamName))
3543+ replyMSG.append("<font color=\"LEVEL\">This is your Flag</font><br1>");
3544+ else
3545+ replyMSG.append("<font color=\"LEVEL\">Enemy Flag!</font><br1>");
3546+ if (_started)
3547+ {
3548+ processInFlagRange(eventPlayer);
3549+ }
3550+ else
3551+ replyMSG.append("CTF match is not in progress yet.<br>Wait for a GM to start the event<br>");
3552+ replyMSG.append("</center></body></html>");
3553+ adminReply.setHtml(replyMSG.toString());
3554+ eventPlayer.sendPacket(adminReply);
3555+ }
3556+ catch (Exception e)
3557+ {
3558+ e.printStackTrace();
3559+ _log.info("CTF Engine[showEventHtlm(" + eventPlayer.getName() + ", " + objectId + ")]: exception: " + e.getStackTrace());
3560+ }
3561+ }
3562+
3563+ /**
3564+ * Check restore flags.
3565+ */
3566+ public static void checkRestoreFlags()
3567+ {
3568+ Vector<Integer> teamsTakenFlag = new Vector<>();
3569+ try
3570+ {
3571+ synchronized (_players)
3572+ {
3573+ for (Player player : _players)
3574+ {
3575+ if (player != null)
3576+ {
3577+ if (player.isOnlineInt() == 0 && player._haveFlagCTF)
3578+ {
3579+ // logged off with a flag in his hands
3580+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: " + player.getName() + " logged off with a CTF flag!"));
3581+ player._haveFlagCTF = false;
3582+ if (_teams.indexOf(player._teamNameHaveFlagCTF) >= 0)
3583+ if (_flagsTaken.get(_teams.indexOf(player._teamNameHaveFlagCTF)))
3584+ {
3585+ _flagsTaken.set(_teams.indexOf(player._teamNameHaveFlagCTF), false);
3586+ spawnFlag(player._teamNameHaveFlagCTF);
3587+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: " + player._teamNameHaveFlagCTF + " flag now returned to place."));
3588+ }
3589+ removeFlagFromPlayer(player);
3590+ player._teamNameHaveFlagCTF = null;
3591+ return;
3592+ }
3593+ else if (player._haveFlagCTF)
3594+ teamsTakenFlag.add(_teams.indexOf(player._teamNameHaveFlagCTF));
3595+ }
3596+ }
3597+ }
3598+
3599+ // Go over the list of ALL teams
3600+ for (String team : _teams)
3601+ {
3602+ if (team == null)
3603+ continue;
3604+ int index = _teams.indexOf(team);
3605+ if (!teamsTakenFlag.contains(index))
3606+ {
3607+ if (_flagsTaken.get(index))
3608+ {
3609+ _flagsTaken.set(index, false);
3610+ spawnFlag(team);
3611+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: " + team + " flag returned due to player error."));
3612+ }
3613+ }
3614+ }
3615+ // Check if a player ran away from the event holding a flag:
3616+ synchronized (_players)
3617+ {
3618+ for (Player player : _players)
3619+ {
3620+ if (player != null && player._haveFlagCTF)
3621+ {
3622+ if (isOutsideCTFArea(player))
3623+ {
3624+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: " + player.getName() + " escaped from the event holding a flag!"));
3625+ player._haveFlagCTF = false;
3626+ if (_teams.indexOf(player._teamNameHaveFlagCTF) >= 0)
3627+ if (_flagsTaken.get(_teams.indexOf(player._teamNameHaveFlagCTF)))
3628+ {
3629+ _flagsTaken.set(_teams.indexOf(player._teamNameHaveFlagCTF), false);
3630+ spawnFlag(player._teamNameHaveFlagCTF);
3631+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: " + player._teamNameHaveFlagCTF + " flag now returned to place."));
3632+ }
3633+ removeFlagFromPlayer(player);
3634+ player._teamNameHaveFlagCTF = null;
3635+ player.teleToLocation(_teamsX.get(_teams.indexOf(player._teamNameCTF)), _teamsY.get(_teams.indexOf(player._teamNameCTF)), _teamsZ.get(_teams.indexOf(player._teamNameCTF)), 0);
3636+ player.sendMessage("You have been returned to your team spawn");
3637+ return;
3638+ }
3639+ }
3640+ }
3641+ }
3642+
3643+ }
3644+ catch (Exception e)
3645+ {
3646+ e.printStackTrace();
3647+
3648+ _log.info("CTF.restoreFlags() Error:" + e.toString());
3649+ return;
3650+ }
3651+ }
3652+
3653+ /**
3654+ * Adds the flag to player.
3655+ * @param _player the _player
3656+ */
3657+ public static void addFlagToPlayer(Player _player)
3658+ {
3659+ // Remove items from the player hands (right, left, both)
3660+ // This is NOT a BUG, I don't want them to see the icon they have 8D
3661+ ItemInstance wpn = _player.getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
3662+ if (wpn == null)
3663+ {
3664+ wpn = _player.getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
3665+ if (wpn != null)
3666+ _player.getInventory().unEquipItemInBodySlotAndRecord(Inventory.PAPERDOLL_RHAND);
3667+ }
3668+ else
3669+ {
3670+ _player.getInventory().unEquipItemInBodySlotAndRecord(Inventory.PAPERDOLL_RHAND);
3671+ wpn = _player.getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND);
3672+ if (wpn != null)
3673+ _player.getInventory().unEquipItemInBodySlotAndRecord(Inventory.PAPERDOLL_LHAND);
3674+ }
3675+ // Add the flag in his hands
3676+ _player.getInventory().equipItem(ItemTable.getInstance().createItem("", CTF._FLAG_IN_HAND_ITEM_ID, 1, _player, null));
3677+ _player.broadcastPacket(new SocialAction(_player, 16)); // Amazing glow
3678+ _player._haveFlagCTF = true;
3679+ _player.broadcastUserInfo();
3680+ CreatureSay cs = new CreatureSay(_player.getObjectId(), 15, ":", "You got it! Run back! ::"); // 8D
3681+ _player.sendPacket(cs);
3682+ }
3683+
3684+ /**
3685+ * Removes the flag from player.
3686+ * @param player the player
3687+ */
3688+ public static void removeFlagFromPlayer(Player player)
3689+ {
3690+ ItemInstance wpn = player.getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
3691+ player._haveFlagCTF = false;
3692+ if (wpn != null)
3693+ {
3694+ ItemInstance[] unequiped = player.getInventory().unEquipItemInBodySlotAndRecord(wpn.getItem().getBodyPart());
3695+ player.getInventory().destroyItemByItemId("", CTF._FLAG_IN_HAND_ITEM_ID, 1, player, null);
3696+ InventoryUpdate iu = new InventoryUpdate();
3697+ for (ItemInstance element : unequiped)
3698+ iu.addModifiedItem(element);
3699+ player.sendPacket(iu);
3700+ player.sendPacket(new ItemList(player, true)); // Get your weapon back now ...
3701+ player.abortAttack();
3702+ player.broadcastUserInfo();
3703+ }
3704+ else
3705+ {
3706+ player.getInventory().destroyItemByItemId("", CTF._FLAG_IN_HAND_ITEM_ID, 1, player, null);
3707+ player.sendPacket(new ItemList(player, true)); // Get your weapon back now ...
3708+ player.abortAttack();
3709+ player.broadcastUserInfo();
3710+ }
3711+ }
3712+
3713+ /**
3714+ * Sets the team flag.
3715+ * @param teamName the team name
3716+ * @param activeChar the active char
3717+ */
3718+ public static void setTeamFlag(String teamName, Player activeChar)
3719+ {
3720+ int index = _teams.indexOf(teamName);
3721+
3722+ if (index == -1)
3723+ return;
3724+ addOrSet(_teams.indexOf(teamName), null, false, _FlagNPC, activeChar.getX(), activeChar.getY(), activeChar.getZ());
3725+ }
3726+
3727+ /**
3728+ * Spawn all flags.
3729+ */
3730+ public static void spawnAllFlags()
3731+ {
3732+ while (_flagSpawns.size() < _teams.size())
3733+ _flagSpawns.add(null);
3734+ while (_throneSpawns.size() < _teams.size())
3735+ _throneSpawns.add(null);
3736+ for (String team : _teams)
3737+ {
3738+ int index = _teams.indexOf(team);
3739+ NpcTemplate tmpl = NpcTable.getInstance().getTemplate(_flagIds.get(index));
3740+ NpcTemplate throne = NpcTable.getInstance().getTemplate(32027);
3741+ try
3742+ {
3743+ // Spawn throne
3744+ _throneSpawns.set(index, new L2Spawn(throne));
3745+ _throneSpawns.get(index).setLoc(_flagsX.get(index), _flagsY.get(index), _flagsZ.get(index) - 10, 0);
3746+ _throneSpawns.get(index).setRespawnDelay(1);
3747+ SpawnTable.getInstance().addNewSpawn(_throneSpawns.get(index), false);
3748+ _throneSpawns.get(index).setRespawnState(true);
3749+ _throneSpawns.get(index).doSpawn(false);
3750+ _throneSpawns.get(index).getNpc().getStatus().setCurrentHp(999999999);
3751+ _throneSpawns.get(index).getNpc().decayMe();
3752+ _throneSpawns.get(index).getNpc().spawnMe(_throneSpawns.get(index).getNpc().getX(), _throneSpawns.get(index).getNpc().getY(), _throneSpawns.get(index).getNpc().getZ());
3753+ _throneSpawns.get(index).getNpc().setTitle(team + " Throne");
3754+ _throneSpawns.get(index).getNpc().broadcastPacket(new MagicSkillUse(_throneSpawns.get(index).getNpc(), _throneSpawns.get(index).getNpc(), 1036, 1, 5500, 1));
3755+ _throneSpawns.get(index).getNpc()._isCTF_throneSpawn = true;
3756+ // Spawn flag
3757+ _flagSpawns.set(index, new L2Spawn(tmpl));
3758+ _flagSpawns.get(index).setLoc(_flagsX.get(index), _flagsY.get(index), _flagsZ.get(index), 0);
3759+ _flagSpawns.get(index).setRespawnDelay(1);
3760+ SpawnTable.getInstance().addNewSpawn(_flagSpawns.get(index), false);
3761+ _flagSpawns.get(index).setRespawnState(true);
3762+ _flagSpawns.get(index).doSpawn(false);
3763+ _flagSpawns.get(index).getNpc().getStatus().setCurrentHp(999999999);
3764+ _flagSpawns.get(index).getNpc().setTitle(team + "'s Flag");
3765+ _flagSpawns.get(index).getNpc()._CTF_FlagTeamName = team;
3766+ _flagSpawns.get(index).getNpc().decayMe();
3767+ _flagSpawns.get(index).getNpc().spawnMe(_flagSpawns.get(index).getNpc().getX(), _flagSpawns.get(index).getNpc().getY(), _flagSpawns.get(index).getNpc().getZ());
3768+ _flagSpawns.get(index).getNpc()._isCTF_Flag = true;
3769+ calculateOutSideOfCTF(); // Sets event boundaries so players don't run with the flag.
3770+ }
3771+ catch (Exception e)
3772+ {
3773+ _log.info("CTF Engine[spawnAllFlags()]: exception: ");
3774+ e.printStackTrace();
3775+ }
3776+ }
3777+ }
3778+
3779+ /**
3780+ * Unspawn all flags.
3781+ */
3782+ public static void unspawnAllFlags()
3783+ {
3784+ try
3785+ {
3786+ if (_throneSpawns == null || _flagSpawns == null || _teams == null)
3787+ return;
3788+ for (String team : _teams)
3789+ {
3790+ int index = _teams.indexOf(team);
3791+ if (_throneSpawns.get(index) != null)
3792+ {
3793+ _throneSpawns.get(index).getNpc().deleteMe();
3794+ _throneSpawns.get(index).setRespawnState(false);
3795+ SpawnTable.getInstance().deleteSpawn(_throneSpawns.get(index), true);
3796+ }
3797+ if (_flagSpawns.get(index) != null)
3798+ {
3799+ _flagSpawns.get(index).getNpc().deleteMe();
3800+ _flagSpawns.get(index).setRespawnState(false);
3801+ SpawnTable.getInstance().deleteSpawn(_flagSpawns.get(index), true);
3802+ }
3803+ }
3804+ _throneSpawns.removeAllElements();
3805+ }
3806+ catch (Exception e)
3807+ {
3808+ _log.info("CTF Engine[unspawnAllFlags()]: exception: ");
3809+ e.printStackTrace();
3810+ }
3811+ }
3812+
3813+ /**
3814+ * Unspawn flag.
3815+ * @param teamName the team name
3816+ */
3817+ private static void unspawnFlag(String teamName)
3818+ {
3819+ int index = _teams.indexOf(teamName);
3820+
3821+ _flagSpawns.get(index).getNpc().deleteMe();
3822+ _flagSpawns.get(index).setRespawnState(false);
3823+ SpawnTable.getInstance().deleteSpawn(_flagSpawns.get(index), true);
3824+ }
3825+
3826+ /**
3827+ * Spawn flag.
3828+ * @param teamName the team name
3829+ */
3830+ public static void spawnFlag(String teamName)
3831+ {
3832+ int index = _teams.indexOf(teamName);
3833+ NpcTemplate tmpl = NpcTable.getInstance().getTemplate(_flagIds.get(index));
3834+
3835+ try
3836+ {
3837+ _flagSpawns.set(index, new L2Spawn(tmpl));
3838+
3839+ _flagSpawns.get(index).setLoc(_flagsX.get(index), _flagsY.get(index), _flagsZ.get(index), 0);
3840+ _flagSpawns.get(index).setRespawnDelay(1);
3841+
3842+ SpawnTable.getInstance().addNewSpawn(_flagSpawns.get(index), false);
3843+
3844+ _flagSpawns.get(index).setRespawnState(true);
3845+ _flagSpawns.get(index).doSpawn(false);
3846+ _flagSpawns.get(index).getNpc().getStatus().setCurrentHp(999999999);
3847+ _flagSpawns.get(index).getNpc().setTitle(teamName + "'s Flag");
3848+ _flagSpawns.get(index).getNpc()._CTF_FlagTeamName = teamName;
3849+ _flagSpawns.get(index).getNpc()._isCTF_Flag = true;
3850+ _flagSpawns.get(index).getNpc().decayMe();
3851+ _flagSpawns.get(index).getNpc().spawnMe(_flagSpawns.get(index).getNpc().getX(), _flagSpawns.get(index).getNpc().getY(), _flagSpawns.get(index).getNpc().getZ());
3852+ }
3853+ catch (Exception e)
3854+ {
3855+ _log.info("CTF Engine[spawnFlag(" + teamName + ")]: exception: ");
3856+ e.printStackTrace();
3857+ }
3858+ }
3859+
3860+ /**
3861+ * In range of flag.
3862+ * @param _player the _player
3863+ * @param flagIndex the flag index
3864+ * @param offset the offset
3865+ * @return true, if successful
3866+ */
3867+ public static boolean InRangeOfFlag(Player _player, int flagIndex, int offset)
3868+ {
3869+ if (_player.getX() > CTF._flagsX.get(flagIndex) - offset && _player.getX() < CTF._flagsX.get(flagIndex) + offset && _player.getY() > CTF._flagsY.get(flagIndex) - offset && _player.getY() < CTF._flagsY.get(flagIndex) + offset && _player.getZ() > CTF._flagsZ.get(flagIndex) - offset && _player.getZ() < CTF._flagsZ.get(flagIndex) + offset)
3870+ return true;
3871+ return false;
3872+ }
3873+
3874+ /**
3875+ * Process in flag range.
3876+ * @param _player the _player
3877+ */
3878+ public static void processInFlagRange(Player _player)
3879+ {
3880+ try
3881+ {
3882+ checkRestoreFlags();
3883+ for (String team : _teams)
3884+ {
3885+ if (team.equals(_player._teamNameCTF))
3886+ {
3887+ int indexOwn = _teams.indexOf(_player._teamNameCTF);
3888+
3889+ // If player is near his team flag holding the enemy flag
3890+ if (InRangeOfFlag(_player, indexOwn, 100) && !_flagsTaken.get(indexOwn) && _player._haveFlagCTF)
3891+ {
3892+ int indexEnemy = _teams.indexOf(_player._teamNameHaveFlagCTF);
3893+ // Return enemy flag to place
3894+ _flagsTaken.set(indexEnemy, false);
3895+ spawnFlag(_player._teamNameHaveFlagCTF);
3896+ // Remove the flag from this player
3897+ _player.broadcastPacket(new SocialAction(_player, 16)); // Amazing glow
3898+ _player.broadcastUserInfo();
3899+ _player.broadcastPacket(new SocialAction(_player, 3)); // Victory
3900+ _player.broadcastUserInfo();
3901+ removeFlagFromPlayer(_player);
3902+ _teamPointsCount.set(indexOwn, teamPointsCount(team) + 1);
3903+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: " + _player.getName() + " scores for " + _player._teamNameCTF + "."));
3904+ }
3905+ }
3906+ else
3907+ {
3908+ int indexEnemy = _teams.indexOf(team);
3909+ // If the player is near a enemy flag
3910+ if (InRangeOfFlag(_player, indexEnemy, 100) && !_flagsTaken.get(indexEnemy) && !_player._haveFlagCTF && !_player.isDead())
3911+ {
3912+ _flagsTaken.set(indexEnemy, true);
3913+ unspawnFlag(team);
3914+ _player._teamNameHaveFlagCTF = team;
3915+ addFlagToPlayer(_player);
3916+ _player.broadcastUserInfo();
3917+ _player._haveFlagCTF = true;
3918+ Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, _eventName, "CTF: " + team + " flag taken by " + _player.getName() + "..."));
3919+ pointTeamTo(_player, team);
3920+ break;
3921+ }
3922+ }
3923+ }
3924+ }
3925+ catch (Exception e)
3926+ {
3927+ e.printStackTrace();
3928+ return;
3929+ }
3930+ }
3931+
3932+ /**
3933+ * Point team to.
3934+ * @param hasFlag the has flag
3935+ * @param ourFlag the our flag
3936+ */
3937+ public static void pointTeamTo(Player hasFlag, String ourFlag)
3938+ {
3939+ try
3940+ {
3941+ synchronized (_players)
3942+ {
3943+ for (Player player : _players)
3944+ {
3945+ if (player != null && player.isOnlineInt() != 0)
3946+ {
3947+ if (player._teamNameCTF.equals(ourFlag))
3948+ {
3949+ player.sendMessage(hasFlag.getName() + " took your flag!");
3950+ if (player._haveFlagCTF)
3951+ {
3952+ player.sendMessage("You can not return the flag to headquarters, until your flag is returned to it's place.");
3953+ player.sendPacket(new RadarControl(1, 1, player.getX(), player.getY(), player.getZ()));
3954+ }
3955+ else
3956+ {
3957+ player.sendPacket(new RadarControl(0, 1, hasFlag.getX(), hasFlag.getY(), hasFlag.getZ()));
3958+ L2Radar rdr = new L2Radar(player);
3959+ L2Radar.RadarOnPlayer radar = rdr.new RadarOnPlayer(hasFlag, player);
3960+ ThreadPool.schedule(radar, 10000 + Rnd.get(30000));
3961+ }
3962+ }
3963+ }
3964+ }
3965+ }
3966+ }
3967+ catch (Exception e)
3968+ {
3969+ e.printStackTrace();
3970+ return;
3971+ }
3972+ }
3973+
3974+ /**
3975+ * Adds the or set.
3976+ * @param listSize the list size
3977+ * @param flagSpawn the flag spawn
3978+ * @param flagsTaken the flags taken
3979+ * @param flagId the flag id
3980+ * @param flagX the flag x
3981+ * @param flagY the flag y
3982+ * @param flagZ the flag z
3983+ */
3984+ private static void addOrSet(int listSize, L2Spawn flagSpawn, boolean flagsTaken, int flagId, int flagX, int flagY, int flagZ)
3985+ {
3986+ while (_flagsX.size() <= listSize)
3987+ {
3988+ _flagSpawns.add(null);
3989+ _flagsTaken.add(false);
3990+ _flagIds.add(_FlagNPC);
3991+ _flagsX.add(0);
3992+ _flagsY.add(0);
3993+ _flagsZ.add(0);
3994+ }
3995+ _flagSpawns.set(listSize, flagSpawn);
3996+ _flagsTaken.set(listSize, flagsTaken);
3997+ _flagIds.set(listSize, flagId);
3998+ _flagsX.set(listSize, flagX);
3999+ _flagsY.set(listSize, flagY);
4000+ _flagsZ.set(listSize, flagZ);
4001+ }
4002+
4003+ /**
4004+ * Used to calculate the event CTF area, so that players don't run off with the flag. Essential, since a player may take the flag just so other teams can't score points. This function is Only called upon ONE time on BEGINING OF EACH EVENT right after we spawn the flags.
4005+ */
4006+ private static void calculateOutSideOfCTF()
4007+ {
4008+ if (_teams == null || _flagSpawns == null || _teamsX == null || _teamsY == null || _teamsZ == null)
4009+ return;
4010+ int division = _teams.size() * 2, pos = 0;
4011+ int[] locX = new int[division], locY = new int[division], locZ = new int[division];
4012+ // Get all coordinates inorder to create a polygon:
4013+ for (L2Spawn flag : _flagSpawns)
4014+ {
4015+ if (flag == null)
4016+ continue;
4017+
4018+ locX[pos] = flag.getLocX();
4019+ locY[pos] = flag.getLocY();
4020+ locZ[pos] = flag.getLocZ();
4021+ pos++;
4022+ if (pos > division / 2)
4023+ break;
4024+ }
4025+ for (int x = 0; x < _teams.size(); x++)
4026+ {
4027+ locX[pos] = _teamsX.get(x);
4028+ locY[pos] = _teamsY.get(x);
4029+ locZ[pos] = _teamsZ.get(x);
4030+ pos++;
4031+ if (pos > division)
4032+ break;
4033+ }
4034+ // Find the polygon center, note that it's not the mathematical center of the polygon,
4035+ // Rather than a point which centers all coordinates:
4036+ int centerX = 0, centerY = 0, centerZ = 0;
4037+ for (int x = 0; x < pos; x++)
4038+ {
4039+ centerX += (locX[x] / division);
4040+ centerY += (locY[x] / division);
4041+ centerZ += (locZ[x] / division);
4042+ }
4043+ // Now let's find the furthest distance from the "center" to the egg shaped sphere
4044+ // Surrounding the polygon, size x1.5 (for maximum logical area to wander...):
4045+ int maxX = 0, maxY = 0, maxZ = 0;
4046+ for (int x = 0; x < pos; x++)
4047+ {
4048+ if (maxX < 2 * Math.abs(centerX - locX[x]))
4049+ maxX = (2 * Math.abs(centerX - locX[x]));
4050+ if (maxY < 2 * Math.abs(centerY - locY[x]))
4051+ maxY = (2 * Math.abs(centerY - locY[x]));
4052+ if (maxZ < 2 * Math.abs(centerZ - locZ[x]))
4053+ maxZ = (2 * Math.abs(centerZ - locZ[x]));
4054+ }
4055+
4056+ // CenterX,centerY,centerZ are the coordinates of the "event center".
4057+ // So let's save those coordinates to check on the players:
4058+ _eventCenterX = centerX;
4059+ _eventCenterY = centerY;
4060+ _eventCenterZ = centerZ;
4061+ _eventOffset = maxX;
4062+ if (_eventOffset < maxY)
4063+ _eventOffset = maxY;
4064+ if (_eventOffset < maxZ)
4065+ _eventOffset = maxZ;
4066+ }
4067+
4068+ /**
4069+ * Checks if is outside ctf area.
4070+ * @param _player the _player
4071+ * @return true, if is outside ctf area
4072+ */
4073+ public static boolean isOutsideCTFArea(Player _player)
4074+ {
4075+ if (_player == null || _player.isOnlineInt() == 0)
4076+ return true;
4077+ if (!(_player.getX() > _eventCenterX - _eventOffset && _player.getX() < _eventCenterX + _eventOffset && _player.getY() > _eventCenterY - _eventOffset && _player.getY() < _eventCenterY + _eventOffset && _player.getZ() > _eventCenterZ - _eventOffset && _player.getZ() < _eventCenterZ + _eventOffset))
4078+ return true;
4079+ return false;
4080+ }
4081+}
4082\ No newline at end of file
4083Index: java/net/sf/l2j/gameserver/network/clientpackets/Action.java
4084===================================================================
4085--- java/net/sf/l2j/gameserver/network/clientpackets/Action.java (revision 447)
4086+++ java/net/sf/l2j/gameserver/network/clientpackets/Action.java (working copy)
4087@@ -1,5 +1,6 @@
4088 package net.sf.l2j.gameserver.network.clientpackets;
4089
4090+import net.sf.l2j.gameserver.event.CTF;
4091 import net.sf.l2j.gameserver.event.L2Event;
4092 import net.sf.l2j.gameserver.event.TvT;
4093 import net.sf.l2j.gameserver.model.World;
4094@@ -52,17 +53,17 @@
4095 return;
4096 }
4097
4098- // Block action during Event start
4099- if (L2Event.active && activeChar.eventSitForced)
4100- {
4101- getClient().sendPacket(ActionFailed.STATIC_PACKET);
4102- return;
4103- }
4104- else if ((TvT.is_sitForced() && activeChar._inEventTvT))
4105- {
4106- getClient().sendPacket(ActionFailed.STATIC_PACKET);
4107- return;
4108- }
4109+ // Block action during Event start
4110+ if (L2Event.active && activeChar.eventSitForced)
4111+ {
4112+ getClient().sendPacket(ActionFailed.STATIC_PACKET);
4113+ return;
4114+ }
4115+ else if ((TvT.is_sitForced() && activeChar._inEventTvT) || (CTF.is_sitForced() && activeChar._inEventCTF))
4116+ {
4117+ getClient().sendPacket(ActionFailed.STATIC_PACKET);
4118+ return;
4119+ }
4120
4121 switch (_actionId)
4122 {
4123Index: java/net/sf/l2j/gameserver/model/actor/instance/VillageMaster.java
4124===================================================================
4125--- java/net/sf/l2j/gameserver/model/actor/instance/VillageMaster.java (revision 447)
4126+++ java/net/sf/l2j/gameserver/model/actor/instance/VillageMaster.java (working copy)
4127@@ -160,6 +160,13 @@
4128 return;
4129 }
4130
4131+ // You can't add Subclass when you are registered in Events (TVT, CTF)
4132+ if (player._inEventTvT || player._inEventCTF)
4133+ {
4134+ player.sendMessage("You can't add a subclass while in an event.");
4135+ return;
4136+ }
4137+
4138 // Affecting subclasses (add/del/change) if registered in Olympiads makes you ineligible to compete.
4139 if (OlympiadManager.getInstance().isRegisteredInComp(player))
4140 OlympiadManager.getInstance().unRegisterNoble(player);
4141@@ -203,6 +210,13 @@
4142 return;
4143 }
4144
4145+ // You can't add Subclass when you are registered in Events (TVT, CTF)
4146+ if (player._inEventTvT || player._inEventCTF)
4147+ {
4148+ player.sendMessage("You can't add a subclass while in an event.");
4149+ return;
4150+ }
4151+
4152 // Subclasses may not be added while you are over your weight limit.
4153 if (player.getInventoryLimit() * 0.8 <= player.getInventory().getSize() || player.getWeightPenalty() > 0)
4154 {
4155@@ -240,6 +254,13 @@
4156 return;
4157 }
4158
4159+ // You can't add Subclass when you are registered in Events (TVT, CTF)
4160+ if (player._inEventTvT || player._inEventCTF)
4161+ {
4162+ player.sendMessage("You can't add a subclass while in an event.");
4163+ return;
4164+ }
4165+
4166 // Subclasses may not be changed while a you are over your weight limit.
4167 if (player.getInventoryLimit() * 0.8 <= player.getInventory().getSize() || player.getWeightPenalty() > 0)
4168 {
4169@@ -280,6 +301,13 @@
4170 break;
4171 }
4172
4173+ // You can't add Subclass when you are registered in Events (TVT, CTF)
4174+ if (player._inEventTvT || player._inEventCTF)
4175+ {
4176+ player.sendMessage("You can't add a subclass while in an event.");
4177+ return;
4178+ }
4179+
4180 // custom value
4181 if (player.getSubClasses().size() > 3)
4182 {
4183@@ -320,6 +348,13 @@
4184 if (!FloodProtectors.performAction(player.getClient(), Action.SUBCLASS))
4185 return;
4186
4187+ // You can't add Subclass when you are registered in Events (TVT, CTF)
4188+ if (player._inEventTvT || player._inEventCTF)
4189+ {
4190+ player.sendMessage("You can't add a subclass while in an event.");
4191+ return;
4192+ }
4193+
4194 boolean allowAddition = true;
4195
4196 if (player.getSubClasses().size() >= 3)
4197@@ -372,6 +407,13 @@
4198 if (!FloodProtectors.performAction(player.getClient(), Action.SUBCLASS))
4199 return;
4200
4201+ // You can't add Subclass when you are registered in Events (TVT, CTF)
4202+ if (player._inEventTvT || player._inEventCTF)
4203+ {
4204+ player.sendMessage("You can't add a subclass while in an event.");
4205+ return;
4206+ }
4207+
4208 if (player.getClassIndex() == paramOne)
4209 {
4210 html.setFile("data/html/villagemaster/SubClass_Current.htm");
4211@@ -417,6 +459,13 @@
4212 return;
4213 }
4214
4215+ // You can't add Subclass when you are registered in Events (TVT, CTF)
4216+ if (player._inEventTvT || player._inEventCTF)
4217+ {
4218+ player.sendMessage("You can't add a subclass while in an event.");
4219+ return;
4220+ }
4221+
4222 sb = new StringBuilder(300);
4223 for (ClassId subClass : subsAvailable)
4224 StringUtil.append(sb, "<a action=\"bypass -h npc_%objectId%_Subclass 7 ", paramOne, " ", subClass.getId(), "\" msg=\"1445;", "\">", subClass, "</a><br>");
4225@@ -445,6 +494,13 @@
4226 if (!FloodProtectors.performAction(player.getClient(), Action.SUBCLASS))
4227 return;
4228
4229+ // You can't add Subclass when you are registered in Events (TVT, CTF)
4230+ if (player._inEventTvT || player._inEventCTF)
4231+ {
4232+ player.sendMessage("You can't add a subclass while in an event.");
4233+ return;
4234+ }
4235+
4236 if (!isValidNewSubClass(player, paramTwo))
4237 return;
4238
4239Index: java/net/sf/l2j/gameserver/event/EventManager.java
4240===================================================================
4241--- java/net/sf/l2j/gameserver/event/EventManager.java (revision 447)
4242+++ java/net/sf/l2j/gameserver/event/EventManager.java (working copy)
4243@@ -16,8 +16,8 @@
4244 *
4245 * http://www.gnu.org/copyleft/gpl.html
4246 */
4247- package net.sf.l2j.gameserver.event;
4248-
4249+package net.sf.l2j.gameserver.event;
4250+
4251 import java.io.File;
4252 import java.io.FileInputStream;
4253 import java.io.IOException;
4254@@ -40,6 +40,9 @@
4255
4256 public static boolean TVT_EVENT_ENABLED;
4257 public static ArrayList<String> TVT_TIMES_LIST;
4258+
4259+ public static boolean CTF_EVENT_ENABLED;
4260+ public static ArrayList<String> CTF_TIMES_LIST;
4261
4262 private static EventManager instance = null;
4263
4264@@ -69,15 +72,21 @@
4265 // ============================================================
4266
4267 TVT_EVENT_ENABLED = Boolean.parseBoolean(eventSettings.getProperty("TVTEventEnabled", "false"));
4268- TVT_TIMES_LIST = new ArrayList<>();
4269-
4270+ TVT_TIMES_LIST = new ArrayList<>();
4271 String[] propertySplit;
4272- propertySplit = eventSettings.getProperty("TVTStartTime", "").split(";");
4273-
4274+ propertySplit = eventSettings.getProperty("TVTStartTime", "").split(";");
4275 for (String time : propertySplit)
4276 {
4277 TVT_TIMES_LIST.add(time);
4278 }
4279+
4280+ CTF_EVENT_ENABLED = Boolean.parseBoolean(eventSettings.getProperty("CTFEventEnabled", "false"));
4281+ CTF_TIMES_LIST = new ArrayList<>();
4282+ propertySplit = eventSettings.getProperty("CTFStartTime", "").split(";");
4283+ for (String time : propertySplit)
4284+ {
4285+ CTF_TIMES_LIST.add(time);
4286+ }
4287 }
4288 catch (Exception e)
4289 {
4290@@ -102,9 +111,10 @@
4291 public void startEventRegistration()
4292 {
4293 if (TVT_EVENT_ENABLED)
4294- {
4295 registerTvT();
4296- }
4297+
4298+ if (CTF_EVENT_ENABLED)
4299+ registerCTF();
4300 }
4301
4302 private static void registerTvT()
4303@@ -125,4 +135,22 @@
4304 EventsGlobalTask.getInstance().registerNewEventTask(newInstance);
4305 }
4306 }
4307+
4308+ private static void registerCTF()
4309+ {
4310+ CTF.loadData();
4311+ if (!CTF.checkStartJoinOk())
4312+ _log.log(Level.SEVERE, "registerCTF: CTF Event is not setted Properly");
4313+
4314+ // clear all tvt
4315+ EventsGlobalTask.getInstance().clearEventTasksByEventName(CTF.get_eventName());
4316+
4317+ for (String time : CTF_TIMES_LIST)
4318+ {
4319+ CTF newInstance = CTF.getNewInstance();
4320+ // System.out.println("registerCTF: reg.time: "+time);
4321+ newInstance.setEventStartTime(time);
4322+ EventsGlobalTask.getInstance().registerNewEventTask(newInstance);
4323+ }
4324+ }
4325 }
4326\ No newline at end of file
4327Index: java/net/sf/l2j/gameserver/handler/skillhandlers/SummonFriend.java
4328===================================================================
4329--- java/net/sf/l2j/gameserver/handler/skillhandlers/SummonFriend.java (revision 447)
4330+++ java/net/sf/l2j/gameserver/handler/skillhandlers/SummonFriend.java (working copy)
4331@@ -2,6 +2,7 @@
4332
4333 import net.sf.l2j.commons.math.MathUtil;
4334
4335+import net.sf.l2j.gameserver.event.CTF;
4336 import net.sf.l2j.gameserver.event.TvT;
4337 import net.sf.l2j.gameserver.handler.ISkillHandler;
4338 import net.sf.l2j.gameserver.model.L2Skill;
4339@@ -37,7 +38,7 @@
4340
4341 if (player._inEvent)
4342 return;
4343- if (player._inEventTvT && TvT.is_started())
4344+ if (player._inEventTvT && TvT.is_started() || player._inEventCTF && CTF.is_started())
4345 return;
4346
4347 for (WorldObject obj : targets)
4348@@ -57,7 +58,7 @@
4349
4350 if (target._inEvent)
4351 return;
4352- if (target._inEventTvT)
4353+ if (target._inEventTvT && TvT.is_started() || target._inEventCTF && CTF.is_started())
4354 return;
4355
4356 // Check target distance.
4357Index: java/net/sf/l2j/gameserver/model/L2Skill.java
4358===================================================================
4359--- java/net/sf/l2j/gameserver/model/L2Skill.java (revision 447)
4360+++ java/net/sf/l2j/gameserver/model/L2Skill.java (working copy)
4361@@ -12,6 +12,7 @@
4362 import net.sf.l2j.Config;
4363 import net.sf.l2j.gameserver.data.SkillTable;
4364 import net.sf.l2j.gameserver.data.SkillTreeTable;
4365+import net.sf.l2j.gameserver.event.CTF;
4366 import net.sf.l2j.gameserver.event.TvT;
4367 import net.sf.l2j.gameserver.geoengine.GeoEngine;
4368 import net.sf.l2j.gameserver.instancemanager.ZoneManager;
4369@@ -246,6 +247,8 @@
4370
4371 private L2ExtractableSkill _extractableItems = null;
4372
4373+ public boolean _inEventTvT = false;
4374+
4375 protected L2Skill(StatsSet set)
4376 {
4377 _id = set.getInteger("skill_id");
4378@@ -1516,6 +1519,14 @@
4379 if (!checkForAreaOffensiveSkills(activeChar, obj, this, srcInArena))
4380 continue;
4381
4382+ if (((TvT.is_started() && !Config.TVT_ALLOW_INTERFERENCE) || (CTF.is_started() && !Config.CTF_ALLOW_INTERFERENCE) && !obj.isGM()))
4383+ {
4384+ if ((obj._inEventTvT && !obj._inEventTvT) || (!obj._inEventTvT && obj._inEventTvT))
4385+ continue;
4386+ if ((obj._inEventCTF && !obj._inEventCTF) || (!obj._inEventCTF && obj._inEventCTF))
4387+ continue;
4388+ }
4389+
4390 targetList.add(obj);
4391 }
4392 }
4393@@ -1565,10 +1576,12 @@
4394 if (addSummon(activeChar, partyMember, radius, false))
4395 targetList.add(partyMember.getPet());
4396
4397- if (((TvT.is_started() && !Config.TVT_ALLOW_INTERFERENCE) && !player.isGM()))
4398+ if (((TvT.is_started() && !Config.TVT_ALLOW_INTERFERENCE) || (CTF.is_started() && !Config.CTF_ALLOW_INTERFERENCE) && !player.isGM()))
4399 {
4400 if ((partyMember._inEventTvT && !player._inEventTvT) || (!partyMember._inEventTvT && player._inEventTvT))
4401 continue;
4402+ if ((partyMember._inEventCTF && !player._inEventCTF) || (!partyMember._inEventCTF && player._inEventCTF))
4403+ continue;
4404 }
4405 }
4406 }
4407@@ -1668,6 +1681,14 @@
4408 continue;
4409 }
4410
4411+ if (((TvT.is_started() && !Config.TVT_ALLOW_INTERFERENCE) || (CTF.is_started() && !Config.CTF_ALLOW_INTERFERENCE) && !player.isGM()))
4412+ {
4413+ if ((player._inEventTvT && !obj._inEventTvT) || (!player._inEventTvT && obj._inEventTvT))
4414+ continue;
4415+ if ((player._inEventCTF && !obj._inEventCTF) || (!player._inEventCTF && obj._inEventCTF))
4416+ continue;
4417+ }
4418+
4419 if (!player.checkPvpSkill(obj, this))
4420 continue;
4421
4422@@ -1773,6 +1794,14 @@
4423 continue;
4424 }
4425
4426+ if (((TvT.is_started() && !Config.TVT_ALLOW_INTERFERENCE) || (CTF.is_started() && !Config.CTF_ALLOW_INTERFERENCE) && !player.isGM()))
4427+ {
4428+ if ((player._inEventTvT && !obj._inEventTvT) || (!player._inEventTvT && obj._inEventTvT))
4429+ continue;
4430+ if ((player._inEventCTF && !obj._inEventCTF) || (!player._inEventCTF && obj._inEventCTF))
4431+ continue;
4432+ }
4433+
4434 if (!player.checkPvpSkill(obj, this))
4435 continue;
4436
4437@@ -2086,6 +2115,14 @@
4438 return false;
4439 }
4440
4441+ if (((TvT.is_started() && !Config.TVT_ALLOW_INTERFERENCE) || (CTF.is_started() && !Config.CTF_ALLOW_INTERFERENCE) && !player.isGM()))
4442+ {
4443+ if ((player._inEventTvT && !targetPlayer._inEventTvT) || (!player._inEventTvT && targetPlayer._inEventTvT))
4444+ return false;
4445+ if ((player._inEventCTF && !targetPlayer._inEventCTF) || (!player._inEventCTF && targetPlayer._inEventCTF))
4446+ return false;
4447+ }
4448+
4449 if (!sourceInArena && !(targetPlayer.isInsideZone(ZoneId.PVP) && !targetPlayer.isInsideZone(ZoneId.SIEGE)))
4450 {
4451 if (player.getAllyId() != 0 && player.getAllyId() == targetPlayer.getAllyId())
4452Index: java/net/sf/l2j/gameserver/handler/voicedcommandhandlers/CTFCmd.java
4453===================================================================
4454--- java/net/sf/l2j/gameserver/handler/voicedcommandhandlers/CTFCmd.java (revision 0)
4455+++ java/net/sf/l2j/gameserver/handler/voicedcommandhandlers/CTFCmd.java (working copy)
4456@@ -0,0 +1,184 @@
4457+/*
4458+ * This program is free software: you can redistribute it and/or modify it under
4459+ * the terms of the GNU General Public License as published by the Free Software
4460+ * Foundation, either version 3 of the License, or (at your option) any later
4461+ * version.
4462+ *
4463+ * This program is distributed in the hope that it will be useful, but WITHOUT
4464+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
4465+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
4466+ * details.
4467+ *
4468+ * You should have received a copy of the GNU General Public License along with
4469+ * this program. If not, see <http://www.gnu.org/licenses/>.
4470+ */
4471+package net.sf.l2j.gameserver.handler.voicedcommandhandlers;
4472+
4473+import net.sf.l2j.Config;
4474+import net.sf.l2j.gameserver.data.ItemTable;
4475+import net.sf.l2j.gameserver.event.CTF;
4476+import net.sf.l2j.gameserver.handler.IVoicedCommandHandler;
4477+import net.sf.l2j.gameserver.model.actor.instance.Player;
4478+import net.sf.l2j.gameserver.model.base.ClassId;
4479+
4480+public class CTFCmd implements IVoicedCommandHandler
4481+{
4482+ private static final String[] VOICED_COMMANDS =
4483+ {
4484+ "ctfjoin",
4485+ "ctfleave",
4486+ "ctfinfo"
4487+ };
4488+
4489+ @Override
4490+ public boolean useVoicedCommand(String command, Player activeChar, String target)
4491+ {
4492+ if (command.startsWith("ctfjoin"))
4493+ {
4494+ JoinCTF(activeChar);
4495+ }
4496+ else if (command.startsWith("ctfleave"))
4497+ {
4498+ LeaveCTF(activeChar);
4499+ }
4500+
4501+ else if (command.startsWith("ctfinfo"))
4502+ {
4503+ CTFinfo(activeChar);
4504+ }
4505+
4506+ return true;
4507+ }
4508+
4509+ @Override
4510+ public String[] getVoicedCommandList()
4511+ {
4512+ return VOICED_COMMANDS;
4513+ }
4514+
4515+ public boolean JoinCTF(Player activeChar)
4516+ {
4517+ if (activeChar == null)
4518+ {
4519+ return false;
4520+ }
4521+
4522+ if (!Config.CTF_ALLOW_HEALER_CLASSES && (activeChar.getClassId() == ClassId.BISHOP || activeChar.getClassId() == ClassId.CARDINAL || activeChar.getClassId() == ClassId.ELVEN_ORACLE || activeChar.getClassId() == ClassId.ELVEN_ELDER || activeChar.getClassId() == ClassId.SHILLIEN_ORACLE || activeChar.getClassId() == ClassId.SHILLIEN_ELDER))
4523+ {
4524+ activeChar.sendMessage("You are not allowed to participate to the event with Healer Class.");
4525+ return false;
4526+ }
4527+
4528+ if (!CTF.is_joining())
4529+ {
4530+ activeChar.sendMessage("There is no CTF Event in progress.");
4531+ return false;
4532+ }
4533+ else if (CTF.is_joining() && activeChar._inEventCTF)
4534+ {
4535+ activeChar.sendMessage("You are already registered.");
4536+ return false;
4537+ }
4538+ else if (activeChar.isInOlympiadMode())
4539+ {
4540+ activeChar.sendMessage("You are not allowed to participate to the event because you are in Olympiad.");
4541+ return false;
4542+ }
4543+ else if (activeChar.getInventoryLimit() * 0.8 <= activeChar.getInventory().getSize())
4544+ {
4545+ activeChar.sendMessage("You are not allowed to participate to the event because your inventory is 80% full.");
4546+ return false;
4547+ }
4548+ else if (activeChar.getLevel() < CTF.get_minlvl())
4549+ {
4550+ activeChar.sendMessage("You are not allowed to participate to the event because your level is too low.");
4551+ return false;
4552+ }
4553+ else if (activeChar.getLevel() > CTF.get_maxlvl())
4554+ {
4555+ activeChar.sendMessage("You are not allowed to participate to the event because your level is too high.");
4556+ return false;
4557+ }
4558+ else if (activeChar.getKarma() > 0)
4559+ {
4560+ activeChar.sendMessage("You are not allowed to participate to the event because you have Karma.");
4561+ return false;
4562+ }
4563+ else if (CTF.is_teleport() || CTF.is_started())
4564+ {
4565+ activeChar.sendMessage("CTF Event registration period is over. You can't register now.");
4566+ return false;
4567+ }
4568+ else
4569+ {
4570+ CTF.addPlayer(activeChar, "");
4571+ return true;
4572+ }
4573+ }
4574+
4575+ public boolean LeaveCTF(Player activeChar)
4576+ {
4577+ if (activeChar == null)
4578+ {
4579+ return false;
4580+ }
4581+
4582+ if (!CTF.is_joining())
4583+ {
4584+ activeChar.sendMessage("There is no CTF Event in progress.");
4585+ return false;
4586+ }
4587+ else if ((CTF.is_teleport() || CTF.is_started()) && activeChar._inEventCTF)
4588+ {
4589+ activeChar.sendMessage("You can not leave now because CTF event has started.");
4590+ return false;
4591+ }
4592+ else if (CTF.is_joining() && !activeChar._inEventCTF)
4593+ {
4594+ activeChar.sendMessage("You aren't registered in the CTF Event.");
4595+ return false;
4596+ }
4597+ else
4598+ {
4599+ CTF.removePlayer(activeChar);
4600+ return true;
4601+ }
4602+ }
4603+
4604+ public boolean CTFinfo(Player activeChar)
4605+ {
4606+ if (activeChar == null)
4607+ {
4608+ return false;
4609+ }
4610+
4611+ if (!CTF.is_joining())
4612+ {
4613+ activeChar.sendMessage("There is no CTF Event in progress.");
4614+ return false;
4615+ }
4616+ else if (CTF.is_teleport() || CTF.is_started())
4617+ {
4618+ activeChar.sendMessage("I can't provide you this info. Command available only in joining period.");
4619+ return false;
4620+ }
4621+ else
4622+ {
4623+ if (CTF._playersShuffle.size() == 1)
4624+ {
4625+ activeChar.sendMessage("There is " + CTF._playersShuffle.size() + " player participating in this event.");
4626+ activeChar.sendMessage("Reward: " + CTF.get_rewardAmount() + " " + ItemTable.getInstance().getTemplate(CTF.get_rewardId()).getName() + ".");
4627+ activeChar.sendMessage("Player Min lvl: " + CTF.get_minlvl() + ".");
4628+ activeChar.sendMessage("Player Max lvl: " + CTF.get_maxlvl() + ".");
4629+ }
4630+ else
4631+ {
4632+ activeChar.sendMessage("There are " + CTF._playersShuffle.size() + " players participating in this event.");
4633+ activeChar.sendMessage("Reward: " + CTF.get_rewardAmount() + " " + ItemTable.getInstance().getTemplate(CTF.get_rewardId()).getName() + ".");
4634+ activeChar.sendMessage("Player Min lvl: " + CTF.get_minlvl() + ".");
4635+ activeChar.sendMessage("Player Max lvl: " + CTF.get_maxlvl() + ".");
4636+ }
4637+ return true;
4638+ }
4639+ }
4640+}
4641\ No newline at end of file
4642Index: java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java
4643===================================================================
4644--- java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java (revision 448)
4645+++ java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java (working copy)
4646@@ -13,6 +13,7 @@
4647 import net.sf.l2j.gameserver.cache.HtmCache;
4648 import net.sf.l2j.gameserver.communitybbs.CommunityBoard;
4649 import net.sf.l2j.gameserver.data.xml.AdminData;
4650+import net.sf.l2j.gameserver.event.CTF;
4651 import net.sf.l2j.gameserver.event.L2Event;
4652 import net.sf.l2j.gameserver.event.TvT;
4653 import net.sf.l2j.gameserver.handler.AdminCommandHandler;
4654@@ -116,25 +117,32 @@
4655 }
4656+ else if (_command.substring(endOfId + 1).startsWith("ctf_player_join "))
4657+ {
4658+ String teamName = _command.substring(endOfId + 1).substring(16);
4659+ if(CTF.is_joining())
4660+ CTF.addPlayer(activeChar, teamName);
4661+ else
4662+ activeChar.sendMessage("The event is already started. You can not join now!");
4663+ }
4664+ else if (_command.substring(endOfId + 1).startsWith("ctf_player_leave"))
4665+ {
4666+ if(CTF.is_joining())
4667+ CTF.removePlayer(activeChar);
4668+ else
4669+ activeChar.sendMessage("The event is already started. You can not leave now!");
4670+ }
4671
4672 if (_command.substring(endOfId+1).startsWith("event_participate"))
4673 {
4674Index: java/net/sf/l2j/Config.java
4675===================================================================
4676--- java/net/sf/l2j/Config.java (revision 449)
4677+++ java/net/sf/l2j/Config.java (working copy)
4678@@ -312,6 +311,25 @@
4679 public static boolean TVT_STATS_LOGGER;
4680 public static boolean TVT_ALLOW_HEALER_CLASSES;
4681 public static boolean TVT_REMOVE_BUFFS_ON_DIE;
4682+
4683+ /** CTF Event */
4684+ public static String CTF_EVEN_TEAMS;
4685+ public static boolean CTF_ALLOW_INTERFERENCE;
4686+ public static boolean CTF_ALLOW_POTIONS;
4687+ public static boolean CTF_ALLOW_SUMMON;
4688+ public static boolean CTF_ON_START_REMOVE_ALL_EFFECTS;
4689+ public static boolean CTF_ON_START_UNSUMMON_PET;
4690+ public static boolean CTF_ANNOUNCE_TEAM_STATS;
4691+ public static boolean CTF_ANNOUNCE_REWARD;
4692+ public static long CTF_REVIVE_DELAY;
4693+ public static boolean CTF_REVIVE_RECOVERY;
4694+ public static boolean CTF_COMMAND;
4695+ public static boolean CTF_AURA;
4696+ public static boolean CTF_STATS_LOGGER;
4697+ public static int CTF_SPAWN_OFFSET;
4698+ public static boolean CTF_ALLOW_HEALER_CLASSES;
4699+ public static boolean CTF_REMOVE_BUFFS_ON_DIE;
4700+
4701 public static boolean ALLOW_DUALBOX_EVENT;
4702
4703 // --------------------------------------------------
4704@@ -1312,6 +1329,26 @@
4705 TVT_STATS_LOGGER = events.getProperty("TvTStatsLogger", true);
4706 TVT_ALLOW_HEALER_CLASSES = events.getProperty("TvTAllowedHealerClasses", true);
4707 TVT_REMOVE_BUFFS_ON_DIE = events.getProperty("TvTRemoveBuffsOnPlayerDie", false);
4708+
4709+ CTF_EVEN_TEAMS = events.getProperty("CTFEvenTeams", "BALANCE");
4710+ CTF_ALLOW_INTERFERENCE = events.getProperty("CTFAllowInterference", false);
4711+ CTF_ALLOW_POTIONS = events.getProperty("CTFAllowPotions", false);
4712+ CTF_ALLOW_SUMMON = events.getProperty("CTFAllowSummon", false);
4713+ CTF_ON_START_REMOVE_ALL_EFFECTS = events.getProperty("CTFOnStartRemoveAllEffects", true);
4714+ CTF_ON_START_UNSUMMON_PET = events.getProperty("CTFOnStartUnsummonPet", true);
4715+ CTF_ANNOUNCE_TEAM_STATS = events.getProperty("CTFAnnounceTeamStats", false);
4716+ CTF_ANNOUNCE_REWARD = events.getProperty("CTFAnnounceReward", false);
4717+ CTF_REVIVE_DELAY = events.getProperty("CTFReviveDelay", 20000);
4718+ if (CTF_REVIVE_DELAY < 1000)
4719+ CTF_REVIVE_DELAY = 1000; // can't be set less then 1 second
4720+ CTF_REVIVE_RECOVERY = events.getProperty("CTFReviveRecovery", false);
4721+ CTF_COMMAND = events.getProperty("CTFCommand", true);
4722+ CTF_AURA = events.getProperty("CTFAura", true);
4723+ CTF_STATS_LOGGER = events.getProperty("CTFStatsLogger", true);
4724+ CTF_SPAWN_OFFSET = events.getProperty("CTFSpawnOffset", 100);
4725+ CTF_ALLOW_HEALER_CLASSES = events.getProperty("CTFAllowedHealerClasses", true);
4726+ CTF_REMOVE_BUFFS_ON_DIE = events.getProperty("CTFRemoveBuffsOnPlayerDie", false);
4727+
4728 ALLOW_DUALBOX_EVENT = events.getProperty("AllowDualBoxInEvent", false);
4729 }
4730
4731Index: java/net/sf/l2j/gameserver/network/clientpackets/RequestRestartPoint.java
4732===================================================================
4733--- java/net/sf/l2j/gameserver/network/clientpackets/RequestRestartPoint.java (revision 447)
4734+++ java/net/sf/l2j/gameserver/network/clientpackets/RequestRestartPoint.java (working copy)
4735@@ -5,6 +5,7 @@
4736 import net.sf.l2j.Config;
4737 import net.sf.l2j.gameserver.data.MapRegionTable;
4738 import net.sf.l2j.gameserver.data.MapRegionTable.TeleportType;
4739+import net.sf.l2j.gameserver.event.CTF;
4740 import net.sf.l2j.gameserver.event.TvT;
4741 import net.sf.l2j.gameserver.instancemanager.CastleManager;
4742 import net.sf.l2j.gameserver.instancemanager.ClanHallManager;
4743@@ -40,7 +41,7 @@
4744 @Override
4745 public void run()
4746 {
4747- if ((_player._inEventTvT && TvT.is_started()))
4748+ if ((_player._inEventTvT && TvT.is_started()) || (_player._inEventCTF && CTF.is_started()))
4749 {
4750 _player.sendMessage("You can't restart in Event!");
4751 return;
4752Index: java/net/sf/l2j/gameserver/GameServer.java
4753===================================================================
4754--- java/net/sf/l2j/gameserver/GameServer.java (revision 448)
4755+++ java/net/sf/l2j/gameserver/GameServer.java (working copy)
4756@@ -287,6 +287,11 @@
4757 else
4758 _log.info("TVT: Disabled.");
4759
4760+ if (EventManager.CTF_EVENT_ENABLED)
4761+ _log.info("CTF: Enabled.");
4762+ else
4763+ _log.info("CTF: Disabled.");
4764+
4765 StringUtil.printSection("Handlers");
4766 _log.config("AutoSpawnHandler: Loaded " + AutoSpawnManager.getInstance().size() + " handlers.");
4767 _log.config("AdminCommandHandler: Loaded " + AdminCommandHandler.getInstance().size() + " handlers.");
4768Index: java/net/sf/l2j/gameserver/network/clientpackets/UseItem.java
4769===================================================================
4770--- java/net/sf/l2j/gameserver/network/clientpackets/UseItem.java (revision 447)
4771+++ java/net/sf/l2j/gameserver/network/clientpackets/UseItem.java (working copy)
4772@@ -170,10 +170,13 @@
4773
4774 if (item.isEquipable())
4775 {
4776- if (activeChar.isCastingNow() || activeChar.isCastingSimultaneouslyNow())
4777+ if (activeChar.isCastingNow() || activeChar.isCastingSimultaneouslyNow() || (activeChar._inEventCTF && activeChar._haveFlagCTF))
4778 {
4779- activeChar.sendPacket(SystemMessageId.CANNOT_USE_ITEM_WHILE_USING_MAGIC);
4780- return;
4781+ if (activeChar._inEventCTF && activeChar._haveFlagCTF)
4782+ activeChar.sendMessage("This item can not be equipped when you have the flag.");
4783+ else
4784+ activeChar.sendPacket(SystemMessageId.CANNOT_USE_ITEM_WHILE_USING_MAGIC);
4785+ return;
4786 }
4787
4788 switch (item.getItem().getBodyPart())
4789Index: java/net/sf/l2j/gameserver/handler/usercommandhandlers/Escape.java
4790===================================================================
4791--- java/net/sf/l2j/gameserver/handler/usercommandhandlers/Escape.java (revision 449)
4792+++ java/net/sf/l2j/gameserver/handler/usercommandhandlers/Escape.java (working copy)
4793@@ -1,6 +1,7 @@
4794 package net.sf.l2j.gameserver.handler.usercommandhandlers;
4795
4796 import net.sf.l2j.gameserver.data.SkillTable;
4797+import net.sf.l2j.gameserver.event.CTF;
4798 import net.sf.l2j.gameserver.event.TvT;
4799 import net.sf.l2j.gameserver.handler.IUserCommandHandler;
4800 import net.sf.l2j.gameserver.model.actor.instance.Player;
4801@@ -23,17 +24,11 @@
4802 return false;
4803 }
4804 // Check to see if the current player is in TVT Event.
4805- if (activeChar._inEventTvT && TvT.is_started())
4806+ if (activeChar._inEventTvT && TvT.is_started() || activeChar._inEventCTF && CTF.is_started())
4807 {
4808 activeChar.sendMessage("You may not use an escape skill in event.");
4809 return false;
4810 }
4811
4812 activeChar.stopMove(null);
4813
4814Index: java/net/sf/l2j/gameserver/model/actor/instance/MutedFolk.java
4815===================================================================
4816--- java/net/sf/l2j/gameserver/model/actor/instance/MutedFolk.java (revision 447)
4817+++ java/net/sf/l2j/gameserver/model/actor/instance/MutedFolk.java (working copy)
4818@@ -1,5 +1,6 @@
4819 package net.sf.l2j.gameserver.model.actor.instance;
4820
4821+import net.sf.l2j.gameserver.event.CTF;
4822 import net.sf.l2j.gameserver.event.L2Event;
4823 import net.sf.l2j.gameserver.event.TvT;
4824 import net.sf.l2j.gameserver.model.actor.Npc;
4825@@ -67,6 +60,28 @@
4826
4827 // Send ActionFailed to the player in order to avoid he stucks
4828 player.sendPacket(ActionFailed.STATIC_PACKET);
4829+
4830+ // Open a chat window on client with the text of the L2NpcInstance
4831+ if (isEventMob)
4832+ {
4833+ L2Event.showEventHtml(player, String.valueOf(getObjectId()));
4834+ }
4835+ else if (_isEventMobTvT)
4836+ {
4837+ TvT.showEventHtml(player, String.valueOf(getObjectId()));
4838+ }
4839+ else if (_isEventMobCTF)
4840+ {
4841+ CTF.showEventHtml(player, String.valueOf(getObjectId()));
4842+ }
4843+ else if (_isCTF_Flag && player._inEventCTF)
4844+ {
4845+ CTF.showFlagHtml(player, String.valueOf(this.getObjectId()), _CTF_FlagTeamName);
4846+ }
4847+ else if (_isCTF_throneSpawn)
4848+ {
4849+ CTF.checkRestoreFlags();
4850+ }
4851 }
4852 }
4853 }
4854Index: java/net/sf/l2j/gameserver/handler/itemhandlers/ItemSkills.java
4855===================================================================
4856--- java/net/sf/l2j/gameserver/handler/itemhandlers/ItemSkills.java (revision 447)
4857+++ java/net/sf/l2j/gameserver/handler/itemhandlers/ItemSkills.java (working copy)
4858@@ -1,6 +1,7 @@
4859 package net.sf.l2j.gameserver.handler.itemhandlers;
4860
4861 import net.sf.l2j.Config;
4862+import net.sf.l2j.gameserver.event.CTF;
4863 import net.sf.l2j.gameserver.event.TvT;
4864 import net.sf.l2j.gameserver.handler.IItemHandler;
4865 import net.sf.l2j.gameserver.model.L2Skill;
4866@@ -45,6 +45,12 @@
4867 return;
4868 }
4869
4870+ if (activeChar._inEventCTF && CTF.is_started() && !Config.CTF_ALLOW_POTIONS)
4871+ {
4872+ activeChar.sendPacket(ActionFailed.STATIC_PACKET);
4873+ return;
4874+ }
4875+
4876 final IntIntHolder[] skills = item.getEtcItem().getSkills();
4877 if (skills == null)
4878 {
4879Index: java/net/sf/l2j/gameserver/network/clientpackets/RequestJoinParty.java
4880===================================================================
4881--- java/net/sf/l2j/gameserver/network/clientpackets/RequestJoinParty.java (revision 447)
4882+++ java/net/sf/l2j/gameserver/network/clientpackets/RequestJoinParty.java (working copy)
4883@@ -1,5 +1,6 @@
4884 package net.sf.l2j.gameserver.network.clientpackets;
4885
4886+import net.sf.l2j.gameserver.event.CTF;
4887 import net.sf.l2j.gameserver.event.TvT;
4888 import net.sf.l2j.gameserver.model.BlockList;
4889 import net.sf.l2j.gameserver.model.World;
4890@@ -54,9 +55,9 @@
4891 return;
4892 }
4893
4894- if ((requestor._inEventTvT && !target._inEventTvT && (TvT.is_started() || TvT.is_teleport())) || (!requestor._inEventTvT && target._inEventTvT && (TvT.is_started() || TvT.is_teleport())))
4895+ if ((requestor._inEventTvT && !target._inEventTvT && (TvT.is_started() || TvT.is_teleport())) || (!requestor._inEventTvT && target._inEventTvT && (TvT.is_started() || TvT.is_teleport())) || (requestor._inEventCTF && !target._inEventCTF && (CTF.is_started() || CTF.is_teleport())) || (!requestor._inEventCTF && target._inEventCTF && (CTF.is_started() || CTF.is_teleport())))
4896 {
4897- requestor.sendMessage("You can't invite that player in party: you or your target are in Event");
4898+ requestor.sendMessage("The player you tried to invite is participating in the event.");
4899 return;
4900 }
4901
4902### Eclipse Workspace Patch 1.0
4903#P aCis_datapack
4904Index: sql/ctf_teams.sql
4905===================================================================
4906--- sql/ctf_teams.sql (revision 0)
4907+++ sql/ctf_teams.sql (working copy)
4908@@ -0,0 +1,19 @@
4909+DROP TABLE IF EXISTS `ctf_teams`;
4910+CREATE TABLE `ctf_teams` (
4911+ `teamId` int(4) NOT NULL DEFAULT '0',
4912+ `teamName` varchar(255) NOT NULL DEFAULT '',
4913+ `teamX` int(11) NOT NULL DEFAULT '0',
4914+ `teamY` int(11) NOT NULL DEFAULT '0',
4915+ `teamZ` int(11) NOT NULL DEFAULT '0',
4916+ `teamColor` int(11) NOT NULL DEFAULT '0',
4917+ `flagX` int(11) NOT NULL DEFAULT '0',
4918+ `flagY` int(11) NOT NULL DEFAULT '0',
4919+ `flagZ` int(11) NOT NULL DEFAULT '0',
4920+ PRIMARY KEY (`teamId`)
4921+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
4922+
4923+-- ----------------------------
4924+-- Records of ctf_teams
4925+-- ----------------------------
4926+INSERT INTO ctf_teams VALUES ('0', 'Blue', '112650', '-16020', '-999', '16711680', '112610', '-15306', '-552');
4927+INSERT INTO ctf_teams VALUES ('1', 'red', '109201', '-15314', '-992', '255', '109994', '-14996', '-553');
4928Index: tools/database_installer.bat
4929===================================================================
4930--- tools/database_installer.bat (revision 447)
4931+++ tools/database_installer.bat (working copy)
4932@@ -90,6 +90,8 @@
4933 %mysqlPath% -h %gshost% -u %gsuser% --password=%gspass% -D %gsdb% < ../sql/clan_wars.sql
4934 %mysqlPath% -h %gshost% -u %gsuser% --password=%gspass% -D %gsdb% < ../sql/clanhall.sql
4935 %mysqlPath% -h %gshost% -u %gsuser% --password=%gspass% -D %gsdb% < ../sql/clanhall_functions.sql
4936+%mysqlPath% -h %gshost% -u %gsuser% --password=%gspass% -D %gsdb% < ../sql/ctf.sql
4937+%mysqlPath% -h %gshost% -u %gsuser% --password=%gspass% -D %gsdb% < ../sql/ctf_teams.sql
4938 %mysqlPath% -h %gshost% -u %gsuser% --password=%gspass% -D %gsdb% < ../sql/cursed_weapons.sql
4939 %mysqlPath% -h %gshost% -u %gsuser% --password=%gspass% -D %gsdb% < ../sql/fishing_championship.sql
4940 %mysqlPath% -h %gshost% -u %gsuser% --password=%gspass% -D %gsdb% < ../sql/forums.sql
4941Index: sql/ctf.sql
4942===================================================================
4943--- sql/ctf.sql (revision 0)
4944+++ sql/ctf.sql (working copy)
4945@@ -0,0 +1,26 @@
4946+DROP TABLE IF EXISTS `ctf`;
4947+CREATE TABLE `ctf` (
4948+ `eventName` varchar(255) NOT NULL DEFAULT '',
4949+ `eventDesc` varchar(255) NOT NULL DEFAULT '',
4950+ `joiningLocation` varchar(255) NOT NULL DEFAULT '',
4951+ `minlvl` int(4) NOT NULL DEFAULT '0',
4952+ `maxlvl` int(4) NOT NULL DEFAULT '0',
4953+ `npcId` int(8) NOT NULL DEFAULT '0',
4954+ `npcX` int(11) NOT NULL DEFAULT '0',
4955+ `npcY` int(11) NOT NULL DEFAULT '0',
4956+ `npcZ` int(11) NOT NULL DEFAULT '0',
4957+ `npcHeading` int(11) NOT NULL DEFAULT '0',
4958+ `rewardId` int(11) NOT NULL DEFAULT '0',
4959+ `rewardAmount` int(11) NOT NULL DEFAULT '0',
4960+ `teamsCount` int(4) NOT NULL DEFAULT '0',
4961+ `joinTime` int(11) NOT NULL DEFAULT '0',
4962+ `eventTime` int(11) NOT NULL DEFAULT '0',
4963+ `minPlayers` int(4) NOT NULL DEFAULT '0',
4964+ `maxPlayers` int(4) NOT NULL DEFAULT '0',
4965+ `delayForNextEvent` bigint(20) NOT NULL DEFAULT '0'
4966+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
4967+
4968+-- ----------------------------
4969+-- Records of ctf
4970+-- ----------------------------
4971+INSERT INTO ctf VALUES ('Capture the flag', 'CTF', 'Giran', '40', '80', '70011', '83403', '148611', '-3431', '16972', '6392', '3', '2', '5', '5', '8', '100', '300000');
4972Index: tools/full_install.sql
4973===================================================================
4974--- tools/full_install.sql (revision 447)
4975+++ tools/full_install.sql (working copy)
4976@@ -33,6 +33,8 @@
4977 DROP TABLE IF EXISTS clan_wars;
4978 DROP TABLE IF EXISTS clanhall;
4979 DROP TABLE IF EXISTS clanhall_functions;
4980+DROP TABLE IF EXISTS ctf;
4981+DROP TABLE IF EXISTS ctf_teams;
4982 DROP TABLE IF EXISTS cursed_weapons;
4983 DROP TABLE IF EXISTS fishing_championship;
4984 DROP TABLE IF EXISTS forums;