Noticias:

No tienes permiso para ver los enlaces. Para poder verlos Registrate o Conectate.

Menú Principal

Evento Town War

Iniciado por Swarlog, Jun 28, 2025, 11:41 PM

Tema anterior - Siguiente tema

Swarlog

CitarCORE:

### Eclipse Workspace Patch 1.0
#P L2J_Server_BETA
Index: java/com/l2jserver/gameserver/model/actor/instance/L2TeleporterInstance.java
===================================================================
--- java/com/l2jserver/gameserver/model/actor/instance/L2TeleporterInstance.java	(revision 5253)
+++ java/com/l2jserver/gameserver/model/actor/instance/L2TeleporterInstance.java	(working copy)
@@ -222,6 +222,11 @@
 		L2TeleportLocation list = TeleportLocationTable.getInstance().getTemplate(val);
 		if (list != null)
 		{
+			if (Config.TW_DISABLE_GK && isInTownWarEvent())
+			{
+				player.sendMessage("You can't teleport during Town War Event.");
+				return;
+			}
 			//you cannot teleport to village that is in siege
 			if (SiegeManager.getInstance().getSiege(list.getLocX(), list.getLocY(), list.getLocZ()) != null)
 			{
Index: dist/game/config/l2jmods.properties
===================================================================
--- dist/game/config/l2jmods.properties	(revision 5253)
+++ dist/game/config/l2jmods.properties	(working copy)
@@ -221,6 +221,73 @@
 
 
 # ---------------------------------------------------------------------------
+# Town War Event (by SolidSnake)
+# ---------------------------------------------------------------------------
+# Town ID that you can set as War Zone for the event:
+# 
+# 1:  Dark Elf Village
+# 2:  Talking Island
+# 3:  Elven Village
+# 4:  Orc Village
+# 5:  Gludin Town
+# 6:  Dwarven Village
+# 7:  Town of Gludio
+# 8:  Town of Dion
+# 9:  Giran Town
+# 9:  Giran Harbour
+# 10: Oren Town
+# 11: Hunters Village
+# 12: Town of Aden
+# 13: Town of Goddard
+# 14: Town of Rune
+# 15: Heine
+# 16: Floran Village
+# 17: Town of Schuttgart
+# 20: Kamael Village
+# 
+# Default: 9 (Giran Town)
+TownWarTownId = 9
+TownWarTownName = Giran Town
+
+# Set all towns as War Zone (TownWarTownId won't be read) ?
+TownWarAllTowns = False
+
+# Enable or disable the Town War auto system?
+TownWarAutoEvent = False
+
+# Times Town War will occur (24h format).
+TownWarInterval = 9:00,15:00,21:00,3:00
+
+# Time before the event starts (in minutes).
+TownWarTimeBeforeStart = 5
+
+# Event running time (in minutes).
+TownWarRunningTime = 10
+
+# What's the reward for each kill?
+TownWarItemId = 57
+TownWarItemAmount = 5000
+
+# Give PvP/Pk points on Event kill?
+TownWarGivePvPAndPkPoints = False
+
+# Give Karma on Pk during the Town War Event?
+TownWarAllowKarma = False
+
+# Disable gatekeepers in the Town set for the event?
+TownWarDisableGK = False
+
+# Send a ress on participants' death?
+TownWarRessOnDeath = True
+
+# Respawn killed participants in random locations?
+TownWarRandomSpawn = True
+
+# Should participants lose buffs on death?
+TownWarLoseBuffsOnDeath = False
+
+
+# ---------------------------------------------------------------------------
 # L2J Banking System
 # ---------------------------------------------------------------------------
 # Enable/Disable Banking System
Index: java/com/l2jserver/gameserver/model/actor/knownlist/CharKnownList.java
===================================================================
--- java/com/l2jserver/gameserver/model/actor/knownlist/CharKnownList.java	(revision 5253)
+++ java/com/l2jserver/gameserver/model/actor/knownlist/CharKnownList.java	(working copy)
@@ -200,7 +200,12 @@
 			if (obj instanceof L2Character)
 			{
 				if (Util.checkIfInRange((int) radius, getActiveChar(), obj, true))
-					result.add((L2Character) obj);
+					{
+						if (!(obj instanceof L2PcInstance)
+								|| !((L2PcInstance)obj).isInTownWarEvent()
+								|| !((L2PcInstance)obj).getClient().isDetached())
+							result.add((L2Character) obj);
+					}
 			}
 		}
 		
Index: java/com/l2jserver/gameserver/GameServer.java
===================================================================
--- java/com/l2jserver/gameserver/GameServer.java	(revision 5253)
+++ java/com/l2jserver/gameserver/GameServer.java	(working copy)
@@ -116,6 +116,7 @@
 import com.l2jserver.gameserver.model.PartyMatchRoomList;
 import com.l2jserver.gameserver.model.PartyMatchWaitingList;
 import com.l2jserver.gameserver.model.entity.Hero;
+import com.l2jserver.gameserver.model.entity.TownWarManager;
 import com.l2jserver.gameserver.model.entity.TvTManager;
 import com.l2jserver.gameserver.model.olympiad.Olympiad;
 import com.l2jserver.gameserver.network.L2GameClient;
@@ -365,6 +366,7 @@
 		_log.info("IdFactory: Free ObjectID's remaining: " + IdFactory.getInstance().size());
 		
 		TvTManager.getInstance();
+		TownWarManager.getInstance();
 		KnownListUpdateTaskManager.getInstance();
 		
 		if ((Config.OFFLINE_TRADE_ENABLE || Config.OFFLINE_CRAFT_ENABLE) && Config.RESTORE_OFFLINERS)
Index: java/com/l2jserver/gameserver/model/zone/type/L2TownZone.java
===================================================================
--- java/com/l2jserver/gameserver/model/zone/type/L2TownZone.java	(revision 5253)
+++ java/com/l2jserver/gameserver/model/zone/type/L2TownZone.java	(working copy)
@@ -25,6 +25,7 @@
 {
 	private int _townId;
 	private int _taxById;
+	private boolean _isTWZone = false;
 	
 	public L2TownZone(int id)
 	{
@@ -53,15 +54,40 @@
 	@Override
 	protected void onEnter(L2Character character)
 	{
+		if (_isTWZone)
+		{
+			character.setInTownWarEvent(true);
+			character.sendMessage("You entered a Town War event zone.");
+		}
 		character.setInsideZone(L2Character.ZONE_TOWN, true);
 	}
 	
 	@Override
 	protected void onExit(L2Character character)
 	{
+		if (_isTWZone)
+		{
+			character.setInTownWarEvent(false);
+			character.sendMessage("You left a Town War event zone.");
+		}
+
 		character.setInsideZone(L2Character.ZONE_TOWN, false);
 	}
-	
+
+	public void onUpdate(L2Character character)
+	{
+		if (_isTWZone)
+		{
+			character.setInTownWarEvent(true);
+			character.sendMessage("You entered a Town War event zone.");
+		}
+		else
+		{
+			character.setInTownWarEvent(false);
+			character.sendMessage("You left a Town War event zone.");
+		}
+	}
+
 	@Override
 	public void onDieInside(L2Character character)
 	{
@@ -71,7 +97,16 @@
 	public void onReviveInside(L2Character character)
 	{
 	}
-	
+
+	public void updateForCharactersInside()
+	{
+		for (L2Character character : getCharactersInsideArray())
+		{
+			if (character != null)
+				onUpdate(character);
+		}
+	}
+
 	/**
 	 * Returns this zones town id (if any)
 	 * @return
@@ -89,4 +124,9 @@
 	{
 		return _taxById;
 	}
+	
+	public final void setIsTWZone(boolean value)
+	{
+		_isTWZone = value;
+	}
 }
Index: java/com/l2jserver/gameserver/model/entity/TownWarManager.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/TownWarManager.java	(revision 0)
+++ java/com/l2jserver/gameserver/model/entity/TownWarManager.java	(working copy)
@@ -0,0 +1,292 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.model.entity;
+
+import java.util.Calendar;
+import java.util.concurrent.ScheduledFuture;
+import java.util.logging.Logger;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.Announcements;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.instancemanager.TownManager;
+import com.l2jserver.gameserver.model.L2World;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+
+/**
+ * @author SolidSnake
+ */
+public class TownWarManager
+{
+	protected static final Logger _log = Logger.getLogger(TownWarManager.class.getName());
+	private TownWarStartTask _task;
+	private static final int ALL_TOWNS_INT = 17;
+	private boolean isInactive = false;
+	private boolean isStarting = false;
+	private boolean isStarted = false;
+	
+	private TownWarManager()
+	{
+		if (Config.TW_AUTO_EVENT)
+		{
+			isInactive = true;
+			this.scheduleEventStart();
+			_log.info("TownWarEngine[TownWarManager.TownWarManager()]: Started.");
+		}
+		else
+		{
+			_log.info("TownWarEngine[TownWarManager.TownWarManager()]: Disabled.");
+		}
+	}
+	
+	public static TownWarManager getInstance()
+	{
+		return SingletonHolder._instance;
+	}
+	
+	public void scheduleEventStart()
+	{
+		try
+		{
+			Calendar currentTime = Calendar.getInstance();
+			Calendar nextStartTime = null;
+			Calendar testStartTime = null;
+			for (String timeOfDay : Config.TW_INTERVAL)
+			{
+				testStartTime = Calendar.getInstance();
+				testStartTime.setLenient(true);
+				String[] splitTimeOfDay = timeOfDay.split(":");
+				testStartTime.set(Calendar.HOUR_OF_DAY, Integer.parseInt(splitTimeOfDay[0]));
+				testStartTime.set(Calendar.MINUTE, Integer.parseInt(splitTimeOfDay[1]));
+				if (testStartTime.getTimeInMillis() < currentTime.getTimeInMillis())
+				{
+					testStartTime.add(Calendar.DAY_OF_MONTH, 1);
+				}
+				if (nextStartTime == null || testStartTime.getTimeInMillis() < nextStartTime.getTimeInMillis())
+				{
+					nextStartTime = testStartTime;
+				}
+			}
+			_task = new TownWarStartTask(nextStartTime.getTimeInMillis());
+			ThreadPoolManager.getInstance().executeTask(_task);
+		}
+		catch (Exception e)
+		{
+			_log.warning("TownWarEngine[TownWarManager.scheduleEventStart()]: Error figuring out a start time. Check TownWarEventInterval in config file.");
+		}
+	}
+	
+	public void starting()
+	{
+		isInactive = false;
+		isStarting = true;
+		_task.setStartTime(System.currentTimeMillis() + 60000L * Config.TW_TIME_BEFORE_START);
+		ThreadPoolManager.getInstance().executeTask(_task);
+	}
+	
+	public void startEvent()
+	{
+		isStarting = false;
+		isStarted = true;
+		if (Config.TW_ALL_TOWNS)
+		{
+			for (int i = 1; i <= ALL_TOWNS_INT; i++)
+			{
+				TownManager.getTown(i).setIsTWZone(true);
+				TownManager.getTown(i).updateForCharactersInside();
+			}
+			TownManager.getTown(20).setIsTWZone(true);
+			TownManager.getTown(20).updateForCharactersInside();
+			Announcements.getInstance().announceToAll("Town War: All towns are war zone.");
+		}
+		else
+		{
+			TownManager.getTown(Config.TW_TOWN_ID).setIsTWZone(true);
+			TownManager.getTown(Config.TW_TOWN_ID).updateForCharactersInside();
+			Announcements.getInstance().announceToAll("Town War Event: " + Config.TW_TOWN_NAME + " is now a war zone.");
+			Announcements.getInstance().announceToAll("Town War Event: Reward is 5 Glittering Medals for each Kill.");
+			Announcements.getInstance().announceToAll("Town War Event: Good Luck.");
+		}
+		
+		_task.setStartTime(System.currentTimeMillis() + 60000L * Config.TW_RUNNING_TIME);
+		ThreadPoolManager.getInstance().executeTask(_task);
+	}
+	
+	public void endEvent()
+	{
+		isStarted = false;
+		isInactive = true;
+		if (Config.TW_ALL_TOWNS)
+		{
+			for (int i = 1; i <= ALL_TOWNS_INT; i++)
+			{
+				TownManager.getTown(i).setIsTWZone(false);
+				TownManager.getTown(i).updateForCharactersInside();
+			}
+			TownManager.getTown(20).setIsTWZone(false);
+			TownManager.getTown(20).updateForCharactersInside();
+			Announcements.getInstance().announceToAll("Town War: All towns are returned normal.");
+		}
+		else
+		{
+			TownManager.getTown(Config.TW_TOWN_ID).setIsTWZone(false);
+			TownManager.getTown(Config.TW_TOWN_ID).updateForCharactersInside();
+			Announcements.getInstance().announceToAll("Town War Event: " + Config.TW_TOWN_NAME + " has returned to peace zone.");
+			Announcements.getInstance().announceToAll("Town War Event: Congratulations to all winners.");
+		}
+		
+		this.scheduleEventStart();
+	}
+	
+	class TownWarStartTask implements Runnable
+	{
+		private long _startTime;
+		public ScheduledFuture<?> nextRun;
+		
+		public TownWarStartTask(long startTime)
+		{
+			_startTime = startTime;
+		}
+		
+		public void setStartTime(long startTime)
+		{
+			_startTime = startTime;
+		}
+		
+		/**
+		 * @see java.lang.Runnable#run()
+		 */
+		@Override
+		public void run()
+		{
+			int delay = (int) Math.round((_startTime - System.currentTimeMillis()) / 1000.0);
+			
+			if (delay > 0)
+			{
+				this.announce(delay);
+			}
+			
+			int nextMsg = 0;
+			if (delay > 3600)
+			{
+				nextMsg = delay - 3600;
+			}
+			else if (delay > 1800)
+			{
+				nextMsg = delay - 1800;
+			}
+			else if (delay > 900)
+			{
+				nextMsg = delay - 900;
+			}
+			else if (delay > 600)
+			{
+				nextMsg = delay - 600;
+			}
+			else if (delay > 300)
+			{
+				nextMsg = delay - 300;
+			}
+			else if (delay > 60)
+			{
+				nextMsg = delay - 60;
+			}
+			else if (delay > 5)
+			{
+				nextMsg = delay - 5;
+			}
+			else if (delay > 0)
+			{
+				nextMsg = delay;
+			}
+			else
+			{
+				if (TownWarManager.this.isInactive)
+				{
+					TownWarManager.this.starting();
+				}
+				else if (TownWarManager.this.isStarting)
+				{
+					TownWarManager.this.startEvent();
+				}
+				else
+				{
+					TownWarManager.this.endEvent();
+				}
+			}
+			
+			if (delay > 0)
+			{
+				nextRun = ThreadPoolManager.getInstance().scheduleGeneral(this, nextMsg * 1000);
+			}
+		}
+		
+		private void announce(long time)
+		{
+			if (time >= 3600 && time % 3600 == 0)
+			{
+				if (TownWarManager.this.isStarting)
+				{
+					Announcements.getInstance().announceToAll("Town War Event: " + (time / 60 / 60) + " hour(s) until event starts!");
+				}
+				else if (TownWarManager.this.isStarted)
+				{
+					for (L2PcInstance onlinePlayer : L2World.getInstance().getAllPlayersArray())
+					{
+						if (onlinePlayer != null && onlinePlayer.isOnline())
+							onlinePlayer.sendMessage("Town War Event: " + (time / 60 / 60) + " hour(s) until event is finished!");
+					}
+				}
+			}
+			else if (time >= 60)
+			{
+				if (TownWarManager.this.isStarting)
+				{
+					Announcements.getInstance().announceToAll("Town War Event: " + (time / 60) + " minute(s) until event starts!");
+				}
+				else if (TownWarManager.this.isStarted)
+				{
+					for (L2PcInstance onlinePlayer : L2World.getInstance().getAllPlayersArray())
+					{
+						if (onlinePlayer != null && onlinePlayer.isOnline())
+							onlinePlayer.sendMessage("Town War Event: " + (time / 60) + " minute(s) until the event is finished!");
+					}
+				}
+			}
+			else
+			{
+				if (TownWarManager.this.isStarting)
+				{
+					Announcements.getInstance().announceToAll("Town War Event: " + time + " second(s) until event starts!");
+				}
+				else if (TownWarManager.this.isStarted)
+				{
+					for (L2PcInstance onlinePlayer : L2World.getInstance().getAllPlayersArray())
+					{
+						if (onlinePlayer != null && onlinePlayer.isOnline())
+							onlinePlayer.sendMessage("Town War Event: " + time + " second(s) until the event is finished!");
+					}
+				}
+			}
+		}
+	}
+	
+	@SuppressWarnings("synthetic-access")
+	private static class SingletonHolder
+	{
+		protected static final TownWarManager _instance = new TownWarManager();
+	}
+}
\ No newline at end of file
Index: java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java
===================================================================
--- java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java	(revision 5253)
+++ java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java	(working copy)
@@ -218,6 +218,7 @@
 import com.l2jserver.gameserver.network.serverpackets.ExOlympiadMode;
 import com.l2jserver.gameserver.network.serverpackets.ExPrivateStoreSetWholeMsg;
 import com.l2jserver.gameserver.network.serverpackets.ExSetCompassZoneCode;
+import com.l2jserver.gameserver.network.serverpackets.ExShowScreenMessage;
 import com.l2jserver.gameserver.network.serverpackets.ExSpawnEmitter;
 import com.l2jserver.gameserver.network.serverpackets.ExStartScenePlayer;
 import com.l2jserver.gameserver.network.serverpackets.ExStorageMaxCount;
@@ -5628,7 +5629,7 @@
 						}
 					}
 					//If player is Lucky shouldn't get penalized.
-					if (Config.ALT_GAME_DELEVEL && !isLucky())
+					if (Config.ALT_GAME_DELEVEL && !isLucky() && !isInTownWarEvent())
 					{
 						// Reduce the Experience of the L2PcInstance in function of the calculated Death Penalty
 						// NOTE: deathPenalty +- Exp will update karma
@@ -5680,7 +5681,7 @@
 		
 		AntiFeedManager.getInstance().setLastDeathTime(getObjectId());
 		
-		if (isPhoenixBlessed())
+		if (isPhoenixBlessed() || (Config.TW_RESS_ON_DEATH && isInTownWarEvent()))
 			reviveRequest(this, null, false);
 		else if (isAffected(CharEffectList.EFFECT_FLAG_CHARM_OF_COURAGE) && this.isInSiege())
 		{
@@ -5821,7 +5822,19 @@
 			// sendPacket(msg);
 			return;
 		}
-		
+
+		if (isInTownWarEvent() && targetPlayer.isInTownWarEvent()
+            && !getClient().getConnection().getInetAddress().getHostAddress().equals(targetPlayer.getClient().getConnection().getInetAddress().getHostAddress()))
+		{
+			getInventory().addItem("TownWar", Config.TW_ITEM_ID, Config.TW_ITEM_AMOUNT, this, this);
+			SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S2_S1_S);
+			sm.addItemName(Config.TW_ITEM_ID);
+			sm.addItemNumber(Config.TW_ITEM_AMOUNT);
+			sendPacket(sm);
+			ExShowScreenMessage msg = new ExShowScreenMessage("You received your prize for a Town War kill!", 5000);
+			sendPacket(msg);
+		}
+
 		// If in duel and you kill (only can kill l2summon), do nothing
 		if (isInDuel() && targetPlayer.isInDuel()) return;
 		
@@ -5880,12 +5893,15 @@
 		if (target instanceof L2PcInstance
 				&& AntiFeedManager.getInstance().check(this, target))
 		{
-			// Add karma to attacker and increase its PK counter
-			setPvpKills(getPvpKills() + 1);
-			
-			// Send a Server->Client UserInfo packet to attacker with its Karma and PK Counter
-			sendPacket(new UserInfo(this));
-			sendPacket(new ExBrExtraUserInfo(this));
+			if (!isInTownWarEvent() || Config.TW_GIVE_PVP_AND_PK_POINTS)
+			{
+				// Add karma to attacker and increase its PK counter
+				setPvpKills(getPvpKills() + 1);
+				
+				// Send a Server->Client UserInfo packet to attacker with its Karma and PK Counter
+				sendPacket(new UserInfo(this));
+				sendPacket(new ExBrExtraUserInfo(this));
+			}
 		}
 	}
 	
@@ -5940,9 +5956,12 @@
 			newKarma = Integer.MAX_VALUE - getKarma();
 		
 		// Add karma to attacker and increase its PK counter
-		setKarma(getKarma() + newKarma);
+		if (!isInTownWarEvent() || Config.TW_ALLOW_KARMA)
+			setKarma(getKarma() + newKarma);
+
 		if (target instanceof L2PcInstance
-				&& AntiFeedManager.getInstance().check(this, target))
+				&& AntiFeedManager.getInstance().check(this, target)
+				&& (!isInTownWarEvent() || Config.TW_GIVE_PVP_AND_PK_POINTS))
 			setPkKills(getPkKills() + 1);
 		
 		// Send a Server->Client UserInfo packet to attacker with its Karma and PK Counter
@@ -8867,7 +8886,10 @@
 		// Check if the attacker is in TvT and TvT is started
 		if (TvTEvent.isStarted() && TvTEvent.isPlayerParticipant(getObjectId()))
 			return true;
-		
+
+		if (isInTownWarEvent())
+			return true;
+
 		// Check if the attacker is a L2Playable
 		if (attacker instanceof L2Playable)
 		{
@@ -9254,7 +9276,7 @@
 		// Check if this is offensive magic skill
 		if (skill.isOffensive())
 		{
-			if ((isInsidePeaceZone(this, target)) && !getAccessLevel().allowPeaceAttack())
+			if ((isInsidePeaceZone(this, target)) && !allowPeaceAttack())
 			{
 				// If L2Character or target is in a peace zone, send a system message TARGET_IN_PEACEZONE a Server->Client packet ActionFailed
 				sendPacket(SystemMessageId.TARGET_IN_PEACEZONE);
@@ -9283,7 +9305,7 @@
 			}
 			
 			// Check if the target is attackable
-			if (!target.isAttackable() && !getAccessLevel().allowPeaceAttack())
+			if (!target.isAttackable() && !allowPeaceAttack())
 			{
 				// If target is not attackable, send a Server->Client packet ActionFailed
 				sendPacket(ActionFailed.STATIC_PACKET);
@@ -9363,7 +9385,7 @@
 				return false;
 			}
 			// And this skill cannot be used in peace zone, not even on NPCs!
-			if(this.isInsideZone(L2Character.ZONE_PEACE))
+			if(this.isInsideZone(L2Character.ZONE_PEACE) && !allowPeaceAttack())
 			{
 				//Sends a sys msg to client
 				sendPacket(SystemMessageId.TARGET_IN_PEACEZONE);
@@ -9455,7 +9477,7 @@
 			case TARGET_SELF:
 				break;
 			default:
-				if (!checkPvpSkill(target, skill) && !getAccessLevel().allowPeaceAttack())
+				if (!checkPvpSkill(target, skill) && !allowPeaceAttack())
 				{
 					// Send a System Message to the L2PcInstance
 					sendPacket(SystemMessageId.TARGET_IS_INCORRECT);
@@ -9696,6 +9718,8 @@
 			else if ((skilldat != null && !skilldat.isCtrlPressed() && skill.isOffensive() && !srcIsSummon)
 					|| (skilldatpet != null && !skilldatpet.isCtrlPressed() && skill.isOffensive() && srcIsSummon))
 			{
+				if (isInTownWarEvent())
+					return true;
 				if(getClan() != null && ((L2PcInstance)target).getClan() != null)
 				{
 					if(getClan().isAtWarWith(((L2PcInstance)target).getClan().getClanId()) && ((L2PcInstance)target).getClan().isAtWarWith(getClan().getClanId()))
@@ -11382,7 +11406,7 @@
 		{
 			_reviveRequested = 1;
 			int restoreExp = 0;
-			if (isPhoenixBlessed())
+			if (isPhoenixBlessed() || (Config.TW_RESS_ON_DEATH && isInTownWarEvent()))
 				_revivePower=100;
 			else if (isAffected(CharEffectList.EFFECT_FLAG_CHARM_OF_COURAGE))
 				_revivePower=0;
@@ -15507,6 +15531,20 @@
 		return 0;
 	}
 	
+	public boolean allowPeaceAttack()
+	{
+		if (!getAccessLevel().allowPeaceAttack() && getTarget() != null && getTarget() instanceof L2Npc)
+		{
+			return Config.ALT_ATTACKABLE_NPCS;
+		}
+		if (getTarget() != null && getTarget() instanceof L2PcInstance)
+		{
+			L2PcInstance target = (L2PcInstance) getTarget();
+			return ((isInTownWarEvent() && !target.getClient().isDetached()) || getAccessLevel().allowPeaceAttack());
+		}
+		return (isInTownWarEvent() || getAccessLevel().allowPeaceAttack());
+	}
+	
 	public void setLastPetitionGmName(String gmName)
 	{
 		_lastPetitionGmName = gmName;
Index: java/com/l2jserver/Config.java
===================================================================
--- java/com/l2jserver/Config.java	(revision 5253)
+++ java/com/l2jserver/Config.java	(working copy)
@@ -719,6 +719,21 @@
 	public static TIntIntHashMap TVT_EVENT_MAGE_BUFFS;
 	public static int TVT_EVENT_MAX_PARTICIPANTS_PER_IP;
 	public static boolean TVT_ALLOW_VOICED_COMMAND;
+	public static int TW_TOWN_ID;
+	public static String TW_TOWN_NAME;
+	public static boolean TW_ALL_TOWNS;
+	public static boolean TW_AUTO_EVENT;
+	public static String[] TW_INTERVAL;
+	public static int TW_TIME_BEFORE_START;
+	public static int TW_RUNNING_TIME;
+	public static int TW_ITEM_ID;
+	public static int TW_ITEM_AMOUNT;
+	public static boolean TW_GIVE_PVP_AND_PK_POINTS;
+	public static boolean TW_ALLOW_KARMA;
+	public static boolean TW_DISABLE_GK;
+	public static boolean TW_RESS_ON_DEATH;
+	public static boolean TW_RANDOM_SPAWN;
+	public static boolean TW_LOSE_BUFFS_ON_DEATH;
 	public static boolean L2JMOD_ALLOW_WEDDING;
 	public static int L2JMOD_WEDDING_PRICE;
 	public static boolean L2JMOD_WEDDING_PUNISH_INFIDELITY;
@@ -2565,7 +2580,23 @@
 							}
 						}
 					}
-					
+
+					TW_TOWN_ID = Integer.parseInt(L2JModSettings.getProperty("TownWarTownId", "9"));
+					TW_TOWN_NAME = L2JModSettings.getProperty("TownWarTownName", "Giran Town");
+					TW_ALL_TOWNS = Boolean.parseBoolean(L2JModSettings.getProperty("TownWarAllTowns", "False"));
+					TW_AUTO_EVENT = Boolean.parseBoolean(L2JModSettings.getProperty("TownWarAutoEvent", "False"));
+					TW_INTERVAL = L2JModSettings.getProperty("TownWarInterval", "20:00").split(",");
+					TW_TIME_BEFORE_START = Integer.parseInt(L2JModSettings.getProperty("TownWarTimeBeforeStart", "5"));
+					TW_RUNNING_TIME = Integer.parseInt(L2JModSettings.getProperty("TownWarRunningTime", "10"));
+					TW_ITEM_ID = Integer.parseInt(L2JModSettings.getProperty("TownWarItemId", "57"));
+					TW_ITEM_AMOUNT = Integer.parseInt(L2JModSettings.getProperty("TownWarItemAmount", "5000"));
+					TW_GIVE_PVP_AND_PK_POINTS = Boolean.parseBoolean(L2JModSettings.getProperty("TownWarGivePvPAndPkPoints", "False"));
+					TW_ALLOW_KARMA = Boolean.parseBoolean(L2JModSettings.getProperty("TownWarAllowKarma", "False"));
+					TW_DISABLE_GK = Boolean.parseBoolean(L2JModSettings.getProperty("TownWarDisableGK", "False"));
+					TW_RESS_ON_DEATH = Boolean.parseBoolean(L2JModSettings.getProperty("TownWarRessOnDeath", "True"));
+					TW_RANDOM_SPAWN = Boolean.parseBoolean(L2JModSettings.getProperty("TownWarRandomSpawn", "True"));
+					TW_LOSE_BUFFS_ON_DEATH = Boolean.parseBoolean(L2JModSettings.getProperty("TownWarLoseBuffsOnDeath", "False"));
+
 					BANKING_SYSTEM_ENABLED = Boolean.parseBoolean(L2JModSettings.getProperty("BankingEnabled", "false"));
 					BANKING_SYSTEM_GOLDBARS = Integer.parseInt(L2JModSettings.getProperty("BankingGoldbarCount", "1"));
 					BANKING_SYSTEM_ADENA = Integer.parseInt(L2JModSettings.getProperty("BankingAdenaCount", "500000000"));
Index: java/com/l2jserver/gameserver/instancemanager/MapRegionManager.java
===================================================================
--- java/com/l2jserver/gameserver/instancemanager/MapRegionManager.java	(revision 5253)
+++ java/com/l2jserver/gameserver/instancemanager/MapRegionManager.java	(working copy)
@@ -469,7 +469,11 @@
 		{
 			L2RespawnZone zone = ZoneManager.getInstance().getZone(activeChar, L2RespawnZone.class);
 			if (zone != null)
+        {
+            if (Config.TW_RANDOM_SPAWN && activeChar.isInTownWarEvent())
+                return getRestartRegion(activeChar, zone.getRespawnPoint((L2PcInstance) activeChar)).getRandomLoc();
 				return getRestartRegion(activeChar, zone.getRespawnPoint((L2PcInstance) activeChar)).getSpawnLoc();
+        }
 			return getMapRegion(activeChar).getSpawnLoc();
 		}
 		catch (Exception e)
Index: java/com/l2jserver/gameserver/model/L2MapRegion.java
===================================================================
--- java/com/l2jserver/gameserver/model/L2MapRegion.java	(revision 5253)
+++ java/com/l2jserver/gameserver/model/L2MapRegion.java	(working copy)
@@ -140,7 +140,12 @@
 	{
 		return _spawnLocs;
 	}
-	
+
+	public final Location getRandomLoc() // For the Town War Event
+	{
+		return _spawnLocs.get(Rnd.get(_spawnLocs.size()));
+	}
+
 	public final Location getSpawnLoc()
 	{
 		if (Config.RANDOM_RESPAWN_IN_TOWN_ENABLED)
Index: java/com/l2jserver/gameserver/network/clientpackets/RequestRestartPoint.java
===================================================================
--- java/com/l2jserver/gameserver/network/clientpackets/RequestRestartPoint.java	(revision 5253)
+++ java/com/l2jserver/gameserver/network/clientpackets/RequestRestartPoint.java	(working copy)
@@ -134,7 +134,10 @@
 					_log.warning("Player ["+activeChar.getName()+"] called RestartPointPacket - To Clanhall and he doesn't have Clanhall!");
 					return;
 				}
-				loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, MapRegionManager.TeleportWhereType.ClanHall);
+					if (activeChar.isInTownWarEvent())
+						loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, MapRegionManager.TeleportWhereType.Town);
+					else
+						loc = MapRegionManager.getInstance().getTeleToLocation(activeChar, MapRegionManager.TeleportWhereType.ClanHall);
 				
 				if (ClanHallManager.getInstance().getClanHallByOwner(activeChar.getClan())!= null &&
 						ClanHallManager.getInstance().getClanHallByOwner(activeChar.getClan()).getFunction(ClanHall.FUNC_RESTORE_EXP) != null)
Index: java/com/l2jserver/gameserver/model/actor/L2Character.java
===================================================================
--- java/com/l2jserver/gameserver/model/actor/L2Character.java	(revision 5253)
+++ java/com/l2jserver/gameserver/model/actor/L2Character.java	(working copy)
@@ -232,6 +232,8 @@
 	private final byte[] _zones = new byte[23];
 	protected byte _zoneValidateCounter = 4;
 	
+	private boolean _isInTownWar;
+	
 	private L2Character _debugger = null;
 	
 	private final ReentrantLock _teleportLock;
@@ -670,6 +672,12 @@
 	 */
 	public void teleToLocation(int x, int y, int z, int heading, int randomOffset)
 	{
+		if (Config.TW_DISABLE_GK && isInTownWarEvent() && !isPendingRevive())
+		{
+			sendMessage("You can't teleport during Town War Event.");
+			return;
+		}
+
 		// Stop movement
 		stopMove(null, false);
 		abortAttack();
@@ -2200,7 +2208,7 @@
 			}
 			else if (!region.checkEffectRangeInsidePeaceZone(skill, getX(), getY(), getZ()))
 				canCast = false;
-			if (!canCast)
+			if (!canCast && !isInTownWarEvent())
 			{
 				SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_CANNOT_BE_USED);
 				sm.addSkillName(skill);
@@ -2352,7 +2360,7 @@
 			if (((L2Playable) this).getCharmOfLuck()) //remove Lucky Charm if player have Nobless blessing buff
 				((L2Playable) this).stopCharmOfLuck(null);
 		}
-		else
+		else if (!isInTownWarEvent() || Config.TW_LOSE_BUFFS_ON_DEATH)
 			stopAllEffectsExceptThoseThatLastThroughDeath();
 		
 		if (this instanceof L2PcInstance && ((L2PcInstance) this).getAgathionId() != 0)
@@ -5756,7 +5764,7 @@
 	@Override
 	public void onForcedAttack(L2PcInstance player)
 	{
-		if (isInsidePeaceZone(player))
+		if (isInsidePeaceZone(player) && !player.allowPeaceAttack())
 		{
 			// If L2Character or target is in a peace zone, send a system message TARGET_IN_PEACEZONE a Server->Client packet ActionFailed
 			player.sendPacket(SystemMessageId.TARGET_IN_PEACEZONE);
@@ -5778,7 +5786,7 @@
 				return;
 			}
 		}
-		if (player.getTarget() != null && !player.getTarget().isAttackable() && !player.getAccessLevel().allowPeaceAttack())
+		if (player.getTarget() != null && !player.getTarget().isAttackable() && !player.allowPeaceAttack())
 		{
 			// If target is not attackable, send a Server->Client packet ActionFailed
 			player.sendPacket(ActionFailed.STATIC_PACKET);
@@ -5817,7 +5825,7 @@
 	
 	public boolean isInsidePeaceZone(L2PcInstance attacker, L2Object target)
 	{
-		return (!attacker.getAccessLevel().allowPeaceAttack() && isInsidePeaceZone((L2Object) attacker, target));
+		return (!attacker.allowPeaceAttack() && isInsidePeaceZone((L2Object) attacker, target));
 	}
 	
 	public boolean isInsidePeaceZone(L2Object attacker, L2Object target)
@@ -5828,6 +5836,11 @@
 			return false;
 		if (InstanceManager.getInstance().getInstance(this.getInstanceId()).isPvPInstance())
 			return false;
+
+		if (attacker instanceof L2Summon && target.getActingPlayer() != null
+				&& target.getActingPlayer().isInTownWarEvent()
+				&& !target.getActingPlayer().getClient().isDetached())
+			return false;
 		
 		if (TerritoryWarManager.PLAYER_WITH_WARD_CAN_BE_KILLED_IN_PEACEZONE && TerritoryWarManager.getInstance().isTWInProgress())
 		{
@@ -6380,7 +6393,7 @@
 						sendPacket(SystemMessageId.DIST_TOO_FAR_CASTING_STOPPED);
 					else if (_skipgeo > 0)
 						sendPacket(SystemMessageId.CANT_SEE_TARGET);
-					else if (_skippeace > 0)
+					else if (_skippeace > 0 && ((L2PcInstance)this).allowPeaceAttack())
 						sendPacket(SystemMessageId.A_MALICIOUS_SKILL_CANNOT_BE_USED_IN_PEACE_ZONE);
 				}
 				abortCast();
@@ -7627,6 +7640,16 @@
 		return _effects.isAffected(flag);
 	}
 	
+	public boolean isInTownWarEvent()
+	{
+		return _isInTownWar;
+	}
+	
+	public void setInTownWarEvent(boolean value)
+	{
+		_isInTownWar = value;
+	}
+	
 	public void broadcastSocialAction(int id)
 	{
 		broadcastPacket(new SocialAction(getObjectId(), id));
Index: java/com/l2jserver/gameserver/network/clientpackets/RequestActionUse.java
===================================================================
--- java/com/l2jserver/gameserver/network/clientpackets/RequestActionUse.java	(revision 5253)
+++ java/com/l2jserver/gameserver/network/clientpackets/RequestActionUse.java	(working copy)
@@ -201,7 +201,7 @@
 						return;
 					}
 					
-					if (!activeChar.getAccessLevel().allowPeaceAttack() && activeChar.isInsidePeaceZone(pet, target))
+					if (!activeChar.allowPeaceAttack() && activeChar.isInsidePeaceZone(pet, target))
 					{
 						activeChar.sendPacket(SystemMessageId.TARGET_IN_PEACEZONE);
 						return;
Index: java/com/l2jserver/gameserver/model/actor/L2Playable.java
===================================================================
--- java/com/l2jserver/gameserver/model/actor/L2Playable.java	(revision 5253)
+++ java/com/l2jserver/gameserver/model/actor/L2Playable.java	(working copy)
@@ -14,6 +14,7 @@
  */
 package com.l2jserver.gameserver.model.actor;
 
+import com.l2jserver.Config;
 import com.l2jserver.gameserver.ai.CtrlEvent;
 import com.l2jserver.gameserver.model.CharEffectList;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
@@ -138,7 +139,7 @@
 			if (getCharmOfLuck()) //remove Lucky Charm if player have Nobless blessing buff
 				stopCharmOfLuck(null);
 		}
-		else
+		else if (!isInTownWarEvent() || Config.TW_LOSE_BUFFS_ON_DEATH)
 			stopAllEffectsExceptThoseThatLastThroughDeath();
 		
 		// Send the Server->Client packet StatusUpdate with current HP and MP to all other L2PcInstance to inform
Index: java/com/l2jserver/gameserver/model/skills/L2Skill.java
===================================================================
--- java/com/l2jserver/gameserver/model/skills/L2Skill.java	(revision 5253)
+++ java/com/l2jserver/gameserver/model/skills/L2Skill.java	(working copy)
@@ -1464,7 +1464,7 @@
 						&& player.getSiegeSide() == targetPlayer.getSiegeSide())
 					return false;
 				
-				if (skill.isOffensive() && target.isInsideZone(L2Character.ZONE_PEACE))
+				if (skill.isOffensive() && target.isInsideZone(L2Character.ZONE_PEACE) && !player.allowPeaceAttack())
 					return false;
 				
 				if (player.isInParty() && targetPlayer.isInParty())
Index: java/com/l2jserver/gameserver/model/actor/L2Summon.java
===================================================================
--- java/com/l2jserver/gameserver/model/actor/L2Summon.java	(revision 5253)
+++ java/com/l2jserver/gameserver/model/actor/L2Summon.java	(working copy)
@@ -669,7 +669,7 @@
 		// Check if this is offensive magic skill
 		if (skill.isOffensive())
 		{
-			if (isInsidePeaceZone(this, target) && getOwner() != null && (!getOwner().getAccessLevel().allowPeaceAttack()))
+			if (isInsidePeaceZone(this, target) && getOwner() != null && !getOwner().allowPeaceAttack())
 			{
 				// If summon or target is in a peace zone, send a system message TARGET_IN_PEACEZONE
 				sendPacket(SystemMessageId.TARGET_IN_PEACEZONE);
@@ -702,7 +702,7 @@
 			}
 			else
 			{
-				if (!target.isAttackable() && getOwner() != null && (!getOwner().getAccessLevel().allowPeaceAttack()))
+				if (!target.isAttackable() && getOwner() != null && !getOwner().allowPeaceAttack())
 				{
 					return false;
 				}
@@ -798,7 +798,7 @@
 	{
 		final L2PcInstance actingPlayer = getActingPlayer();
 		
-		if (!actingPlayer.checkPvpSkill(getTarget(), skill, true) && !actingPlayer.getAccessLevel().allowPeaceAttack())
+		if (!actingPlayer.checkPvpSkill(getTarget(), skill, true) && !actingPlayer.allowPeaceAttack())
 		{
 			// Send a System Message to the L2PcInstance
 			actingPlayer.sendPacket(SystemMessageId.TARGET_IS_INCORRECT);

CitarDATA:

### Eclipse Workspace Patch 1.0
#P L2J_DataPack_BETA
Index: dist/game/data/scripts/handlers/admincommandhandlers/AdminTownWar.java
===================================================================
--- dist/game/data/scripts/handlers/admincommandhandlers/AdminTownWar.java	(revision 0)
+++ dist/game/data/scripts/handlers/admincommandhandlers/AdminTownWar.java	(working copy)
@@ -0,0 +1,98 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package handlers.admincommandhandlers;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.Announcements;
+import com.l2jserver.gameserver.handler.IAdminCommandHandler;
+import com.l2jserver.gameserver.instancemanager.TownManager;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * @author SolidSnake, mrTJO
+ */
+public class AdminTownWar implements IAdminCommandHandler
+{
+	private static final String[] ADMIN_COMMANDS = {
+		"admin_townwar_start",
+		"admin_townwar_end"
+	};
+	
+	private static final int ALL_TOWNS_INT = 17;
+	
+	@Override
+	public boolean useAdminCommand(String command, L2PcInstance activeChar)
+	{
+		if (command.startsWith("admin_townwar_start"))
+		{
+			startTownWar();
+		}
+		if (command.startsWith("admin_townwar_end"))
+		{
+			endTownWar();
+		}
+		return true;
+	}
+	
+	private void startTownWar()
+	{
+		if (Config.TW_ALL_TOWNS)
+		{
+			for (int i = 1; i <= ALL_TOWNS_INT; i++)
+			{
+				TownManager.getTown(i).setIsTWZone(true);
+				TownManager.getTown(i).updateForCharactersInside();
+			}
+			TownManager.getTown(20).setIsTWZone(true);
+			TownManager.getTown(20).updateForCharactersInside();
+			Announcements.getInstance().announceToAll("Town War: All towns are war zone.");
+		}
+		else
+		{
+			TownManager.getTown(Config.TW_TOWN_ID).setIsTWZone(true);
+			TownManager.getTown(Config.TW_TOWN_ID).updateForCharactersInside();
+			Announcements.getInstance().announceToAll("Town War Event Starting.");
+			Announcements.getInstance().announceToAll("" + Config.TW_TOWN_NAME + " is now a war zone.");
+		}
+	}
+	
+	private void endTownWar()
+	{
+		if (Config.TW_ALL_TOWNS)
+		{
+			for (int i = 1; i <= ALL_TOWNS_INT; i++)
+			{
+				TownManager.getTown(i).setIsTWZone(false);
+				TownManager.getTown(i).updateForCharactersInside();
+			}
+			TownManager.getTown(20).setIsTWZone(false);
+			TownManager.getTown(20).updateForCharactersInside();
+			Announcements.getInstance().announceToAll("Town War: All towns are returned normal.");
+		}
+		else
+		{
+			TownManager.getTown(Config.TW_TOWN_ID).setIsTWZone(false);
+			TownManager.getTown(Config.TW_TOWN_ID).updateForCharactersInside();
+			Announcements.getInstance().announceToAll("Town War Event Finished.");
+			Announcements.getInstance().announceToAll("" + Config.TW_TOWN_NAME + " has been set to peace zone.");
+		}
+	}
+	
+	@Override
+	public String[] getAdminCommandList()
+	{
+		return ADMIN_COMMANDS;
+	}
+}
\ No newline at end of file
Index: dist/game/data/scripts/handlers/MasterHandler.java
===================================================================
--- dist/game/data/scripts/handlers/MasterHandler.java	(revision 8771)
+++ dist/game/data/scripts/handlers/MasterHandler.java	(working copy)
@@ -98,6 +98,7 @@
 import handlers.admincommandhandlers.AdminTeleport;
 import handlers.admincommandhandlers.AdminTerritoryWar;
 import handlers.admincommandhandlers.AdminTest;
+import handlers.admincommandhandlers.AdminTownWar;
 import handlers.admincommandhandlers.AdminTvTEvent;
 import handlers.admincommandhandlers.AdminUnblockIp;
 import handlers.admincommandhandlers.AdminVitality;
@@ -425,6 +426,7 @@
 			AdminTeleport.class,
 			AdminTerritoryWar.class,
 			AdminTest.class,
+			AdminTownWar.class,
 			AdminTvTEvent.class,
 			AdminUnblockIp.class,
 			AdminVitality.class,