BiggBoss 13 лет назад
Родитель
Сommit
f814936f7c
44 измененных файлов с 1975 добавлено и 398 удалено
  1. 23 0
      L2J_Server_BETA/dist/game/config/ConquerableHallSiege.properties
  2. 27 0
      L2J_Server_BETA/java/com/l2jserver/Config.java
  3. 2 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/GameServer.java
  4. 4 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/Shutdown.java
  5. 11 8
      L2J_Server_BETA/java/com/l2jserver/gameserver/ai/L2SiegeGuardAI.java
  6. 52 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/ai/L2SpecialSiegeGuardAI.java
  7. 17 8
      L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/DoorTable.java
  8. 196 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/instancemanager/CHSiegeManager.java
  9. 87 47
      L2J_Server_BETA/java/com/l2jserver/gameserver/instancemanager/ClanHallManager.java
  10. 13 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/instancemanager/MapRegionManager.java
  11. 3 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/instancemanager/TerritoryWarManager.java
  12. 7 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Npc.java
  13. 8 8
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2AuctioneerInstance.java
  14. 27 7
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2CastleDoormenInstance.java
  15. 43 19
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2ClanHallManagerInstance.java
  16. 20 8
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2DefenderInstance.java
  17. 13 4
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2DoorInstance.java
  18. 6 11
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2SiegeFlagInstance.java
  19. 11 2
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2SiegeNpcInstance.java
  20. 15 2
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2WyvernManagerInstance.java
  21. 5 2
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/knownlist/DefenderKnownList.java
  22. 1 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/Auction.java
  23. 32 195
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/ClanHall.java
  24. 3 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/FortSiege.java
  25. 2 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/Siegable.java
  26. 3 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/Siege.java
  27. 214 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/clanhall/AuctionableHall.java
  28. 521 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/clanhall/ClanHallSiegeEngine.java
  29. 272 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/clanhall/SiegableHall.java
  30. 26 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/clanhall/SiegeStatus.java
  31. 22 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/quest/Quest.java
  32. 7 2
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/zone/type/L2ClanHallZone.java
  33. 8 2
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/zone/type/L2SiegeZone.java
  34. 16 2
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/EnterWorld.java
  35. 32 11
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestJoinSiege.java
  36. 6 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestRestartPoint.java
  37. 16 3
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestSiegeAttackerList.java
  38. 3 2
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/AgitDecoInfo.java
  39. 5 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/Die.java
  40. 3 3
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/ExShowAgitInfo.java
  41. 73 25
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/SiegeAttackerList.java
  42. 66 19
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/SiegeInfo.java
  43. 41 3
      L2J_Server_BETA/java/com/l2jserver/gameserver/skills/l2skills/L2SkillSiegeFlag.java
  44. 13 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/templates/item/L2Item.java

+ 23 - 0
L2J_Server_BETA/dist/game/config/ConquerableHallSiege.properties

@@ -0,0 +1,23 @@
+# --------------------------------------------------
+# Contestable halls general configuration
+# --------------------------------------------------
+# Min level that each clan needs to register
+# for the siege
+MinClanLevel = 4
+
+# Max number of clans allowed to register for
+# the battle
+MaxAttackers = 500
+
+# Max numbers of flags that each clan is allowed
+# to put
+MaxFlagsPerClan = 1
+
+# Enable the fame reward
+EnableFame = false
+
+# Fame amount
+FameAmount = 0
+
+# Fame Frequency
+FameFrequency = 0

+ 27 - 0
L2J_Server_BETA/java/com/l2jserver/Config.java

@@ -83,6 +83,7 @@ public final class Config
 	public static final String CHAT_FILTER_FILE = "./config/chatfilter.txt";
 	public static final String SECURITY_CONFIG_FILE = "./config/security.properties";
 	public static final String EMAIL_CONFIG_FILE = "./config/email.properties";
+	public static final String CH_SIEGE_FILE = "./config/ConquerableHallSiege.properties";
 	
 	
 	//--------------------------------------------------
@@ -1076,6 +1077,15 @@ public final class Config
 	public static String EMAIL_SYS_SELECTQUERY;
 	public static String EMAIL_SYS_DBFIELD;
 	
+	// Conquerable Halls Settings
+	public static int CHS_CLAN_MINLEVEL;
+	public static int CHS_MAX_ATTACKERS;
+	public static int CHS_MAX_FLAGS_PER_CLAN;
+	public static boolean CHS_ENABLE_FAME;
+	public static int CHS_FAME_AMOUNT;
+	public static int CHS_FAME_FREQUENCY;
+
+	
 	/**
 	 * This class initializes all global variables for configuration.<br>
 	 * If the key doesn't appear in properties file, a default value is set by this class.
@@ -2996,6 +3006,23 @@ public final class Config
 					e.printStackTrace();
 					throw new Error("Failed to Load " + EMAIL_CONFIG_FILE + " File.");
 				}
+				try
+				{
+					L2Properties chSiege = new L2Properties();
+					is = new FileInputStream(new File(CH_SIEGE_FILE));
+					chSiege.load(is);
+					
+					CHS_MAX_ATTACKERS = Integer.parseInt(chSiege.getProperty("MaxAttackers", "500"));
+					CHS_CLAN_MINLEVEL = Integer.parseInt(chSiege.getProperty("MinClanLevel", "4"));
+					CHS_MAX_FLAGS_PER_CLAN = Integer.parseInt(chSiege.getProperty("MaxFlagsPerClan", "1"));
+					CHS_ENABLE_FAME = Boolean.parseBoolean(chSiege.getProperty("EnableFame", "false"));
+					CHS_FAME_AMOUNT = Integer.parseInt(chSiege.getProperty("FameAmount", "0"));
+					CHS_FAME_FREQUENCY = Integer.parseInt(chSiege.getProperty("FameFrequency", "0"));
+				}
+				catch(Exception e)
+				{
+					e.printStackTrace();
+				}
 			}
 			finally
 			{

+ 2 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/GameServer.java

@@ -85,6 +85,7 @@ import com.l2jserver.gameserver.instancemanager.AirShipManager;
 import com.l2jserver.gameserver.instancemanager.AntiFeedManager;
 import com.l2jserver.gameserver.instancemanager.AuctionManager;
 import com.l2jserver.gameserver.instancemanager.BoatManager;
+import com.l2jserver.gameserver.instancemanager.CHSiegeManager;
 import com.l2jserver.gameserver.instancemanager.CastleManager;
 import com.l2jserver.gameserver.instancemanager.CastleManorManager;
 import com.l2jserver.gameserver.instancemanager.ClanHallManager;
@@ -250,6 +251,7 @@ public class GameServer
 		
 		printSection("Clans");
 		ClanTable.getInstance();
+		CHSiegeManager.getInstance();
 		ClanHallManager.getInstance();
 		AuctionManager.getInstance();
 		

+ 4 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/Shutdown.java

@@ -23,6 +23,7 @@ import com.l2jserver.Config;
 import com.l2jserver.L2DatabaseFactory;
 import com.l2jserver.gameserver.datatables.ClanTable;
 import com.l2jserver.gameserver.datatables.OfflineTradersTable;
+import com.l2jserver.gameserver.instancemanager.CHSiegeManager;
 import com.l2jserver.gameserver.instancemanager.CastleManorManager;
 import com.l2jserver.gameserver.instancemanager.CursedWeaponsManager;
 import com.l2jserver.gameserver.instancemanager.GlobalVariablesManager;
@@ -568,6 +569,9 @@ public class Shutdown extends Thread
 		CastleManorManager.getInstance().save();
 		_log.info("Castle Manor Manager: Data saved("+tc.getEstimatedTimeAndRestartCounter()+"ms).");
 		
+		CHSiegeManager.getInstance().onServerShutDown();
+		_log.info("CHSiegeManager: Siegable hall attacker lists saved!");
+		
 		// Save all global (non-player specific) Quest data that needs to persist after reboot
 		QuestManager.getInstance().save();
 		_log.info("Quest Manager: Data saved("+tc.getEstimatedTimeAndRestartCounter()+"ms).");

+ 11 - 8
L2J_Server_BETA/java/com/l2jserver/gameserver/ai/L2SiegeGuardAI.java

@@ -121,7 +121,7 @@ public class L2SiegeGuardAI extends L2CharacterAI implements Runnable
 	 * @param target The targeted L2Object
 	 *
 	 */
-	private boolean autoAttackCondition(L2Character target)
+	protected boolean autoAttackCondition(L2Character target)
 	{
 		// Check if the target isn't another guard, folk or a door
 		if (target == null || target instanceof L2DefenderInstance || target instanceof L2NpcInstance || target instanceof L2DoorInstance
@@ -384,7 +384,7 @@ public class L2SiegeGuardAI extends L2CharacterAI implements Runnable
 			
 			if (!(cha instanceof L2Npc))
 			{
-				if (_selfAnalysis.hasHealOrResurrect && cha instanceof L2PcInstance && ((L2Npc) _actor).getCastle().getSiege().checkIsDefender(((L2PcInstance) cha).getClan()))
+				if (_selfAnalysis.hasHealOrResurrect && cha instanceof L2PcInstance && (((L2Npc) _actor).getCastle().getSiege().checkIsDefender(((L2PcInstance) cha).getClan())))
 				{
 					// heal friends
 					if (!_actor.isAttackingDisabled() && cha.getCurrentHp() < cha.getMaxHp() * 0.6 && _actor.getCurrentHp() > _actor.getMaxHp() / 2 && _actor.getCurrentMp() > _actor.getMaxMp() / 2 && cha.isInCombat())
@@ -491,13 +491,16 @@ public class L2SiegeGuardAI extends L2CharacterAI implements Runnable
 		}
 		
 		// never attack defenders
-		if (attackTarget instanceof L2PcInstance && sGuard.getCastle().getSiege().checkIsDefender(((L2PcInstance) attackTarget).getClan()))
+		if (attackTarget instanceof L2PcInstance) 
 		{
-			// Cancel the target
-			sGuard.stopHating(attackTarget);
-			_actor.setTarget(null);
-			setIntention(AI_INTENTION_IDLE, null, null);
-			return;
+			if(sGuard.getConquerableHall() == null && sGuard.getCastle().getSiege().checkIsDefender(((L2PcInstance) attackTarget).getClan()))
+			{	
+				// Cancel the target
+				sGuard.stopHating(attackTarget);
+				_actor.setTarget(null);
+				setIntention(AI_INTENTION_IDLE, null, null);
+				return;
+			}
 		}
 		
 		if (!GeoData.getInstance().canSeeTarget(_actor, attackTarget))

+ 52 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/ai/L2SpecialSiegeGuardAI.java

@@ -0,0 +1,52 @@
+/*
+ * 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.ai;
+
+import java.util.ArrayList;
+
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.actor.L2Character.AIAccessor;
+
+/**
+ * @author BiggBoss
+ *
+ */
+public final class L2SpecialSiegeGuardAI extends L2SiegeGuardAI
+{
+	private ArrayList<Integer> _allied;
+	
+	/**
+	 * @param accessor
+	 */
+	public L2SpecialSiegeGuardAI(AIAccessor accessor)
+	{
+		super(accessor);
+		_allied = new ArrayList<Integer>();
+	}
+	
+	public ArrayList<Integer> getAlly()
+	{
+		return _allied;
+	}
+	
+	@Override
+	protected boolean autoAttackCondition(L2Character target)
+	{
+		if(_allied.contains(target.getObjectId()))
+			return false;
+		
+		return super.autoAttackCondition(target);
+	}
+}

+ 17 - 8
L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/DoorTable.java

@@ -34,6 +34,7 @@ import com.l2jserver.gameserver.instancemanager.InstanceManager;
 import com.l2jserver.gameserver.instancemanager.MapRegionManager;
 import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
 import com.l2jserver.gameserver.model.entity.ClanHall;
+import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
 import com.l2jserver.gameserver.pathfinding.AbstractNodeLoc;
 import com.l2jserver.gameserver.templates.StatsSet;
 import com.l2jserver.gameserver.templates.chars.L2CharTemplate;
@@ -89,14 +90,6 @@ public class DoorTable
 				L2DoorInstance door = parseList(line, false);
 				putDoor(door);
 				door.spawnMe(door.getX(), door.getY(), door.getZ());
-				ClanHall clanhall = ClanHallManager.getInstance().getNearbyClanHall(door.getX(), door.getY(), 500);
-				if (clanhall != null)
-				{
-					clanhall.getDoors().add(door);
-					door.setClanHall(clanhall);
-					if (Config.DEBUG)
-						_log.info("door " + door.getDoorName() + " attached to ch " + clanhall.getName());
-				}
 			}
 			
 			_log.info("DoorTable: Loaded " + _staticItems.size() + " Door Templates for " + _regions.size() + " regions.");
@@ -159,6 +152,9 @@ public class DoorTable
 			boolean targetable = true;
 			if (st.hasMoreTokens())
 				targetable = Boolean.parseBoolean(st.nextToken());
+			int hallId = 0;
+			if(st.hasMoreTokens())
+				hallId = Integer.parseInt(st.nextToken());
 
 			if (rangeXMin > rangeXMax)
 				_log.severe("Error in door data, XMin > XMax, ID:" + id);
@@ -226,6 +222,19 @@ public class DoorTable
 			door.setEmitter(emitter);
 			door.setTargetable(targetable);
 			
+			if(hallId > 0)
+			{
+				ClanHall hall = ClanHallManager.getAllClanHalls().get(hallId);
+				if(hall != null)
+				{
+					door.setClanHall(hall);
+					hall.getDoors().add(door);
+					
+					if(hall.isSiegableHall())
+						((SiegableHall)hall).getDoorDefault().add(line);
+				}
+			}
+			
 			if (commanderDoor)
 				door.setIsCommanderDoor(startOpen);
 			else

+ 196 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/instancemanager/CHSiegeManager.java

@@ -0,0 +1,196 @@
+/*
+ * 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.instancemanager;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import com.l2jserver.Config;
+import com.l2jserver.L2DatabaseFactory;
+import com.l2jserver.gameserver.model.L2Clan;
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.clanhall.ClanHallSiegeEngine;
+import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
+import com.l2jserver.gameserver.model.zone.type.L2ClanHallZone;
+import com.l2jserver.gameserver.network.SystemMessageId;
+import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.gameserver.templates.StatsSet;
+
+import javolution.util.FastMap;
+
+/**
+ * @author BiggBoss
+ */
+public final class CHSiegeManager
+{
+	private static final Logger _log = Logger.getLogger(CHSiegeManager.class.getName());
+	private static final String SQL_LOAD_HALLS = "SELECT * FROM siegable_clanhall";
+	
+	private static final class SingletonHolder
+	{
+		private static final CHSiegeManager INSTANCE = new CHSiegeManager();
+	}
+	
+	private FastMap<Integer, SiegableHall> _siegableHalls = new FastMap<Integer, SiegableHall>();
+	
+	private CHSiegeManager()
+	{
+		_log.info("Initializing CHSiegeManager...");
+		loadClanHalls();
+	}
+	
+	public static CHSiegeManager getInstance()
+	{
+		return SingletonHolder.INSTANCE;
+	}
+	
+	private final void loadClanHalls()
+	{
+		Connection con = null;
+		try
+		{
+			con = L2DatabaseFactory.getInstance().getConnection();
+			PreparedStatement statement = con.prepareStatement(SQL_LOAD_HALLS);
+			ResultSet rs = statement.executeQuery();
+			
+			_siegableHalls.clear();
+			
+			while(rs.next())
+			{
+				final int id = rs.getInt("clanHallId");
+				
+				StatsSet set = new StatsSet();
+				
+				set.set("id", id);
+				set.set("name", rs.getString("name"));
+				set.set("ownerId", rs.getInt("ownerId"));
+				set.set("desc", rs.getString("desc"));
+				set.set("location", rs.getString("location"));
+				set.set("nextSiege", rs.getLong("nextSiege"));
+				set.set("siegeLenght", rs.getLong("siegeLenght"));
+				set.set("scheduleConfig", rs.getString("schedule_config"));
+				SiegableHall hall = new SiegableHall(set);
+				_siegableHalls.put(id, hall);
+				ClanHallManager.addClanHall(hall);
+			}
+			_log.config("CHSiegeManager: Loaded "+_siegableHalls.size()+" conquerable clan halls");
+			rs.close();
+			statement.close();
+		}
+		catch(Exception e)
+		{
+			_log.warning("CHSiegeManager: Could not load siegable clan halls!:");
+			e.printStackTrace();
+		}
+		finally
+		{
+			L2DatabaseFactory.close(con);
+		}
+	}
+	
+	public FastMap<Integer, SiegableHall> getConquerableHalls()
+	{
+		return _siegableHalls;
+	}
+	
+	
+	public SiegableHall getSiegableHall(int clanHall)
+	{
+		return getConquerableHalls().get(clanHall);
+	}
+	
+	public final SiegableHall getNearbyClanHall(L2Character activeChar)
+	{
+		return getNearbyClanHall(activeChar.getX(), activeChar.getY(), 10000);
+	}
+	
+	public final SiegableHall getNearbyClanHall(int x, int y, int maxDist)
+	{
+		L2ClanHallZone zone = null;
+		
+		for (Map.Entry<Integer, SiegableHall> ch : _siegableHalls.entrySet())
+		{
+			zone = ch.getValue().getZone();
+			if (zone != null && zone.getDistanceToZone(x, y) < maxDist)
+				return ch.getValue();
+		}
+		return null;
+	}
+	
+	public final ClanHallSiegeEngine getSiege(L2Character character)
+	{
+		SiegableHall hall = getNearbyClanHall(character);
+		if(hall == null)
+			return null;
+		return hall.getSiege();
+	}
+	
+	public final void registerClan(L2Clan clan, SiegableHall hall, L2PcInstance player)
+	{
+		if(clan.getLevel() < Config.CHS_CLAN_MINLEVEL)
+			player.sendMessage("Only clans of level "+Config.CHS_CLAN_MINLEVEL+" or higher may register for a castle siege");
+		else if(hall.isWaitingBattle())
+		{
+			SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.DEADLINE_FOR_SIEGE_S1_PASSED);
+			sm.addString(hall.getName());
+			player.sendPacket(sm);
+		}
+		else if(hall.isInSiege())
+			player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.NOT_SIEGE_REGISTRATION_TIME2));
+		else if(hall.getOwnerId() == clan.getClanId())
+			player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.CLAN_THAT_OWNS_CASTLE_IS_AUTOMATICALLY_REGISTERED_DEFENDING));
+		else if(clan.getHasCastle() != 0 || clan.getHasHideout() != 0)
+			player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.CLAN_THAT_OWNS_CASTLE_CANNOT_PARTICIPATE_OTHER_SIEGE));
+		else if(hall.getSiege().checkIsAttacker(clan))
+			player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.ALREADY_REQUESTED_SIEGE_BATTLE));
+		else if(isClanParticipating(clan))
+			player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.APPLICATION_DENIED_BECAUSE_ALREADY_SUBMITTED_A_REQUEST_FOR_ANOTHER_SIEGE_BATTLE));
+		else if(hall.getAttackers().size() >= Config.CHS_MAX_ATTACKERS)
+			player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.ATTACKER_SIDE_FULL));
+		else
+			hall.addAttacker(clan);
+	}
+	
+	public final void unRegisterClan(L2Clan clan, SiegableHall hall)
+	{
+		if(!hall.isRegistering())
+			return;
+		hall.removeAttacker(clan);
+	}
+	
+	public final boolean isClanParticipating(L2Clan clan)
+	{
+		for(SiegableHall hall : getConquerableHalls().values())
+			if(hall.getSiege() != null && hall.getSiege().checkIsAttacker(clan))
+				return true;
+		return false;
+	}
+	
+	public final void onServerShutDown()
+	{
+		for(SiegableHall hall : getConquerableHalls().values())
+		{
+			//Rainbow springs has his own attackers table
+			if(hall.getId() == 62 || hall.getSiege() == null)
+				continue;
+			
+			hall.getSiege().saveAttackers();
+		}
+	}
+}

+ 87 - 47
L2J_Server_BETA/java/com/l2jserver/gameserver/instancemanager/ClanHallManager.java

@@ -29,18 +29,22 @@ import com.l2jserver.gameserver.model.L2Clan;
 import com.l2jserver.gameserver.model.L2Object;
 import com.l2jserver.gameserver.model.entity.Auction;
 import com.l2jserver.gameserver.model.entity.ClanHall;
+import com.l2jserver.gameserver.model.entity.clanhall.AuctionableHall;
+import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
 import com.l2jserver.gameserver.model.zone.type.L2ClanHallZone;
+import com.l2jserver.gameserver.templates.StatsSet;
 
 /**
  * @author  Steuf
  */
-public class ClanHallManager
+public final class ClanHallManager
 {
 	protected static final Logger _log = Logger.getLogger(ClanHallManager.class.getName());
 	
-	private Map<Integer, ClanHall> _clanHall;
-	private Map<Integer, ClanHall> _freeClanHall;
-	private Map<Integer, ClanHall> _allClanHalls;
+	private Map<Integer, AuctionableHall> _clanHall;
+	private Map<Integer, AuctionableHall> _freeClanHall;
+	private Map<Integer, AuctionableHall> _allAuctionableClanHalls;
+	private static Map<Integer, ClanHall> _allClanHalls = new FastMap<Integer, ClanHall>();
 	private boolean _loaded = false;
 	
 	public static ClanHallManager getInstance()
@@ -56,9 +60,9 @@ public class ClanHallManager
 	private ClanHallManager()
 	{
 		_log.info("Initializing ClanHallManager");
-		_clanHall = new FastMap<Integer, ClanHall>();
-		_freeClanHall = new FastMap<Integer, ClanHall>();
-		_allClanHalls = new FastMap<Integer, ClanHall>();
+		_clanHall = new FastMap<Integer, AuctionableHall>();
+		_freeClanHall = new FastMap<Integer, AuctionableHall>();
+		_allAuctionableClanHalls = new FastMap<Integer, AuctionableHall>();
 		load();
 	}
 	
@@ -77,38 +81,35 @@ public class ClanHallManager
 		Connection con = null;
 		try
 		{
-			int id, ownerId, lease, grade = 0;
-			String Name, Desc, Location;
-			long paidUntil = 0;
-			boolean paid = false;
+			int id, ownerId, lease;
 			con = L2DatabaseFactory.getInstance().getConnection();
 			PreparedStatement statement = con.prepareStatement("SELECT * FROM clanhall ORDER BY id");
 			ResultSet rs = statement.executeQuery();
 			while (rs.next())
 			{
-				id = rs.getInt("id");
-				Name = rs.getString("name");
-				ownerId = rs.getInt("ownerId");
-				lease = rs.getInt("lease");
-				Desc = rs.getString("desc");
-				Location = rs.getString("location");
-				paidUntil = rs.getLong("paidUntil");
-				grade = rs.getInt("Grade");
-				paid = rs.getBoolean("paid");
+				StatsSet set = new StatsSet();
 				
-				ClanHall ch = new ClanHall(id, Name, ownerId, lease, Desc, Location, paidUntil, grade, paid);
-				_allClanHalls.put(id, ch);
+				id = rs.getInt("id");
+ 				ownerId = rs.getInt("ownerId");
+ 				lease = rs.getInt("lease");
+
+				set.set("id", id);
+				set.set("name", rs.getString("name"));
+				set.set("ownerId", ownerId);
+				set.set("lease", lease);
+				set.set("desc", rs.getString("desc"));
+				set.set("location", rs.getString("location"));
+				set.set("paidUntil", rs.getLong("paidUntil"));
+				set.set("grade", rs.getInt("Grade"));
+				set.set("paid", rs.getBoolean("paid"));
+				AuctionableHall ch = new AuctionableHall(set);
+				_allAuctionableClanHalls.put(id, ch);
+				addClanHall(ch);
 				
-				if (ownerId > 0)
+				if (ch.getOwnerId() > 0)
 				{
-					final L2Clan owner = ClanTable.getInstance().getClan(ownerId);
-					if (owner != null)
-					{
-						_clanHall.put(id, ch);
-						owner.setHasHideout(id);
-						continue;
-					}
-					ch.free();
+					_clanHall.put(id, ch);
+					continue;
 				}
 				_freeClanHall.put(id, ch);
 				
@@ -133,24 +134,34 @@ public class ClanHallManager
 		}
 	}
 	
+	public static final Map<Integer, ClanHall> getAllClanHalls()
+	{
+		return _allClanHalls;
+	}
+
 	/** Get Map with all FreeClanHalls */
-	public final Map<Integer, ClanHall> getFreeClanHalls()
+	public final Map<Integer, AuctionableHall> getFreeClanHalls()
 	{
 		return _freeClanHall;
 	}
 	
 	/** Get Map with all ClanHalls that have owner*/
-	public final Map<Integer, ClanHall> getClanHalls()
+	public final Map<Integer, AuctionableHall> getClanHalls()
 	{
 		return _clanHall;
 	}
 	
 	/** Get Map with all ClanHalls*/
-	public final Map<Integer, ClanHall> getAllClanHalls()
+	public final Map<Integer, AuctionableHall> getAllAuctionableClanHalls()
 	{
-		return _allClanHalls;
+		return _allAuctionableClanHalls;
 	}
 	
+	public static final void addClanHall(ClanHall hall)
+	{
+		_allClanHalls.put(hall.getId(), hall);
+	}
+
 	/** Check is free ClanHall */
 	public final boolean isFree(int chId)
 	{
@@ -185,18 +196,19 @@ public class ClanHallManager
 	/** Get Clan Hall by Id */
 	public final ClanHall getClanHallById(int clanHallId)
 	{
-		if (_clanHall.containsKey(clanHallId))
-			return _clanHall.get(clanHallId);
-		if (_freeClanHall.containsKey(clanHallId))
-			return _freeClanHall.get(clanHallId);
-		_log.warning("Clan hall id " + clanHallId + " not found in clanhall table!");
-		return null;
+		return _allClanHalls.get(clanHallId);
 	}
 	
+	public final AuctionableHall getAuctionableHallById(int clanHallId)
+	{
+		return _allAuctionableClanHalls.get(clanHallId);
+	}
+
+	
 	/** Get Clan Hall by x,y,z */
 	public final ClanHall getClanHall(int x, int y, int z)
 	{
-		for (ClanHall temp : getClanHalls().values())
+		for (ClanHall temp : getAllClanHalls().values())
 		{
 			if (temp.checkIfInZone(x, y, z))
 				return temp;
@@ -209,17 +221,17 @@ public class ClanHallManager
 		return getClanHall(activeObject.getX(), activeObject.getY(), activeObject.getZ());
 	}
 	
-	public final ClanHall getNearbyClanHall(int x, int y, int maxDist)
+	public final AuctionableHall getNearbyClanHall(int x, int y, int maxDist)
 	{
 		L2ClanHallZone zone = null;
 		
-		for (Map.Entry<Integer, ClanHall> ch : _clanHall.entrySet())
+		for (Map.Entry<Integer, AuctionableHall> ch : _clanHall.entrySet())
 		{
 			zone = ch.getValue().getZone();
 			if (zone != null && zone.getDistanceToZone(x, y) < maxDist)
 				return ch.getValue();
 		}
-		for (Map.Entry<Integer, ClanHall> ch : _freeClanHall.entrySet())
+		for (Map.Entry<Integer, AuctionableHall> ch : _freeClanHall.entrySet())
 		{
 			zone = ch.getValue().getZone();
 			if (zone != null && zone.getDistanceToZone(x, y) < maxDist)
@@ -228,14 +240,42 @@ public class ClanHallManager
 		return null;
 	}
 	
+	public final ClanHall getNearbyAbstractHall(int x, int y, int maxDist)
+	{
+		L2ClanHallZone zone = null;
+		for(Map.Entry<Integer, ClanHall> ch : _allClanHalls.entrySet())
+		{
+			zone = ch.getValue().getZone();
+			if(zone != null && zone.getDistanceToZone(x, y) < maxDist)
+				return ch.getValue();
+		}
+		return null;
+	}
+	
 	/** Get Clan Hall by Owner */
-	public final ClanHall getClanHallByOwner(L2Clan clan)
+	public final AuctionableHall getClanHallByOwner(L2Clan clan)
+	{
+		for (Map.Entry<Integer, AuctionableHall> ch : _clanHall.entrySet())
+		{
+			if (clan.getClanId() == ch.getValue().getOwnerId())
+				return ch.getValue();
+		}
+		return null;
+	}
+	
+	public final ClanHall getAbstractHallByOwner(L2Clan clan)
 	{
-		for (Map.Entry<Integer, ClanHall> ch : _clanHall.entrySet())
+		// Separate loops to avoid iterating over free clan halls
+		for (Map.Entry<Integer, AuctionableHall> ch : _clanHall.entrySet())
 		{
 			if (clan.getClanId() == ch.getValue().getOwnerId())
 				return ch.getValue();
 		}
+		for(Map.Entry<Integer, SiegableHall> ch : CHSiegeManager.getInstance().getConquerableHalls().entrySet())
+		{
+			if(clan.getClanId() == ch.getValue().getOwnerId())
+				return ch.getValue();
+		}
 		return null;
 	}
 	

+ 13 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/instancemanager/MapRegionManager.java

@@ -39,6 +39,7 @@ import com.l2jserver.gameserver.model.entity.Castle;
 import com.l2jserver.gameserver.model.entity.ClanHall;
 import com.l2jserver.gameserver.model.entity.Fort;
 import com.l2jserver.gameserver.model.entity.Instance;
+import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
 import com.l2jserver.gameserver.model.zone.type.L2ClanHallZone;
 import com.l2jserver.gameserver.model.zone.type.L2RespawnZone;
 import com.l2jserver.gameserver.util.Util;
@@ -295,7 +296,7 @@ public class MapRegionManager
 				// If teleport to clan hall
 				if (teleportWhere == TeleportWhereType.ClanHall)
 				{
-					clanhall = ClanHallManager.getInstance().getClanHallByOwner(player.getClan());
+					clanhall = ClanHallManager.getInstance().getAbstractHallByOwner(player.getClan());
 					if (clanhall != null)
 					{
 						L2ClanHallZone zone = clanhall.getZone();
@@ -355,6 +356,7 @@ public class MapRegionManager
 				{
 					castle = CastleManager.getInstance().getCastle(player);
 					fort = FortManager.getInstance().getFort(player);
+					clanhall = ClanHallManager.getInstance().getNearbyAbstractHall(activeChar.getX(), activeChar.getY(), 10000);
 					L2SiegeFlagInstance tw_flag = TerritoryWarManager.getInstance().getFlagForClan(player.getClan());
 					if (tw_flag != null)
 						return new Location(tw_flag.getX(), tw_flag.getY(), tw_flag.getZ());
@@ -387,6 +389,16 @@ public class MapRegionManager
 							}
 						}
 					}
+					else if(clanhall != null && clanhall.isSiegableHall())
+					{
+						SiegableHall sHall = (SiegableHall)clanhall;
+						List<L2Npc> flags = sHall.getSiege().getFlag(player.getClan());
+						if(flags != null && !flags.isEmpty())
+						{
+							L2Npc flag = flags.get(0);
+							return new Location(flag.getX(), flag.getY(), flag.getZ());
+						}
+					}
 				}
 			}
 			

+ 3 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/instancemanager/TerritoryWarManager.java

@@ -1676,4 +1676,7 @@ public class TerritoryWarManager implements Siegable
 	{
 		return Config.CASTLE_ZONE_FAME_AQUIRE_POINTS;
 	}
+	
+	@Override
+	public void updateSiege() { }
 }

+ 7 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Npc.java

@@ -29,6 +29,7 @@ import com.l2jserver.gameserver.cache.HtmCache;
 import com.l2jserver.gameserver.datatables.ItemTable;
 import com.l2jserver.gameserver.handler.BypassHandler;
 import com.l2jserver.gameserver.handler.IBypassHandler;
+import com.l2jserver.gameserver.instancemanager.CHSiegeManager;
 import com.l2jserver.gameserver.instancemanager.CastleManager;
 import com.l2jserver.gameserver.instancemanager.FortManager;
 import com.l2jserver.gameserver.instancemanager.TownManager;
@@ -55,6 +56,7 @@ import com.l2jserver.gameserver.model.actor.stat.NpcStat;
 import com.l2jserver.gameserver.model.actor.status.NpcStatus;
 import com.l2jserver.gameserver.model.entity.Castle;
 import com.l2jserver.gameserver.model.entity.Fort;
+import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
 import com.l2jserver.gameserver.model.olympiad.Olympiad;
 import com.l2jserver.gameserver.model.quest.Quest;
 import com.l2jserver.gameserver.model.zone.type.L2TownZone;
@@ -880,6 +882,11 @@ public class L2Npc extends L2Character
 		return CastleManager.getInstance().getCastles().get(_castleIndex);
 	}
 	
+	public final SiegableHall getConquerableHall()
+	{
+		return CHSiegeManager.getInstance().getNearbyClanHall(getX(), getY(), 10000);
+	}
+	
 	/**
 	 * Return closest castle in defined distance
 	 * @param maxDistance long

+ 8 - 8
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2AuctioneerInstance.java

@@ -163,8 +163,8 @@ public final class L2AuctioneerInstance extends L2Npc
 						html.replace("%AGIT_NAME%", a.getItemName());
 						html.replace("%OWNER_PLEDGE_NAME%", a.getSellerClanName());
 						html.replace("%OWNER_PLEDGE_MASTER%", a.getSellerName());
-						html.replace("%AGIT_SIZE%", String.valueOf(ClanHallManager.getInstance().getClanHallById(a.getItemId()).getGrade()*10));
-						html.replace("%AGIT_LEASE%", String.valueOf(ClanHallManager.getInstance().getClanHallById(a.getItemId()).getLease()));
+						html.replace("%AGIT_SIZE%", String.valueOf(ClanHallManager.getInstance().getAuctionableHallById(a.getItemId()).getGrade()*10));
+						html.replace("%AGIT_LEASE%", String.valueOf(ClanHallManager.getInstance().getAuctionableHallById(a.getItemId()).getLease()));
 						html.replace("%AGIT_LOCATION%", ClanHallManager.getInstance().getClanHallById(a.getItemId()).getLocation());
 						html.replace("%AGIT_AUCTION_END%", String.valueOf(format.format(a.getEndDate())));
 						html.replace("%AGIT_AUCTION_REMAIN%", String.valueOf((a.getEndDate()- System.currentTimeMillis())/3600000)+" hours "+String.valueOf((((a.getEndDate() - System.currentTimeMillis()) / 60000) % 60))+" minutes");
@@ -384,8 +384,8 @@ public final class L2AuctioneerInstance extends L2Npc
 						html.replace("%AGIT_NAME%", a.getItemName());
 						html.replace("%OWNER_PLEDGE_NAME%", a.getSellerClanName());
 						html.replace("%OWNER_PLEDGE_MASTER%", a.getSellerName());
-						html.replace("%AGIT_SIZE%", String.valueOf(ClanHallManager.getInstance().getClanHallById(a.getItemId()).getGrade()*10));
-						html.replace("%AGIT_LEASE%", String.valueOf(ClanHallManager.getInstance().getClanHallById(a.getItemId()).getLease()));
+						html.replace("%AGIT_SIZE%", String.valueOf(ClanHallManager.getInstance().getAuctionableHallById(a.getItemId()).getGrade()*10));
+						html.replace("%AGIT_LEASE%", String.valueOf(ClanHallManager.getInstance().getAuctionableHallById(a.getItemId()).getLease()));
 						html.replace("%AGIT_LOCATION%", ClanHallManager.getInstance().getClanHallById(a.getItemId()).getLocation());
 						html.replace("%AGIT_AUCTION_END%", String.valueOf(format.format(a.getEndDate())));
 						html.replace("%AGIT_AUCTION_REMAIN%", String.valueOf((a.getEndDate()-System.currentTimeMillis()) / 3600000)+" hours "+String.valueOf((((a.getEndDate()-System.currentTimeMillis()) / 60000) % 60))+" minutes");
@@ -413,8 +413,8 @@ public final class L2AuctioneerInstance extends L2Npc
 						html.replace("%AGIT_NAME%", a.getItemName());
 						html.replace("%AGIT_OWNER_PLEDGE_NAME%", a.getSellerClanName());
 						html.replace("%OWNER_PLEDGE_MASTER%", a.getSellerName());
-						html.replace("%AGIT_SIZE%", String.valueOf(ClanHallManager.getInstance().getClanHallById(a.getItemId()).getGrade()*10));
-						html.replace("%AGIT_LEASE%", String.valueOf(ClanHallManager.getInstance().getClanHallById(a.getItemId()).getLease()));
+						html.replace("%AGIT_SIZE%", String.valueOf(ClanHallManager.getInstance().getAuctionableHallById(a.getItemId()).getGrade()*10));
+						html.replace("%AGIT_LEASE%", String.valueOf(ClanHallManager.getInstance().getAuctionableHallById(a.getItemId()).getLease()));
 						html.replace("%AGIT_LOCATION%", ClanHallManager.getInstance().getClanHallById(a.getItemId()).getLocation());
 						html.replace("%AGIT_AUCTION_END%", String.valueOf(format.format(a.getEndDate())));
 						html.replace("%AGIT_AUCTION_REMAIN%", String.valueOf((a.getEndDate()-System.currentTimeMillis()) / 3600000)+" hours "+String.valueOf((((a.getEndDate()-System.currentTimeMillis()) / 60000) % 60))+" minutes");
@@ -442,8 +442,8 @@ public final class L2AuctioneerInstance extends L2Npc
 						html.replace("%AGIT_NAME%", ClanHallManager.getInstance().getClanHallById(ItemId).getName());
 						html.replace("%AGIT_OWNER_PLEDGE_NAME%", player.getClan().getName());
 						html.replace("%OWNER_PLEDGE_MASTER%", player.getClan().getLeaderName());
-						html.replace("%AGIT_SIZE%", String.valueOf(ClanHallManager.getInstance().getClanHallById(ItemId).getGrade()*10));
-						html.replace("%AGIT_LEASE%", String.valueOf(ClanHallManager.getInstance().getClanHallById(ItemId).getLease()));
+						html.replace("%AGIT_SIZE%", String.valueOf(ClanHallManager.getInstance().getAuctionableHallById(ItemId).getGrade()*10));
+						html.replace("%AGIT_LEASE%", String.valueOf(ClanHallManager.getInstance().getAuctionableHallById(ItemId).getLease()));
 						html.replace("%AGIT_LOCATION%", ClanHallManager.getInstance().getClanHallById(ItemId).getLocation());
 						html.replace("%AGIT_LINK_BACK%", "bypass -h npc_"+getObjectId()+"_start");
 						html.replace("%objectId%", String.valueOf(getObjectId()));

+ 27 - 7
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2CastleDoormenInstance.java

@@ -17,6 +17,7 @@ package com.l2jserver.gameserver.model.actor.instance;
 import java.util.StringTokenizer;
 
 import com.l2jserver.gameserver.model.L2Clan;
+import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
 import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
 
 
@@ -36,7 +37,10 @@ public class L2CastleDoormenInstance extends L2DoormenInstance
 		
 		while (st.hasMoreTokens())
 		{
-			getCastle().openDoor(player, Integer.parseInt(st.nextToken()));
+			if(getConquerableHall() != null)
+				getConquerableHall().openCloseDoor(Integer.parseInt(st.nextToken()), true);
+			else
+				getCastle().openDoor(player, Integer.parseInt(st.nextToken()));
 		}
 	}
 	
@@ -48,19 +52,32 @@ public class L2CastleDoormenInstance extends L2DoormenInstance
 		
 		while (st.hasMoreTokens())
 		{
-			getCastle().closeDoor(player, Integer.parseInt(st.nextToken()));
+			if(getConquerableHall() != null)
+				getConquerableHall().openCloseDoor(Integer.parseInt(st.nextToken()), false);
+			else
+				getCastle().closeDoor(player, Integer.parseInt(st.nextToken()));
 		}
 	}
 	
 	@Override
 	protected final boolean isOwnerClan(L2PcInstance player)
 	{
-		if (player.getClan() != null && getCastle() != null)
+		if (player.getClan() != null)
 		{
-			// player should have privileges to open doors
-			if (player.getClanId() == getCastle().getOwnerId()
-					&& (player.getClanPrivileges() & L2Clan.CP_CS_OPEN_DOOR) == L2Clan.CP_CS_OPEN_DOOR)
-				return true;
+			if(getConquerableHall() != null)
+			{
+				// player should have privileges to open doors
+				if (player.getClanId() == getConquerableHall().getOwnerId()
+						&& (player.getClanPrivileges() & L2Clan.CP_CS_OPEN_DOOR) == L2Clan.CP_CS_OPEN_DOOR)
+					return true;
+			}
+			else if(getCastle() != null)
+			{
+				// player should have privileges to open doors
+				if (player.getClanId() == getCastle().getOwnerId()
+						&& (player.getClanPrivileges() & L2Clan.CP_CS_OPEN_DOOR) == L2Clan.CP_CS_OPEN_DOOR)
+					return true;
+			}
 		}
 		return false;
 	}
@@ -68,6 +85,9 @@ public class L2CastleDoormenInstance extends L2DoormenInstance
 	@Override
 	protected final boolean isUnderSiege()
 	{
+		SiegableHall hall = getConquerableHall();
+		if(hall != null)
+			return hall.isInSiege();
 		return getCastle().getZone().isActive();
 	}
 }

+ 43 - 19
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2ClanHallManagerInstance.java

@@ -20,11 +20,13 @@ import java.util.StringTokenizer;
 import com.l2jserver.Config;
 import com.l2jserver.gameserver.datatables.SkillTable;
 import com.l2jserver.gameserver.datatables.TeleportLocationTable;
+import com.l2jserver.gameserver.instancemanager.CHSiegeManager;
 import com.l2jserver.gameserver.instancemanager.ClanHallManager;
 import com.l2jserver.gameserver.model.L2Clan;
 import com.l2jserver.gameserver.model.L2Skill;
 import com.l2jserver.gameserver.model.L2TeleportLocation;
 import com.l2jserver.gameserver.model.entity.ClanHall;
+import com.l2jserver.gameserver.model.entity.clanhall.AuctionableHall;
 import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
 import com.l2jserver.gameserver.network.serverpackets.AgitDecoInfo;
@@ -60,11 +62,12 @@ public class L2ClanHallManagerInstance extends L2MerchantInstance
 	@Override
 	public void onBypassFeedback(L2PcInstance player, String command)
 	{
-		SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm");
 		int condition = validateCondition(player);
 		if (condition <= COND_ALL_FALSE)
 			return;
-		else if (condition == COND_OWNER)
+		
+		SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm");
+		if (condition == COND_OWNER)
 		{
 			StringTokenizer st = new StringTokenizer(command, " ");
 			String actualCommand = st.nextToken(); // Get actual command
@@ -98,9 +101,14 @@ public class L2ClanHallManagerInstance extends L2MerchantInstance
 				NpcHtmlMessage html = new NpcHtmlMessage(1);
 				if ((player.getClanPrivileges() & L2Clan.CP_CL_VIEW_WAREHOUSE) == L2Clan.CP_CL_VIEW_WAREHOUSE)
 				{
-					html.setFile(player.getHtmlPrefix(), "data/html/clanHallManager/vault.htm");
-					html.replace("%rent%", String.valueOf(getClanHall().getLease()));
-					html.replace("%date%", format.format(getClanHall().getPaidUntil()));
+					if(getClanHall().getLease() <= 0)
+						html.setFile(player.getHtmlPrefix(), "data/html/clanHallManager/vault-chs.htm");
+					else
+					{				
+						html.setFile(player.getHtmlPrefix(), "data/html/clanHallManager/vault.htm");
+						html.replace("%rent%", String.valueOf(getClanHall().getLease()));
+						html.replace("%date%", format.format(getClanHall().getPaidUntil()));
+					}
 					sendHtmlMessage(player, html);
 				}
 				else
@@ -982,16 +990,20 @@ public class L2ClanHallManagerInstance extends L2MerchantInstance
 						String support_grade2 = "[<a action=\"bypass -h npc_%objectId%_manage other edit_support 3\">Level 3</a>][<a action=\"bypass -h npc_%objectId%_manage other edit_support 4\">Level 4</a>][<a action=\"bypass -h npc_%objectId%_manage other edit_support 5\">Level 5</a>]";
 						String support_grade3 = "[<a action=\"bypass -h npc_%objectId%_manage other edit_support 3\">Level 3</a>][<a action=\"bypass -h npc_%objectId%_manage other edit_support 5\">Level 5</a>][<a action=\"bypass -h npc_%objectId%_manage other edit_support 7\">Level 7</a>][<a action=\"bypass -h npc_%objectId%_manage other edit_support 8\">Level 8</a>]";
 						String item = "[<a action=\"bypass -h npc_%objectId%_manage other edit_item 1\">Level 1</a>][<a action=\"bypass -h npc_%objectId%_manage other edit_item 2\">Level 2</a>][<a action=\"bypass -h npc_%objectId%_manage other edit_item 3\">Level 3</a>]";
-						if (getClanHall().getFunction(ClanHall.FUNC_TELEPORT) != null){
+						if (getClanHall().getFunction(ClanHall.FUNC_TELEPORT) != null)
+						{
 							html.replace("%tele%","Stage "+ String.valueOf(getClanHall().getFunction(ClanHall.FUNC_TELEPORT).getLvl()) + "</font> (<font color=\"FFAABB\">"+String.valueOf(getClanHall().getFunction(ClanHall.FUNC_TELEPORT).getLease())+"</font>Adena /"+String.valueOf(Config.CH_TELE_FEE_RATIO/1000/60/60/24)+" Day)");
 							html.replace("%tele_period%","Withdraw the fee for the next time at " + format.format(getClanHall().getFunction(ClanHall.FUNC_TELEPORT).getEndTime()));
 							html.replace("%change_tele%","[<a action=\"bypass -h npc_%objectId%_manage other tele_cancel\">Deactivate</a>]"+tele);
-						}else{
+						}
+						else
+						{
 							html.replace("%tele%", "none");
 							html.replace("%tele_period%", "none");
 							html.replace("%change_tele%",tele);
 						}
-						if (getClanHall().getFunction(ClanHall.FUNC_SUPPORT) != null){
+						if (getClanHall().getFunction(ClanHall.FUNC_SUPPORT) != null)
+						{
 							html.replace("%support%","Stage "+ String.valueOf(getClanHall().getFunction(ClanHall.FUNC_SUPPORT).getLvl()) + "</font> (<font color=\"FFAABB\">"+String.valueOf(getClanHall().getFunction(ClanHall.FUNC_SUPPORT).getLease())+"</font>Adena /"+String.valueOf(Config.CH_SUPPORT_FEE_RATIO/1000/60/60/24)+" Day)");
 							html.replace("%support_period%","Withdraw the fee for the next time at " + format.format(getClanHall().getFunction(ClanHall.FUNC_SUPPORT).getEndTime()));
 							int grade = getClanHall().getGrade();
@@ -1010,7 +1022,9 @@ public class L2ClanHallManagerInstance extends L2MerchantInstance
 									html.replace("%change_support%","[<a action=\"bypass -h npc_%objectId%_manage other support_cancel\">Deactivate</a>]"+support_grade3);
 									break;
 							}
-						}else{
+						}
+						else
+						{
 							html.replace("%support%", "none");
 							html.replace("%support_period%", "none");
 							int grade = getClanHall().getGrade();
@@ -1030,22 +1044,26 @@ public class L2ClanHallManagerInstance extends L2MerchantInstance
 									break;
 							}
 						}
-						if (getClanHall().getFunction(ClanHall.FUNC_ITEM_CREATE) != null){
+						if (getClanHall().getFunction(ClanHall.FUNC_ITEM_CREATE) != null)
+						{
 							html.replace("%item%","Stage "+ String.valueOf(getClanHall().getFunction(ClanHall.FUNC_ITEM_CREATE).getLvl()) + "</font> (<font color=\"FFAABB\">"+String.valueOf(getClanHall().getFunction(ClanHall.FUNC_ITEM_CREATE).getLease())+"</font>Adena /"+String.valueOf(Config.CH_ITEM_FEE_RATIO/1000/60/60/24)+" Day)");
 							html.replace("%item_period%","Withdraw the fee for the next time at " + format.format(getClanHall().getFunction(ClanHall.FUNC_ITEM_CREATE).getEndTime()));
 							html.replace("%change_item%","[<a action=\"bypass -h npc_%objectId%_manage other item_cancel\">Deactivate</a>]"+item);
-						}else{
+						}
+						else
+						{
 							html.replace("%item%", "none");
 							html.replace("%item_period%", "none");
 							html.replace("%change_item%",item);
 						}
 						sendHtmlMessage(player, html);
 					}
-					else if (val.equalsIgnoreCase("deco"))
+					else if (val.equalsIgnoreCase("deco") && !getClanHall().isSiegableHall())
 					{
 						if (st.countTokens() >= 1)
 						{
-							if(getClanHall().getOwnerId() == 0){
+							if(getClanHall().getOwnerId() == 0)
+							{
 								player.sendMessage("This clan Hall have no owner, you cannot change configuration");
 								return;
 							}
@@ -1112,7 +1130,8 @@ public class L2ClanHallManagerInstance extends L2MerchantInstance
 								sendHtmlMessage(player, html);
 								return;
 							}
-							else if (val.equalsIgnoreCase("curtains")){
+							else if (val.equalsIgnoreCase("curtains"))
+							{
 								if (st.countTokens() >= 1)
 								{
 									int fee;
@@ -1235,7 +1254,7 @@ public class L2ClanHallManagerInstance extends L2MerchantInstance
 					else
 					{
 						NpcHtmlMessage html = new NpcHtmlMessage(1);
-						html.setFile(player.getHtmlPrefix(), "data/html/clanHallManager/manage.htm");
+						html.setFile(player.getHtmlPrefix(), getClanHall().isSiegableHall()? "data/html/clanHallManager/manage_siegable.htm" : "data/html/clanHallManager/manage.htm");
 						sendHtmlMessage(player, html);
 					}
 				}
@@ -1311,7 +1330,10 @@ public class L2ClanHallManagerInstance extends L2MerchantInstance
 			else if (actualCommand.equalsIgnoreCase("list_back"))
 			{
 				NpcHtmlMessage html = new NpcHtmlMessage(1);
-				html.setFile(player.getHtmlPrefix(), "data/html/clanHallManager/chamberlain.htm");
+				if(getClanHall().getLease() > 0)
+					html.setFile(player.getHtmlPrefix(), "data/html/clanHallManager/chamberlain.htm");
+				else
+					html.setFile(player.getHtmlPrefix(), "data/html/clanHallManager/chamberlain-chs.htm");
 				html.replace("%objectId%", String.valueOf(this.getObjectId()));
 				html.replace("%npcname%", this.getName());
 				sendHtmlMessage(player, html);
@@ -1353,7 +1375,7 @@ public class L2ClanHallManagerInstance extends L2MerchantInstance
 		int condition = validateCondition(player);
 		if (condition == COND_OWNER)
 			filename = "data/html/clanHallManager/chamberlain.htm";// Owner message window
-		if (condition == COND_OWNER_FALSE)
+		else if (condition == COND_OWNER_FALSE)
 			filename = "data/html/clanHallManager/chamberlain-of.htm";
 		NpcHtmlMessage html = new NpcHtmlMessage(1);
 		html.setFile(player.getHtmlPrefix(), filename);
@@ -1381,10 +1403,12 @@ public class L2ClanHallManagerInstance extends L2MerchantInstance
 		if (_clanHallId < 0)
 		{
 			ClanHall temp = ClanHallManager.getInstance().getNearbyClanHall(getX(), getY(), 500);
+			if(temp == null)
+				temp = CHSiegeManager.getInstance().getNearbyClanHall(this);
 			
 			if (temp != null)
 				_clanHallId = temp.getId();
-			
+				
 			if (_clanHallId < 0) return null;
 		}
 		return ClanHallManager.getInstance().getClanHallById(_clanHallId);
@@ -1418,7 +1442,7 @@ public class L2ClanHallManagerInstance extends L2MerchantInstance
 	
 	private void revalidateDeco(L2PcInstance player)
 	{
-		ClanHall ch = ClanHallManager.getInstance().getClanHallByOwner(player.getClan());
+		AuctionableHall ch = ClanHallManager.getInstance().getClanHallByOwner(player.getClan());
 		if (ch == null) return;
 		AgitDecoInfo bl = new AgitDecoInfo(ch);
 		player.sendPacket(bl);

+ 20 - 8
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2DefenderInstance.java

@@ -19,6 +19,7 @@ import com.l2jserver.gameserver.ai.CtrlIntention;
 import com.l2jserver.gameserver.ai.L2CharacterAI;
 import com.l2jserver.gameserver.ai.L2FortSiegeGuardAI;
 import com.l2jserver.gameserver.ai.L2SiegeGuardAI;
+import com.l2jserver.gameserver.ai.L2SpecialSiegeGuardAI;
 import com.l2jserver.gameserver.instancemanager.CastleManager;
 import com.l2jserver.gameserver.instancemanager.FortManager;
 import com.l2jserver.gameserver.instancemanager.TerritoryWarManager;
@@ -29,6 +30,7 @@ import com.l2jserver.gameserver.model.actor.L2Playable;
 import com.l2jserver.gameserver.model.actor.knownlist.DefenderKnownList;
 import com.l2jserver.gameserver.model.entity.Castle;
 import com.l2jserver.gameserver.model.entity.Fort;
+import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
 import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
 import com.l2jserver.gameserver.network.serverpackets.MyTargetSelected;
 import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
@@ -39,6 +41,7 @@ public class L2DefenderInstance extends L2Attackable
 {
 	private Castle _castle = null; // the castle which the instance should defend
 	private Fort _fort = null; // the fortress which the instance should defend
+	private SiegableHall _hall = null; // the siegable hall which the instance should defend
 	
 	public L2DefenderInstance(int objectId, L2NpcTemplate template)
 	{
@@ -67,10 +70,14 @@ public class L2DefenderInstance extends L2Attackable
 			synchronized(this)
 			{
 				if (_ai == null)
-					if (getCastle(10000) == null)
+				{
+					if (getConquerableHall() == null && getCastle(10000) == null)
 						_ai = new L2FortSiegeGuardAI(new AIAccessor());
-					else
+					else if(getCastle(10000) != null)
 						_ai = new L2SiegeGuardAI(new AIAccessor());
+					else
+						_ai = new L2SpecialSiegeGuardAI(new AIAccessor());
+				}	
 				return _ai;
 			}
 		}
@@ -94,9 +101,10 @@ public class L2DefenderInstance extends L2Attackable
 		
 		// Check if siege is in progress
 		if ((_fort != null && _fort.getZone().isActive())
-				|| (_castle != null && _castle.getZone().isActive()))
+				|| (_castle != null && _castle.getZone().isActive())
+				|| (_hall != null && _hall.getSiegeZone().isActive()))
 		{
-			int activeSiegeId = (_fort != null ? _fort.getFortId() : (_castle != null ? _castle.getCastleId() : 0));
+			int activeSiegeId = (_fort != null ? _fort.getFortId() : (_castle != null ? _castle.getCastleId() : (_hall != null? _hall.getId() : 0)));
 			
 			// Check if player is an enemy of this defender npc
 			if (player != null && ((player.getSiegeState() == 2 && !player.isRegisteredOnThisSiegeField(activeSiegeId))
@@ -144,8 +152,9 @@ public class L2DefenderInstance extends L2Attackable
 		
 		_fort = FortManager.getInstance().getFort(getX(), getY(), getZ());
 		_castle = CastleManager.getInstance().getCastle(getX(), getY(), getZ());
-		if (_fort == null && _castle == null)
-			_log.warning("L2DefenderInstance spawned outside of Fortress or Castle Zone! NpcId: "+getNpcId()+ " x="+getX()+ " y="+getY()+ " z="+getZ());
+		_hall = getConquerableHall();
+		if (_fort == null && _castle == null && _hall == null)
+			_log.warning("L2DefenderInstance spawned outside of Fortress, Castle or Siegable hall Zone! NpcId: "+getNpcId()+ " x="+getX()+ " y="+getY()+ " z="+getZ());
 	}
 	
 	/**
@@ -218,12 +227,15 @@ public class L2DefenderInstance extends L2Attackable
 				L2PcInstance player = attacker.getActingPlayer();
 				// Check if siege is in progress
 				if ((_fort != null && _fort.getZone().isActive())
-						|| (_castle != null && _castle.getZone().isActive()))
+						|| (_castle != null && _castle.getZone().isActive())
+						|| _hall != null && _hall.getSiegeZone().isActive())
 				{
-					int activeSiegeId = (_fort != null ? _fort.getFortId() : (_castle != null ? _castle.getCastleId() : 0));
+					int activeSiegeId = (_fort != null ? _fort.getFortId() : (_castle != null ? _castle.getCastleId() : (_hall != null? _hall.getId() : 0)));
 					if (player != null && ((player.getSiegeState() == 2 && player.isRegisteredOnThisSiegeField(activeSiegeId))
 							|| (player.getSiegeState() == 1 && TerritoryWarManager.getInstance().isAllyField(player, activeSiegeId))))
+					{
 						return;
+					}
 				}
 			}
 			super.addDamageHate(attacker, damage, aggro);

+ 13 - 4
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2DoorInstance.java

@@ -41,6 +41,7 @@ import com.l2jserver.gameserver.model.actor.status.DoorStatus;
 import com.l2jserver.gameserver.model.entity.Castle;
 import com.l2jserver.gameserver.model.entity.ClanHall;
 import com.l2jserver.gameserver.model.entity.Fort;
+import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
 import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.serverpackets.DoorStatusUpdate;
 import com.l2jserver.gameserver.network.serverpackets.OnEventTrigger;
@@ -390,6 +391,8 @@ public class L2DoorInstance extends L2Character
 			return true;
 		if (getFort() != null && getFort().getFortId() > 0 && getFort().getZone().isActive() && !getIsCommanderDoor())
 			return true;
+		if(getClanHall() != null && getClanHall().isSiegableHall() && ((SiegableHall)getClanHall()).getSiegeZone().isActive())
+			return true;
 		return false;
 	}
 	
@@ -403,14 +406,19 @@ public class L2DoorInstance extends L2Character
 		if (!(attacker instanceof L2Playable))
 			return false;
 		
-		if (getClanHall() != null)
-			return false;
+		L2PcInstance actingPlayer = attacker.getActingPlayer();
 		
+		if(getClanHall() != null)
+		{
+			if(!getClanHall().isSiegableHall())
+				return false;
+			return ((SiegableHall)getClanHall()).isInSiege()
+					&& ((SiegableHall)getClanHall()).getSiege().checkIsAttacker(actingPlayer.getClan());
+		}
 		// Attackable  only during siege by everyone (not owner)
 		boolean isCastle = (getCastle() != null && getCastle().getCastleId() > 0 && getCastle().getZone().isActive());
 		boolean isFort = (getFort() != null && getFort().getFortId() > 0 && getFort().getZone().isActive() && !getIsCommanderDoor());
 		int activeSiegeId = (getFort() != null ? getFort().getFortId() : (getCastle() != null ? getCastle().getCastleId() : 0));
-		L2PcInstance actingPlayer = attacker.getActingPlayer();
 		
 		if (TerritoryWarManager.getInstance().isTWInProgress())
 		{
@@ -710,8 +718,9 @@ public class L2DoorInstance extends L2Character
 		
 		boolean isFort = (getFort() != null && getFort().getFortId() > 0 && getFort().getSiege().getIsInProgress()) && !getIsCommanderDoor();
 		boolean isCastle = (getCastle() != null	&& getCastle().getCastleId() > 0 && getCastle().getSiege().getIsInProgress());
+		boolean isHall = (getClanHall() != null && getClanHall().isSiegableHall() && ((SiegableHall)getClanHall()).isInSiege());
 		
-		if (isFort || isCastle)
+		if (isFort || isCastle || isHall)
 			broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.CASTLE_GATE_BROKEN_DOWN));
 		return true;
 	}

+ 6 - 11
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2SiegeFlagInstance.java

@@ -16,6 +16,7 @@ package com.l2jserver.gameserver.model.actor.instance;
 
 import com.l2jserver.gameserver.ThreadPoolManager;
 import com.l2jserver.gameserver.ai.CtrlIntention;
+import com.l2jserver.gameserver.instancemanager.CHSiegeManager;
 import com.l2jserver.gameserver.instancemanager.FortSiegeManager;
 import com.l2jserver.gameserver.instancemanager.SiegeManager;
 import com.l2jserver.gameserver.instancemanager.TerritoryWarManager;
@@ -73,6 +74,8 @@ public class L2SiegeFlagInstance extends L2Npc
 		_siege = SiegeManager.getInstance().getSiege(_player.getX(), _player.getY(), _player.getZ());
 		if (_siege == null)
 			_siege = FortSiegeManager.getInstance().getSiege(_player.getX(), _player.getY(), _player.getZ());
+		if(_siege == null)
+			_siege = CHSiegeManager.getInstance().getSiege(player);
 		if (_clan == null || _siege == null)
 		{
 			throw new NullPointerException(getClass().getSimpleName()+": Initialization failed.");
@@ -192,17 +195,9 @@ public class L2SiegeFlagInstance extends L2Npc
 		super.reduceCurrentHp(damage, attacker, skill);
 		if(canTalk())
 		{
-			if (getCastle() != null && getCastle().getSiege().getIsInProgress())
-			{
-				if (_clan != null)
-				{
-					// send warning to owners of headquarters that theirs base is under attack
-					_clan.broadcastToOnlineMembers(SystemMessage.getSystemMessage(SystemMessageId.BASE_UNDER_ATTACK));
-					setCanTalk(false);
-					ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleTalkTask(), 20000);
-				}
-			}
-			else if (getFort() != null && getFort().getSiege().getIsInProgress())
+			if ((getCastle() != null && getCastle().getSiege().getIsInProgress())
+				|| (getFort() != null && getFort().getSiege().getIsInProgress())
+				|| (getConquerableHall() != null && getConquerableHall().isInSiege()))
 			{
 				if (_clan != null)
 				{

+ 11 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2SiegeNpcInstance.java

@@ -14,6 +14,7 @@
  */
 package com.l2jserver.gameserver.model.actor.instance;
 
+import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
 import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
 import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
 import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
@@ -45,12 +46,18 @@ public class L2SiegeNpcInstance extends L2NpcInstance
 	public void showSiegeInfoWindow(L2PcInstance player)
 	{
 		if (validateCondition(player))
-			getCastle().getSiege().listRegisterClan(player);
+		{
+			SiegableHall hall = getConquerableHall();
+			if(hall != null)
+				hall.showSiegeInfo(player);
+			else
+				getCastle().getSiege().listRegisterClan(player);
+		}
 		else
 		{
 			NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
 			html.setFile(player.getHtmlPrefix(), "data/html/siege/" + getNpcId() + "-busy.htm");
-			html.replace("%castlename%",getCastle().getName());
+			html.replace("%castlename%",getConquerableHall() != null? getConquerableHall().getName() : getCastle().getName());
 			html.replace("%objectId%",String.valueOf(getObjectId()));
 			player.sendPacket(html);
 			player.sendPacket(ActionFailed.STATIC_PACKET);
@@ -59,6 +66,8 @@ public class L2SiegeNpcInstance extends L2NpcInstance
 	
 	private boolean validateCondition(L2PcInstance player)
 	{
+		if(getConquerableHall() != null && getConquerableHall().isInSiege())
+			return false;
 		if (getCastle().getSiege().getIsInProgress())
 			return false;       // Busy because of siege
 		

+ 15 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2WyvernManagerInstance.java

@@ -14,7 +14,10 @@
  */
 package com.l2jserver.gameserver.model.actor.instance;
 
+import com.l2jserver.gameserver.model.L2Clan;
 import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.entity.ClanHall;
+import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
 import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
 import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
 import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
@@ -45,11 +48,21 @@ public class L2WyvernManagerInstance extends L2Npc
 	
 	public boolean isOwnerClan(L2PcInstance player)
 	{
-		return true;
+		L2Clan clan = player.getClan();
+		if(clan != null)
+		{
+			ClanHall hall = getConquerableHall();
+			if(hall != null)
+				return hall.getOwnerId() == clan.getClanId();
+		}
+		return false;
 	}
 	
 	public boolean isInSiege()
 	{
-		return false;
+		SiegableHall hall = getConquerableHall();
+		if(hall != null)
+			return hall.isInSiege();
+		return getCastle().getSiege().getIsInProgress();
 	}
 }

+ 5 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/knownlist/DefenderKnownList.java

@@ -23,6 +23,7 @@ import com.l2jserver.gameserver.model.actor.instance.L2FortCommanderInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.entity.Castle;
 import com.l2jserver.gameserver.model.entity.Fort;
+import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
 
 public class DefenderKnownList extends AttackableKnownList
 {
@@ -45,16 +46,18 @@ public class DefenderKnownList extends AttackableKnownList
 		
 		Castle castle = getActiveChar().getCastle();
 		Fort fortress = getActiveChar().getFort();
+		SiegableHall hall = getActiveChar().getConquerableHall();
 		// Check if siege is in progress
 		if ((fortress != null && fortress.getZone().isActive())
-				|| (castle != null && castle.getZone().isActive()))
+				|| (castle != null && castle.getZone().isActive())
+				|| (hall != null && hall.getSiegeZone().isActive()))
 		{
 			L2PcInstance player = null;
 			if (object instanceof L2PcInstance)
 				player = (L2PcInstance) object;
 			else if (object instanceof L2Summon)
 				player = ((L2Summon)object).getOwner();
-			int activeSiegeId = (fortress != null ? fortress.getFortId() : (castle != null ? castle.getCastleId() : 0));
+			int activeSiegeId = (fortress != null ? fortress.getFortId() : (castle != null ? castle.getCastleId() : hall != null? hall.getId() : 0));
 			
 			// Check if player is an enemy of this defender npc
 			if (player != null && ((player.getSiegeState() == 2 && !player.isRegisteredOnThisSiegeField(activeSiegeId))

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/Auction.java

@@ -471,7 +471,7 @@ public class Auction
 			if (_sellerId > 0)
 			{
 				returnItem(_sellerClanName, _highestBidderMaxBid, true);
-				returnItem(_sellerClanName, ClanHallManager.getInstance().getClanHallById(_itemId).getLease(), false);
+				returnItem(_sellerClanName, ClanHallManager.getInstance().getAuctionableHallById(_itemId).getLease(), false);
 			}
 			deleteAuctionFromDB();
 			L2Clan Clan = ClanTable.getInstance().getClanByName(_bidders.get(_highestBidderId).getClanName());

+ 32 - 195
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/ClanHall.java

@@ -29,36 +29,27 @@ import com.l2jserver.Config;
 import com.l2jserver.L2DatabaseFactory;
 import com.l2jserver.gameserver.ThreadPoolManager;
 import com.l2jserver.gameserver.datatables.ClanTable;
-import com.l2jserver.gameserver.datatables.DoorTable;
-import com.l2jserver.gameserver.instancemanager.AuctionManager;
-import com.l2jserver.gameserver.instancemanager.ClanHallManager;
 import com.l2jserver.gameserver.model.L2Clan;
 import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.zone.type.L2ClanHallZone;
-import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.serverpackets.PledgeShowInfoUpdate;
-import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.gameserver.templates.StatsSet;
 
-public class ClanHall
+public abstract class ClanHall
 {
 	protected static final Logger _log = Logger.getLogger(ClanHall.class.getName());
 	
 	private int _clanHallId;
 	private List<L2DoorInstance> _doors;
-	private List<String> _doorDefault;
 	private String _name;
 	private int _ownerId;
-	private int _lease;
 	private String _desc;
 	private String _location;
-	protected long _paidUntil;
 	private L2ClanHallZone _zone;
-	private int _grade;
 	protected final int _chRate = 604800000;
 	protected boolean _isFree = true;
 	private Map<Integer, ClanHallFunction> _functions;
-	protected boolean _paid;
 	
 	/** Clan Hall Functions */
 	public static final int FUNC_TELEPORT = 1;
@@ -67,8 +58,8 @@ public class ClanHall
 	public static final int FUNC_RESTORE_MP = 4;
 	public static final int FUNC_RESTORE_EXP = 5;
 	public static final int FUNC_SUPPORT = 6;
-	public static final int FUNC_DECO_FRONTPLATEFORM = 7;
-	public static final int FUNC_DECO_CURTAINS = 8;
+	public static final int FUNC_DECO_FRONTPLATEFORM = 7; 	//Only Auctionable Halls
+	public static final int FUNC_DECO_CURTAINS = 8;			//Only Auctionable Halls
 	
 	public class ClanHallFunction
 	{
@@ -212,37 +203,27 @@ public class ClanHall
 		}
 	}
 	
-	public ClanHall(int clanHallId, String name, int ownerId, int lease, String desc, String location, long paidUntil, int Grade,
-			boolean paid)
+	public ClanHall(StatsSet set)
 	{
-		_clanHallId = clanHallId;
-		_name = name;
-		_ownerId = ownerId;
+		_clanHallId = set.getInteger("id");
+		_name = set.getString("name");
+		_ownerId = set.getInteger("ownerId");
 		if (Config.DEBUG)
 			_log.warning("Init Owner : " + _ownerId);
-		_lease = lease;
-		_desc = desc;
-		_location = location;
-		_paidUntil = paidUntil;
-		_grade = Grade;
-		_paid = paid;
-		_doorDefault = new FastList<String>();
+		_desc = set.getString("desc");
+		_location = set.getString("location");
 		_functions = new FastMap<Integer, ClanHallFunction>();
 		
-		if (ownerId != 0)
+		if(_ownerId > 0)
 		{
-			_isFree = false;
-			initialyzeTask(false);
-			loadFunctions();
+			L2Clan clan = ClanTable.getInstance().getClan(_ownerId);
+			if(clan != null)
+				clan.setHasHideout(getId());
+			else
+				free();
 		}
 	}
 	
-	/** Return if clanHall is paid or not */
-	public final boolean getPaid()
-	{
-		return _paid;
-	}
-	
 	/** Return Id Of Clan hall */
 	public final int getId()
 	{
@@ -261,12 +242,6 @@ public class ClanHall
 		return _ownerId;
 	}
 	
-	/** Return lease*/
-	public final int getLease()
-	{
-		return _lease;
-	}
-	
 	/** Return Desc */
 	public final String getDesc()
 	{
@@ -279,18 +254,6 @@ public class ClanHall
 		return _location;
 	}
 	
-	/** Return PaidUntil */
-	public final long getPaidUntil()
-	{
-		return _paidUntil;
-	}
-	
-	/** Return Grade */
-	public final int getGrade()
-	{
-		return _grade;
-	}
-	
 	/** Return all DoorInstance */
 	public final List<L2DoorInstance> getDoors()
 	{
@@ -351,8 +314,6 @@ public class ClanHall
 		for (Map.Entry<Integer, ClanHallFunction> fc : _functions.entrySet())
 			removeFunction(fc.getKey());
 		_functions.clear();
-		_paidUntil = 0;
-		_paid = false;
 		updateDb();
 	}
 	
@@ -364,40 +325,12 @@ public class ClanHall
 			return;
 		_ownerId = clan.getClanId();
 		_isFree = false;
-		_paidUntil = System.currentTimeMillis();
-		initialyzeTask(true);
+		clan.setHasHideout(getId());
 		// Annonce to Online member new ClanHall
 		clan.broadcastToOnlineMembers(new PledgeShowInfoUpdate(clan));
 		updateDb();
 	}
-	
-	/** Respawn all doors */
-	public void spawnDoor()
-	{
-		spawnDoor(false);
-	}
-	
-	/** Respawn all doors */
-	public void spawnDoor(boolean isDoorWeak)
-	{
-		for (int i = 0; i < getDoors().size(); i++)
-		{
-			L2DoorInstance door = getDoors().get(i);
-			if (door.getCurrentHp() <= 0)
-			{
-				door.decayMe(); // Kill current if not killed already
-				door = DoorTable.parseList(_doorDefault.get(i), false);
-				DoorTable.getInstance().putDoor(door); //Readd the new door to the DoorTable By Erb
-				if (isDoorWeak)
-					door.setCurrentHp(door.getMaxHp() / 2);
-				door.spawnMe(door.getX(), door.getY(), door.getZ());
-				getDoors().set(i, door);
-			}
-			else if (door.getOpen())
-				door.closeMe();
-		}
-	}
-	
+		
 	/** Open or Close Door */
 	public void openCloseDoor(L2PcInstance activeChar, int doorId, boolean open)
 	{
@@ -448,7 +381,7 @@ public class ClanHall
 	}
 	
 	/** Load All Functions */
-	private void loadFunctions()
+	protected void loadFunctions()
 	{
 		Connection con = null;
 		try
@@ -539,121 +472,25 @@ public class ClanHall
 		return true;
 	}
 	
-	/** Update DB */
-	public void updateDb()
+	public int getGrade()
 	{
-		Connection con = null;
-		try
-		{
-			con = L2DatabaseFactory.getInstance().getConnection();
-			PreparedStatement statement;
-			
-			statement = con.prepareStatement("UPDATE clanhall SET ownerId=?, paidUntil=?, paid=? WHERE id=?");
-			statement.setInt(1, _ownerId);
-			statement.setLong(2, _paidUntil);
-			statement.setInt(3, (_paid) ? 1 : 0);
-			statement.setInt(4, _clanHallId);
-			statement.execute();
-			statement.close();
-		}
-		catch (Exception e)
-		{
-			_log.log(Level.WARNING, "Exception: updateOwnerInDB(L2Clan clan): " + e.getMessage(), e);
-		}
-		finally
-		{
-			L2DatabaseFactory.close(con);
-		}
+		return 0;
 	}
 	
-	/** Initialize Fee Task */
-	private void initialyzeTask(boolean forced)
+	public long getPaidUntil()
 	{
-		long currentTime = System.currentTimeMillis();
-		if (_paidUntil > currentTime)
-			ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), _paidUntil - currentTime);
-		else if (!_paid && !forced)
-		{
-			if (System.currentTimeMillis() + (1000 * 60 * 60 * 24) <= _paidUntil + _chRate)
-				ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), System.currentTimeMillis() + (1000 * 60 * 60 * 24));
-			else
-				ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), (_paidUntil + _chRate) - System.currentTimeMillis());
-		}
-		else
-			ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), 0);
+		return 0;
 	}
 	
-	/** Fee Task */
-	private class FeeTask implements Runnable
+	public int getLease()
 	{
-		public FeeTask()
-		{
-		}
-		
-		public void run()
-		{
-			try
-			{
-				long _time = System.currentTimeMillis();
-				
-				if (_isFree)
-					return;
-				
-				if(_paidUntil > _time)
-				{
-					ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), _paidUntil - _time);
-					return;
-				}
-				
-				L2Clan Clan = ClanTable.getInstance().getClan(getOwnerId());
-				if (ClanTable.getInstance().getClan(getOwnerId()).getWarehouse().getAdena() >= getLease())
-				{
-					if (_paidUntil != 0)
-					{
-						while (_paidUntil <= _time)
-							_paidUntil += _chRate;
-					}
-					else
-						_paidUntil = _time + _chRate;
-					ClanTable.getInstance().getClan(getOwnerId()).getWarehouse().destroyItemByItemId("CH_rental_fee", 57, getLease(), null, null);
-					if (Config.DEBUG)
-						_log.warning("deducted " + getLease() + " adena from " + getName() + " owner's cwh for ClanHall _paidUntil: " + _paidUntil);
-					ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), _paidUntil - _time);
-					_paid = true;
-					updateDb();
-				}
-				else
-				{
-					_paid = false;
-					if (_time > _paidUntil + _chRate)
-					{
-						if (ClanHallManager.getInstance().loaded())
-						{
-							AuctionManager.getInstance().initNPC(getId());
-							ClanHallManager.getInstance().setFree(getId());
-							Clan.broadcastToOnlineMembers(SystemMessage.getSystemMessage(SystemMessageId.THE_CLAN_HALL_FEE_IS_ONE_WEEK_OVERDUE_THEREFORE_THE_CLAN_HALL_OWNERSHIP_HAS_BEEN_REVOKED));
-						}
-						else
-							ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), 3000);
-					}
-					else
-					{
-						updateDb();
-						SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.PAYMENT_FOR_YOUR_CLAN_HALL_HAS_NOT_BEEN_MADE_PLEASE_MAKE_PAYMENT_TO_YOUR_CLAN_WAREHOUSE_BY_S1_TOMORROW);
-						sm.addNumber(getLease());
-						Clan.broadcastToOnlineMembers(sm);
-						if (_time + (1000 * 60 * 60 * 24) <= _paidUntil + _chRate)
-							ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), _time + (1000 * 60 * 60 * 24));
-						else
-							ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), (_paidUntil + _chRate) - _time);
-						
-					}
-				}
-			}
-			catch (Exception e)
-			{
-				_log.log(Level.SEVERE, "", e);
-			}
-		}
+		return 0;
 	}
+	
+	public boolean isSiegableHall()
+	{
+		return false;
+	}
+	
+	public abstract void updateDb();
 }

+ 3 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/FortSiege.java

@@ -1206,4 +1206,7 @@ public class FortSiege implements Siegable
 	{
 		return Config.FORTRESS_ZONE_FAME_AQUIRE_POINTS;
 	}
+	
+	@Override
+	public void updateSiege() { }
 }

+ 2 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/Siegable.java

@@ -57,4 +57,6 @@ public interface Siegable
 	public boolean giveFame();
 	public int getFameFrequency();
 	public int getFameAmount();
+	
+	public void updateSiege();
 }

+ 3 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/Siege.java

@@ -1646,4 +1646,7 @@ public class Siege implements Siegable
 	{
 		return Config.CASTLE_ZONE_FAME_AQUIRE_POINTS;
 	}
+	
+	@Override
+	public void updateSiege() { }
 }

+ 214 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/clanhall/AuctionableHall.java

@@ -0,0 +1,214 @@
+/*
+ * 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.clanhall;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.util.logging.Level;
+
+import com.l2jserver.Config;
+import com.l2jserver.L2DatabaseFactory;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.datatables.ClanTable;
+import com.l2jserver.gameserver.instancemanager.AuctionManager;
+import com.l2jserver.gameserver.instancemanager.ClanHallManager;
+import com.l2jserver.gameserver.model.L2Clan;
+import com.l2jserver.gameserver.model.entity.ClanHall;
+import com.l2jserver.gameserver.network.SystemMessageId;
+import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.gameserver.templates.StatsSet;
+
+public final class AuctionableHall extends ClanHall
+{
+	private long _paidUntil;
+	private int _grade;
+	private boolean _paid;
+	private int _lease;
+	
+	protected final int _chRate = 604800000;
+	
+	public AuctionableHall(StatsSet set)
+	{
+		super(set);
+		_paidUntil = set.getLong("paidUntil");
+		_grade = set.getInteger("grade");
+		_paid = set.getBool("paid");
+		_lease = set.getInteger("lease");
+		
+		if(getOwnerId() != 0)
+		{
+			_isFree = false;
+			initialyzeTask(false);
+			loadFunctions();
+		}
+	}
+
+	/** Return if clanHall is paid or not */
+	public final boolean getPaid()
+	{
+		return _paid;
+	}
+	
+	/** Return lease*/
+	@Override
+	public final int getLease()
+	{
+		return _lease;
+	}
+	
+	/** Return PaidUntil */
+	@Override
+	public final long getPaidUntil()
+	{
+		return _paidUntil;
+	}
+	
+	/** Return Grade */
+	@Override
+	public final int getGrade()
+	{
+		return _grade;
+	}
+	
+	@Override
+	public final void free()
+	{
+		super.free();
+		_paidUntil = 0;
+		_paid = false;
+	}
+	
+	@Override
+	public final void setOwner(L2Clan clan)
+	{
+		super.setOwner(clan);
+		_paidUntil = System.currentTimeMillis();
+		initialyzeTask(true);
+	}
+	
+	/** Initialize Fee Task */
+	private final void initialyzeTask(boolean forced)
+	{
+		long currentTime = System.currentTimeMillis();
+		if (_paidUntil > currentTime)
+			ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), _paidUntil - currentTime);
+		else if (!_paid && !forced)
+		{
+			if (System.currentTimeMillis() + (1000 * 60 * 60 * 24) <= _paidUntil + _chRate)
+				ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), System.currentTimeMillis() + (1000 * 60 * 60 * 24));
+			else
+				ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), (_paidUntil + _chRate) - System.currentTimeMillis());
+		}
+		else
+			ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), 0);
+	}
+	
+	/** Fee Task */
+	private class FeeTask implements Runnable
+	{
+		public void run()
+		{
+			try
+			{
+				long _time = System.currentTimeMillis();
+				
+				if (_isFree)
+					return;
+				
+				if(_paidUntil > _time)
+				{
+					ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), _paidUntil - _time);
+					return;
+				}
+				
+				L2Clan Clan = ClanTable.getInstance().getClan(getOwnerId());
+				if (ClanTable.getInstance().getClan(getOwnerId()).getWarehouse().getAdena() >= getLease())
+				{
+					if (_paidUntil != 0)
+					{
+						while (_paidUntil <= _time)
+							_paidUntil += _chRate;
+					}
+					else
+						_paidUntil = _time + _chRate;
+					ClanTable.getInstance().getClan(getOwnerId()).getWarehouse().destroyItemByItemId("CH_rental_fee", 57, getLease(), null, null);
+					if (Config.DEBUG)
+						_log.warning("deducted " + getLease() + " adena from " + getName() + " owner's cwh for ClanHall _paidUntil: " + _paidUntil);
+					ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), _paidUntil - _time);
+					_paid = true;
+					updateDb();
+				}
+				else
+				{
+					_paid = false;
+					if (_time > _paidUntil + _chRate)
+					{
+						if (ClanHallManager.getInstance().loaded())
+						{
+							AuctionManager.getInstance().initNPC(getId());
+							ClanHallManager.getInstance().setFree(getId());
+							Clan.broadcastToOnlineMembers(SystemMessage.getSystemMessage(SystemMessageId.THE_CLAN_HALL_FEE_IS_ONE_WEEK_OVERDUE_THEREFORE_THE_CLAN_HALL_OWNERSHIP_HAS_BEEN_REVOKED));
+						}
+						else
+							ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), 3000);
+					}
+					else
+					{
+						updateDb();
+						SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.PAYMENT_FOR_YOUR_CLAN_HALL_HAS_NOT_BEEN_MADE_PLEASE_MAKE_PAYMENT_TO_YOUR_CLAN_WAREHOUSE_BY_S1_TOMORROW);
+						sm.addNumber(getLease());
+						Clan.broadcastToOnlineMembers(sm);
+						if (_time + (1000 * 60 * 60 * 24) <= _paidUntil + _chRate)
+							ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), _time + (1000 * 60 * 60 * 24));
+						else
+							ThreadPoolManager.getInstance().scheduleGeneral(new FeeTask(), (_paidUntil + _chRate) - _time);
+						
+					}
+				}
+			}
+			catch (Exception e)
+			{
+				_log.log(Level.SEVERE, "", e);
+			}
+		}
+	}
+	
+	@Override
+	public final void updateDb()
+	{
+		Connection con = null;
+		try
+		{
+			con = L2DatabaseFactory.getInstance().getConnection();
+			PreparedStatement statement;
+			
+			statement = con.prepareStatement("UPDATE clanhall SET ownerId=?, paidUntil=?, paid=? WHERE id=?");
+			statement.setInt(1, getOwnerId());
+			statement.setLong(2, getPaidUntil());
+			statement.setInt(3, (getPaid()) ? 1 : 0);
+			statement.setInt(4, getId());
+			statement.execute();
+			statement.close();
+		}
+		catch (Exception e)
+		{
+			_log.log(Level.WARNING, "Exception: updateOwnerInDB(L2Clan clan): " + e.getMessage(), e);
+		}
+		finally
+		{
+			L2DatabaseFactory.close(con);
+		}
+	}
+}

+ 521 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/clanhall/ClanHallSiegeEngine.java

@@ -0,0 +1,521 @@
+/*
+ * 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.clanhall;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.Calendar;
+import java.util.List;
+import java.util.concurrent.ScheduledFuture;
+import java.util.logging.Logger;
+
+import javolution.util.FastList;
+import javolution.util.FastMap;
+
+import com.l2jserver.Config;
+import com.l2jserver.L2DatabaseFactory;
+import com.l2jserver.gameserver.Announcements;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.datatables.ClanTable;
+import com.l2jserver.gameserver.datatables.NpcTable;
+import com.l2jserver.gameserver.instancemanager.CHSiegeManager;
+import com.l2jserver.gameserver.instancemanager.MapRegionManager;
+import com.l2jserver.gameserver.model.L2Clan;
+import com.l2jserver.gameserver.model.L2MapRegion;
+import com.l2jserver.gameserver.model.L2SiegeClan;
+import com.l2jserver.gameserver.model.L2Spawn;
+import com.l2jserver.gameserver.model.L2World;
+import com.l2jserver.gameserver.model.L2SiegeClan.SiegeClanType;
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.Siegable;
+import com.l2jserver.gameserver.model.quest.Quest;
+import com.l2jserver.gameserver.network.NpcStringId;
+import com.l2jserver.gameserver.network.SystemMessageId;
+import com.l2jserver.gameserver.network.serverpackets.NpcSay;
+import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
+
+/**
+ * @author BiggBoss
+ */
+public abstract class ClanHallSiegeEngine extends Quest implements Siegable
+{	
+	private static final String SQL_LOAD_ATTACKERS = "SELECT attacker_id FROM clanhall_siege_attackers WHERE clanhall_id = ?";
+	private static final String SQL_SAVE_ATTACKERS = "INSERT INTO clanhall_siege_attackers VALUES (?,?)";
+	private static final String SQL_LOAD_GUARDS = "SELECT * FROM clanhall_siege_guards WHERE clanHallId = ?";
+
+	public static final int DEVASTATED_CASTLE = 34;
+	public static final int BANDIT_STRONGHOLD = 35;
+	public static final int FORTRESS_RESSISTANCE = 21;
+	public static final int FORTRESS_OF_DEAD = 64;
+	public static final int RAINBOW_SPRINGS = 62;
+	
+	protected final Logger _log;
+	
+	private FastMap<Integer, L2SiegeClan> _attackers = new FastMap<Integer, L2SiegeClan>();
+	private FastList<L2Spawn> _guards;
+
+	protected SiegableHall _hall;
+	protected ScheduledFuture<?> _siegeTask;
+	protected boolean _missionAccomplished = false;
+	
+	public ClanHallSiegeEngine(int questId, String name, String descr, final int hallId)
+	{
+		super(questId, name, descr);
+		_log = Logger.getLogger(getClass().getName());
+		
+		_hall = CHSiegeManager.getInstance().getSiegableHall(hallId);
+		_hall.setSiege(this);
+
+		long delay = _hall.getNextSiegeTime();
+		if(delay == -1)
+			_log.warning(_hall.getName()+": No date setted for siege!");
+		else
+			_siegeTask = ThreadPoolManager.getInstance().scheduleGeneral(new PrepareOwner(), delay - System.currentTimeMillis() - 3600000);
+		loadAttackers();
+	}
+	
+	private final void loadAttackers()
+	{
+		// XXX
+		if(_hall.getId() == 63)
+			return;;
+		
+		Connection con = null;
+		try
+		{
+			con = L2DatabaseFactory.getInstance().getConnection();
+			PreparedStatement statement = con.prepareStatement(SQL_LOAD_ATTACKERS);
+			statement.setInt(1, _hall.getId());
+			ResultSet rset = statement.executeQuery();
+			while(rset.next())
+			{
+				final int id = rset.getInt("attacker_id");
+				L2SiegeClan clan = new L2SiegeClan(id, SiegeClanType.ATTACKER);
+				_attackers.put(id, clan);
+			}
+			rset.close();
+			statement.close();
+		}
+		catch(Exception e)
+		{
+			_log.warning(getName()+": Could not load siege attackers!:");
+			e.printStackTrace();
+		}
+		finally
+		{
+			L2DatabaseFactory.close(con);
+		}
+	}
+	
+	public final void saveAttackers()
+	{
+		Connection con = null;
+		try
+		{
+			con = L2DatabaseFactory.getInstance().getConnection();
+			
+			PreparedStatement delStatement = con.prepareStatement("DELETE FROM clanhall_siege_attackers WHERE clanhall_id = ?");
+			delStatement.setInt(1, _hall.getId());
+			delStatement.execute();
+			delStatement.close();
+			
+			if(getAttackers().size() > 0)
+			{
+				for(L2SiegeClan clan : getAttackers().values())
+				{
+					PreparedStatement insert = con.prepareStatement(SQL_SAVE_ATTACKERS);
+					insert.setInt(1, _hall.getId());
+					insert.setInt(2, clan.getClanId());
+					insert.execute();
+					insert.close();
+				}
+			}
+			_log.config(getName()+": Sucessfully saved attackers down to database!");
+		}
+		catch(Exception e)
+		{
+			_log.warning(getName()+": Couldnt save attacker list!");
+			e.printStackTrace();
+		}
+		finally
+		{
+			L2DatabaseFactory.close(con);
+		}
+	}
+	
+	public final void loadGuards()
+	{
+		if(_guards == null)
+		{
+			_guards = new FastList<L2Spawn>();
+		
+			Connection con = null;
+			try
+			{
+				con = L2DatabaseFactory.getInstance().getConnection();
+				PreparedStatement statement = con.prepareStatement(SQL_LOAD_GUARDS);
+				statement.setInt(1, _hall.getId());
+				ResultSet rset = statement.executeQuery();
+				while(rset.next())
+				{
+					final int npcId = rset.getInt("npcId");
+					final L2NpcTemplate template = NpcTable.getInstance().getTemplate(npcId);
+					L2Spawn spawn = new L2Spawn(template);
+					spawn.setLocx(rset.getInt("x"));
+					spawn.setLocy(rset.getInt("y"));
+					spawn.setLocz(rset.getInt("z"));
+					spawn.setHeading(rset.getInt("heading"));
+					spawn.setRespawnDelay(rset.getInt("respawnDelay"));
+					spawn.setAmount(1);
+					_guards.add(spawn);
+				}
+				rset.close();
+				statement.close();
+			}
+			catch(Exception e)
+			{
+				_log.warning(getName()+": Couldnt load siege guards!:");
+				e.printStackTrace();
+			}
+			finally
+			{
+				L2DatabaseFactory.close(con);
+			}
+		}
+	}
+	
+	private final void spawnSiegeGuards()
+	{
+		for(L2Spawn guard : _guards)
+			if(guard != null)
+				guard.init();
+	}
+	
+	private final void unSpawnSiegeGuards()
+	{
+		if(_guards != null && _guards.size() > 0)
+		{
+			for(L2Spawn guard : _guards)
+			{
+				if(guard != null)
+				{
+					guard.stopRespawn();
+					guard.getLastSpawn().deleteMe();
+				}
+			}
+		}
+	}
+	
+	public final FastMap<Integer, L2SiegeClan> getAttackers()
+	{
+		return _attackers;
+	}
+
+	@Override
+	public boolean checkIsAttacker(L2Clan clan)
+	{
+		if(clan == null)
+			return false;
+		
+		return _attackers.containsKey(clan.getClanId());
+	}
+
+	@Override
+	public boolean checkIsDefender(L2Clan clan)
+	{
+		return false;
+	}
+	
+	@Override
+	public L2SiegeClan getAttackerClan(int clanId)
+	{
+		return _attackers.get(clanId);
+	}
+
+	@Override
+	public L2SiegeClan getAttackerClan(L2Clan clan)
+	{
+		return getAttackerClan(clan.getClanId());
+	}
+
+	@Override
+	public List<L2SiegeClan> getAttackerClans()
+	{
+		FastList<L2SiegeClan> result = new FastList<L2SiegeClan>();
+		result.addAll(_attackers.values());
+		return result;
+	}
+	
+	@Override
+	public L2SiegeClan getDefenderClan(int clanId)
+	{
+		return null;
+	}
+
+	@Override
+	public L2SiegeClan getDefenderClan(L2Clan clan)
+	{
+		return null;
+	}
+
+	@Override
+	public List<L2SiegeClan> getDefenderClans()
+	{
+		return null;
+	}
+
+	@Override
+	public void endSiege()
+	{
+		SystemMessage end = SystemMessage.getSystemMessage(SystemMessageId.SIEGE_OF_S1_HAS_ENDED);
+		end.addString(_hall.getName());
+		Announcements.getInstance().announceToAll(end);
+
+		L2Clan winner = null;
+		if(_missionAccomplished)
+		{
+			winner = getWinner();
+			if(winner != null)
+			{
+				_hall.setOwner(winner);
+				winner.setHasHideout(_hall.getId());
+			}
+		}
+		_missionAccomplished = false;
+		
+		SystemMessage winnerMsg = null;
+		if(winner != null)
+		{
+			winnerMsg = SystemMessage.getSystemMessage(SystemMessageId.CLAN_S1_VICTORIOUS_OVER_S2_S_SIEGE);
+			winnerMsg.addString(winner.getName());
+			winnerMsg.addString(_hall.getName());
+			Announcements.getInstance().announceToAll(winnerMsg);
+		}
+		else
+		{
+			winnerMsg = SystemMessage.getSystemMessage(SystemMessageId.SIEGE_S1_DRAW);
+			winnerMsg.addString(_hall.getName());
+			Announcements.getInstance().announceToAll(winnerMsg);
+
+		}
+		
+		_hall.updateSiegeZone(false);
+		_hall.updateNextSiege();
+		_hall.spawnDoor(false);
+		_hall.banishForeigners();
+		
+		final byte state = 0;
+		for(L2SiegeClan sClan : getAttackerClans())
+		{
+			final L2Clan clan = ClanTable.getInstance().getClan(sClan.getClanId());
+			if(clan == null)
+				continue;
+			
+			for(L2PcInstance player : clan.getOnlineMembers(0))
+			{
+				player.setSiegeState(state);
+				player.broadcastUserInfo();
+			}
+		}
+		
+		// Update pvp flag for winners when siege zone becomes unactive
+		for(L2Character cha : (L2Character[])_hall.getSiegeZone().getCharactersInside().getValues())
+			if(cha != null && cha instanceof L2PcInstance)
+				((L2PcInstance)cha).startPvPFlag();
+		
+		getAttackers().clear();
+		
+		onSiegeEnds();
+			
+		_siegeTask = ThreadPoolManager.getInstance().scheduleGeneral(new PrepareOwner(), _hall.getNextSiegeTime() - System.currentTimeMillis() - 3600000);
+		_log.config("Siege of "+_hall.getName()+" scheduled for: "+_hall.getSiegeDate().getTime());
+		
+		_hall.updateSiegeStatus(SiegeStatus.REGISTERING);
+		unSpawnSiegeGuards();
+	}
+
+	@Override
+	public List<L2PcInstance> getAttackersInZone()
+	{
+		final FastList<L2PcInstance> list = _hall.getSiegeZone().getAllPlayers();
+		FastList<L2PcInstance> attackers = new FastList<L2PcInstance>();
+		
+		for(L2PcInstance pc : list)
+		{
+			final L2Clan clan = pc.getClan();
+			if(clan != null && _hall.getAttackers().contains(clan))
+				attackers.add(pc);
+		}
+		
+		return attackers;
+	}
+
+	@Override
+	public int getFameAmount()
+	{
+		return Config.CHS_FAME_AMOUNT;
+	}
+
+	@Override
+	public int getFameFrequency()
+	{
+		return Config.CHS_FAME_FREQUENCY;
+	}
+
+	@Override
+	public List<L2Npc> getFlag(L2Clan clan)
+	{
+		List<L2Npc> result = null;
+		L2SiegeClan sClan = getAttackerClan(clan);
+		if(sClan != null)
+			result = sClan.getFlag();
+		return result;
+	}
+
+	@Override
+	public Calendar getSiegeDate()
+	{
+		return _hall.getSiegeDate();
+	}
+
+	@Override
+	public boolean giveFame()
+	{
+		return Config.CHS_ENABLE_FAME;
+	}
+
+	@Override
+	public void startSiege()
+	{		
+		if(_hall.getAttackers().size() < 1 && _hall.getId() != 21) // Fortress of resistance dont have attacker list
+		{
+			onSiegeEnds();
+			getAttackers().clear();
+			_hall.updateNextSiege();
+			SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.SIEGE_OF_S1_HAS_BEEN_CANCELED_DUE_TO_LACK_OF_INTEREST);
+			sm.addString(_hall.getName());
+			Announcements.getInstance().announceToAll(sm);
+			return;
+		}
+		
+		_hall.banishForeigners();
+		_hall.spawnDoor();
+		loadGuards();
+		spawnSiegeGuards();
+		_hall.updateSiegeZone(true);
+		
+		final byte state = 1;
+		for(L2SiegeClan sClan : getAttackerClans())
+		{
+			final L2Clan clan = ClanTable.getInstance().getClan(sClan.getClanId());
+			if(clan == null)
+				continue;
+
+			for(L2PcInstance pc : clan.getOnlineMembers(0))
+			{
+				if(pc != null)
+				{
+					pc.setSiegeState(state);
+					pc.broadcastUserInfo();
+				}
+			}
+		}
+		
+		_hall.updateSiegeStatus(SiegeStatus.RUNNING);
+
+		onSiegeStarts();
+		
+		_siegeTask = ThreadPoolManager.getInstance().scheduleGeneral(new SiegeEnds(),_hall.getSiegeLenght());
+	}
+	
+	@Override
+	public void updateSiege()
+	{
+		cancelSiegeTask();
+		_siegeTask = ThreadPoolManager.getInstance().scheduleGeneral(new PrepareOwner(), _hall.getNextSiegeTime() - 3600000);
+		_log.config(_hall.getName()+" siege scheduled for: "+_hall.getSiegeDate().getTime().toString());
+	}
+	
+	public abstract L2Clan getWinner(); 
+	public void onSiegeStarts() {}
+	public void onSiegeEnds()  {}
+	
+	public void cancelSiegeTask()
+	{
+		if(_siegeTask != null)
+			_siegeTask.cancel(false);
+	}
+	
+	public final void broadcastNpcSay(final L2Npc npc, final int type, final int messageId)
+	{
+		final NpcSay npcSay = new NpcSay(npc.getObjectId(), type, npc.getNpcId(), NpcStringId.getNpcStringId(messageId));
+		final L2MapRegion sourceRegion = MapRegionManager.getInstance().getMapRegion(npc.getX(), npc.getY());
+		L2PcInstance[] charsInside = (L2PcInstance[])L2World.getInstance().getAllPlayers().getValues();
+		
+		for(L2PcInstance pc : charsInside)
+			if(pc != null && MapRegionManager.getInstance().getMapRegion(pc.getX(), pc.getY()) == sourceRegion)
+				pc.sendPacket(npcSay);
+	}
+	
+	public class PrepareOwner implements Runnable
+	{
+		@Override
+		public void run()
+		{
+			if(_hall.getOwnerId() > 0)
+			{
+				final L2SiegeClan clan = new L2SiegeClan(_hall.getOwnerId(), SiegeClanType.ATTACKER);
+				_hall.getAttackers().add(clan);
+			}
+			
+			_hall.free();
+			
+			SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.REGISTRATION_TERM_FOR_S1_ENDED);
+			msg.addString(getName());
+			Announcements.getInstance().announceToAll(msg);
+			_hall.updateSiegeStatus(SiegeStatus.WAITING_BATTLE);
+			
+			if(_hall.getId() == 35)
+			{
+				_hall.getDoor(22170001).openMe();
+				_hall.getDoor(22170002).openMe();
+			}
+			
+			_siegeTask = ThreadPoolManager.getInstance().scheduleGeneral(new SiegeStarts(), 3600000);
+		}
+	}
+	
+	public class SiegeStarts implements Runnable
+	{
+		@Override
+		public void run()
+		{
+			startSiege();
+		}
+	}
+	
+	public class SiegeEnds implements Runnable
+	{
+		@Override
+		public void run()
+		{
+			endSiege();
+		}
+	}
+}

+ 272 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/clanhall/SiegableHall.java

@@ -0,0 +1,272 @@
+/*
+ * 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.clanhall;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.List;
+import java.util.logging.Level;
+
+import javolution.util.FastList;
+import javolution.util.FastMap;
+
+import com.l2jserver.L2DatabaseFactory;
+import com.l2jserver.gameserver.datatables.DoorTable;
+import com.l2jserver.gameserver.model.L2Clan;
+import com.l2jserver.gameserver.model.L2SiegeClan;
+import com.l2jserver.gameserver.model.L2SiegeClan.SiegeClanType;
+import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.entity.ClanHall;
+import com.l2jserver.gameserver.model.zone.type.L2SiegeZone;
+import com.l2jserver.gameserver.network.serverpackets.SiegeInfo;
+import com.l2jserver.gameserver.templates.StatsSet;
+
+/**
+ * @author BiggBoss
+ */
+public final class SiegableHall extends ClanHall
+{	
+	private static final String SQL_SAVE = "UPDATE siegable_clanhall SET ownerId=?, nextSiege=? WHERE clanHallId=?";
+		
+	protected List<String> _doorDefault;
+	
+	private Calendar _nextSiege;
+	private long _siegeLength;
+	private int[] _scheduleConfig = {7,0,0,12,0};
+	
+	private SiegeStatus _status = SiegeStatus.REGISTERING;
+	private L2SiegeZone _siegeZone;
+	
+	private ClanHallSiegeEngine _siege;
+	
+	public SiegableHall(StatsSet set)
+	{
+		super(set);
+		_doorDefault = new FastList<String>();
+		_siegeLength = set.getLong("siegeLenght");
+		String[] rawSchConfig = set.getString("scheduleConfig").split(";");
+		if(rawSchConfig.length == 5)
+		{
+			for(int i = 0; i < 5; i++)
+			{
+				try
+				{
+					_scheduleConfig[i] = Integer.parseInt(rawSchConfig[i]);
+				}
+				catch(Exception e)
+				{
+					_log.warning("SiegableHall - "+getName()+": Wrong schedule_config parameters!");
+				}
+			}
+		}
+		else
+			_log.warning(getName()+": Wrong schedule_config value in siegable_halls table, using default (7 days)");
+		
+		_nextSiege = Calendar.getInstance();
+		long nextSiege = set.getLong("nextSiege");
+		if(nextSiege - System.currentTimeMillis() < 0)
+			updateNextSiege();
+		else
+			_nextSiege.setTimeInMillis(nextSiege);
+		_log.config(getName()+" siege scheduled for: "+_nextSiege.getTime());		
+	}
+			
+	public List<String> getDoorDefault()
+	{
+		return _doorDefault;
+	}
+	
+	public void spawnDoor()
+	{
+		spawnDoor(false);
+	}
+	
+	public void spawnDoor(boolean isDoorWeak)
+	{
+		for (int i = 0; i < getDoors().size(); i++)
+		{
+			L2DoorInstance door = getDoors().get(i);
+			if (door.getCurrentHp() <= 0)
+			{
+				door.decayMe(); // Kill current if not killed already
+				door = DoorTable.parseList(_doorDefault.get(i), false);
+				DoorTable.getInstance().putDoor(door); //Readd the new door to the DoorTable By Erb
+				if (isDoorWeak)
+					door.setCurrentHp(door.getMaxHp() / 2);
+				door.spawnMe(door.getX(), door.getY(), door.getZ());
+				getDoors().set(i, door);
+			}
+			else if (door.getOpen())
+				door.closeMe();
+		}
+	}
+		
+	@Override
+	public final void updateDb()
+	{
+		Connection con = null;
+		try
+		{
+			con = L2DatabaseFactory.getInstance().getConnection();
+			PreparedStatement statement;
+			
+			statement = con.prepareStatement(SQL_SAVE);
+			statement.setInt(1, getOwnerId());
+			statement.setLong(2, getNextSiegeTime());
+			statement.setInt(3, getId());
+			statement.execute();
+			statement.close();
+		}
+		catch (Exception e)
+		{
+			_log.log(Level.WARNING, "Exception: SiegableHall.updateDb(): " + e.getMessage(), e);
+		}
+		finally
+		{
+			L2DatabaseFactory.close(con);
+		}
+	}
+	
+	public final void setSiege(final ClanHallSiegeEngine siegable)
+	{
+		_siege = siegable;
+		_siegeZone.setSiegeInstance(siegable);
+	}
+	
+	public final ClanHallSiegeEngine getSiege()
+	{
+		return _siege;
+	}
+	
+	public final Calendar getSiegeDate()
+	{
+		return _nextSiege;
+	}
+	
+	public final long getNextSiegeTime()
+	{
+		return _nextSiege.getTimeInMillis();
+	}
+	
+	public long getSiegeLenght()
+	{
+		return _siegeLength;
+	}
+	
+	public final void setNextSiegeDate(long date)
+	{
+		_nextSiege.setTimeInMillis(date);
+	}
+	
+	public final void setNextSiegeDate(final Calendar c)
+	{
+		_nextSiege = c;
+	}
+	
+	public final void updateNextSiege()
+	{
+		Calendar c = Calendar.getInstance();
+		c.add(Calendar.DAY_OF_YEAR, _scheduleConfig[0]);
+		c.add(Calendar.MONTH, _scheduleConfig[1]);
+		c.add(Calendar.YEAR, _scheduleConfig[2]);
+		c.set(Calendar.HOUR_OF_DAY, _scheduleConfig[3]);
+		c.set(Calendar.MINUTE, _scheduleConfig[4]);
+		c.set(Calendar.SECOND, 0);
+		setNextSiegeDate(c);
+		updateDb();
+	}
+	
+	public final FastMap<Integer, L2SiegeClan> getAttackersList()
+	{
+		return getSiege().getAttackers();
+	}
+	
+	public final Collection<L2SiegeClan> getAttackers()
+	{
+		return getSiege().getAttackers().values();
+	}
+	
+	public final void addAttacker(final L2Clan clan)
+	{
+		getSiege().getAttackers().put(clan.getClanId(), new L2SiegeClan(clan.getClanId(), SiegeClanType.ATTACKER));
+	}
+	
+	public final void removeAttacker(final L2Clan clan)
+	{
+		getSiege().getAttackers().remove(clan.getClanId());
+	}
+	
+	public final boolean isRegistered(L2Clan clan)
+	{
+		if(getSiege() == null)
+			return false;
+		
+		return getSiege().checkIsAttacker(clan);
+	}
+	
+	public final void clearAttackers()
+	{
+		getSiege().getAttackers().clear();
+	}
+	
+	public final boolean isRegistering() 
+	{ 
+		return _status == SiegeStatus.REGISTERING; 
+	}
+	
+	public final boolean isInSiege() 
+	{ 
+		return _status == SiegeStatus.RUNNING; 
+	}
+	
+	public final boolean isWaitingBattle() 
+	{ 
+		return _status == SiegeStatus.WAITING_BATTLE; 
+	}
+	
+	public final void updateSiegeStatus(SiegeStatus status)
+	{
+		_status = status;
+	}
+	
+	public final L2SiegeZone getSiegeZone()
+	{
+		return _siegeZone;
+	}
+	
+	public final void setSiegeZone(L2SiegeZone zone)
+	{
+		_siegeZone = zone;
+	}
+
+	public final void updateSiegeZone(boolean active)
+	{
+		_siegeZone.setIsActive(active);
+	}	
+
+	public final void showSiegeInfo(L2PcInstance player)
+	{
+		player.sendPacket(new SiegeInfo(this));
+	}
+			
+	@Override
+	public final boolean isSiegableHall()
+	{
+		return true;
+	}
+}

+ 26 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/entity/clanhall/SiegeStatus.java

@@ -0,0 +1,26 @@
+/*
+ * 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.clanhall;
+
+/**
+ * @author BiggBoss
+ *
+ */
+public enum SiegeStatus
+{
+	REGISTERING,
+	WAITING_BATTLE,
+	RUNNING
+}

+ 22 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/model/quest/Quest.java

@@ -51,6 +51,7 @@ import com.l2jserver.gameserver.network.serverpackets.NpcQuestHtmlMessage;
 import com.l2jserver.gameserver.scripting.ManagedScript;
 import com.l2jserver.gameserver.scripting.ScriptManager;
 import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
+import com.l2jserver.gameserver.templates.item.L2Item;
 import com.l2jserver.gameserver.util.MinionList;
 import com.l2jserver.util.Rnd;
 import com.l2jserver.util.Util;
@@ -162,7 +163,8 @@ public class Quest extends ManagedScript
 		ON_SKILL_LEARN(false), // control the AcquireSkill dialog from quest script
 		ON_ENTER_ZONE(true), // on zone enter
 		ON_EXIT_ZONE(true), // on zone exit
-		ON_TRAP_ACTION(true); // on zone exit
+		ON_TRAP_ACTION(true), // on zone exit
+		ON_ITEM_USE(true);
 		
 		
 		// control whether this event type is allowed for the same npc template in multiple quests
@@ -387,6 +389,20 @@ public class Quest extends ManagedScript
 		return showResult(qs.getPlayer(), res);
 	}
 	
+	public final boolean notifyItemUse(L2Item item, L2PcInstance player)
+	{
+		String res = null;
+		try
+		{
+			res = onItemUse(item, player);
+		}
+		catch(Exception e)
+		{
+			return showError(player, e);
+		}
+		return showResult(player, res);
+	}
+	
 	public final boolean notifySpellFinished(L2Npc instance, L2PcInstance player, L2Skill skill)
 	{
 		String res = null;
@@ -754,6 +770,11 @@ public class Quest extends ManagedScript
 		return null;
 	}
 	
+	public String onItemUse(L2Item item, L2PcInstance player)
+	{
+		return null;
+	}
+	
 	public String onSkillSee(L2Npc npc, L2PcInstance caster, L2Skill skill, L2Object[] targets, boolean isPet)
 	{
 		return null;

+ 7 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/model/zone/type/L2ClanHallZone.java

@@ -19,6 +19,7 @@ import com.l2jserver.gameserver.instancemanager.MapRegionManager;
 import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.entity.ClanHall;
+import com.l2jserver.gameserver.model.entity.clanhall.AuctionableHall;
 import com.l2jserver.gameserver.model.zone.L2ZoneRespawn;
 import com.l2jserver.gameserver.network.serverpackets.AgitDecoInfo;
 
@@ -43,7 +44,11 @@ public class L2ClanHallZone extends L2ZoneRespawn
 		{
 			_clanHallId = Integer.parseInt(value);
 			// Register self to the correct clan hall
-			ClanHallManager.getInstance().getClanHallById(_clanHallId).setZone(this);
+			ClanHall hall = ClanHallManager.getInstance().getClanHallById(_clanHallId);
+			if(hall == null)
+				_log.warning("L2ClanHallZone: Clan hall with id "+_clanHallId+" does not exist!");
+			else
+				hall.setZone(this);
 		}
 		else
 			super.setParameter(name, value);
@@ -57,7 +62,7 @@ public class L2ClanHallZone extends L2ZoneRespawn
 			// Set as in clan hall
 			character.setInsideZone(L2Character.ZONE_CLANHALL, true);
 			
-			ClanHall clanHall = ClanHallManager.getInstance().getClanHallById(_clanHallId);
+			AuctionableHall clanHall = ClanHallManager.getInstance().getAuctionableHallById(_clanHallId);
 			if (clanHall == null)
 				return;
 			

+ 8 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/model/zone/type/L2SiegeZone.java

@@ -18,6 +18,7 @@ import javolution.util.FastList;
 
 import com.l2jserver.Config;
 import com.l2jserver.gameserver.datatables.SkillTable;
+import com.l2jserver.gameserver.instancemanager.CHSiegeManager;
 import com.l2jserver.gameserver.instancemanager.FortManager;
 import com.l2jserver.gameserver.instancemanager.FortSiegeManager;
 import com.l2jserver.gameserver.instancemanager.MapRegionManager;
@@ -30,6 +31,7 @@ import com.l2jserver.gameserver.model.actor.instance.L2SiegeSummonInstance;
 import com.l2jserver.gameserver.model.entity.Fort;
 import com.l2jserver.gameserver.model.entity.FortSiege;
 import com.l2jserver.gameserver.model.entity.Siegable;
+import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
 import com.l2jserver.gameserver.model.zone.L2ZoneType;
 import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
@@ -71,7 +73,11 @@ public class L2SiegeZone extends L2ZoneType
 			if (_siegableId != -1)
 				throw new IllegalArgumentException("Siege object already defined!");
 			_siegableId = Integer.parseInt(value);
-			//TODO clan hall siege
+			SiegableHall hall = CHSiegeManager.getInstance().getConquerableHalls().get(_siegableId);
+			if(hall == null)
+				_log.warning("L2SiegeZone: Siegable clan hall with id "+ value + " does not exist!");
+			else
+				hall.setSiegeZone(this);
 		}
 		else
 			super.setParameter(name, value);
@@ -92,7 +98,7 @@ public class L2SiegeZone extends L2ZoneType
 				if (((L2PcInstance) character).isRegisteredOnThisSiegeField(_siegableId))
 				{
 					((L2PcInstance) character).setIsInSiege(true); // in siege
-					if (_siege.giveFame())
+					if (_siege.giveFame() && _siege.getFameFrequency() > 0)
 						((L2PcInstance) character).startFameTask(_siege.getFameFrequency() * 1000, _siege.getFameAmount());
 				}
 				((L2PcInstance) character).sendPacket(SystemMessage.getSystemMessage(SystemMessageId.ENTERED_COMBAT_ZONE));

+ 16 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/EnterWorld.java

@@ -28,6 +28,7 @@ import com.l2jserver.gameserver.communitybbs.Manager.RegionBBSManager;
 import com.l2jserver.gameserver.datatables.AdminCommandAccessRights;
 import com.l2jserver.gameserver.datatables.GMSkillTable;
 import com.l2jserver.gameserver.datatables.SkillTable;
+import com.l2jserver.gameserver.instancemanager.CHSiegeManager;
 import com.l2jserver.gameserver.instancemanager.CastleManager;
 import com.l2jserver.gameserver.instancemanager.ClanHallManager;
 import com.l2jserver.gameserver.instancemanager.CoupleManager;
@@ -49,13 +50,14 @@ import com.l2jserver.gameserver.model.L2World;
 import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.actor.instance.L2ClassMasterInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-import com.l2jserver.gameserver.model.entity.ClanHall;
 import com.l2jserver.gameserver.model.entity.Couple;
 import com.l2jserver.gameserver.model.entity.Fort;
 import com.l2jserver.gameserver.model.entity.FortSiege;
 import com.l2jserver.gameserver.model.entity.L2Event;
 import com.l2jserver.gameserver.model.entity.Siege;
 import com.l2jserver.gameserver.model.entity.TvTEvent;
+import com.l2jserver.gameserver.model.entity.clanhall.AuctionableHall;
+import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
 import com.l2jserver.gameserver.model.quest.Quest;
 import com.l2jserver.gameserver.model.quest.QuestState;
 import com.l2jserver.gameserver.network.SystemMessageId;
@@ -203,7 +205,7 @@ public class EnterWorld extends L2GameClientPacket
 			
 			notifySponsorOrApprentice(activeChar);
 			
-			ClanHall clanHall = ClanHallManager.getInstance().getClanHallByOwner(activeChar.getClan());
+			AuctionableHall clanHall = ClanHallManager.getInstance().getClanHallByOwner(activeChar.getClan());
 			
 			if (clanHall != null)
 			{
@@ -247,6 +249,18 @@ public class EnterWorld extends L2GameClientPacket
 				}
 			}
 			
+			for(SiegableHall hall : CHSiegeManager.getInstance().getConquerableHalls().values())
+			{
+				if(!hall.isInSiege())
+					continue;
+				
+				if(hall.isRegistered(activeChar.getClan()))
+				{
+					activeChar.setSiegeState((byte)1);
+					activeChar.setSiegeSide(hall.getId());
+				}
+			}
+			
 			sendPacket(new PledgeShowMemberListAll(activeChar.getClan(), activeChar));
 			sendPacket(new PledgeStatusChanged(activeChar.getClan()));
 			

+ 32 - 11
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestJoinSiege.java

@@ -15,11 +15,14 @@
 
 package com.l2jserver.gameserver.network.clientpackets;
 
+import com.l2jserver.gameserver.instancemanager.CHSiegeManager;
 import com.l2jserver.gameserver.instancemanager.CastleManager;
 import com.l2jserver.gameserver.model.L2Clan;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.entity.Castle;
+import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
 import com.l2jserver.gameserver.network.SystemMessageId;
+import com.l2jserver.gameserver.network.serverpackets.SiegeInfo;
 import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
 
 /**
@@ -58,23 +61,41 @@ public final class RequestJoinSiege extends L2GameClientPacket
 		if (clan == null) return;
 		
 		Castle castle = CastleManager.getInstance().getCastleById(_castleId);
-		if (castle == null)	return;
+		if (castle != null)
+		{
+			if (_isJoining == 1)
+			{
+				if (System.currentTimeMillis() < clan.getDissolvingExpiryTime())
+				{
+					activeChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.CANT_PARTICIPATE_IN_SIEGE_WHILE_DISSOLUTION_IN_PROGRESS));
+					return;
+				}
+				if (_isAttacker == 1)
+					castle.getSiege().registerAttacker(activeChar);
+				else
+					castle.getSiege().registerDefender(activeChar);
+			}
+			else
+				castle.getSiege().removeSiegeClan(activeChar);
+			castle.getSiege().listRegisterClan(activeChar);
+		}
 		
-		if (_isJoining == 1)
+		SiegableHall hall = CHSiegeManager.getInstance().getSiegableHall(_castleId);
+		if(hall != null)
 		{
-			if (System.currentTimeMillis() < clan.getDissolvingExpiryTime())
+			if (_isJoining == 1)
 			{
-				activeChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.CANT_PARTICIPATE_IN_SIEGE_WHILE_DISSOLUTION_IN_PROGRESS));
-				return;
+				if (System.currentTimeMillis() < clan.getDissolvingExpiryTime())
+				{
+					activeChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.CANT_PARTICIPATE_IN_SIEGE_WHILE_DISSOLUTION_IN_PROGRESS));
+					return;
+				}
+				CHSiegeManager.getInstance().registerClan(clan, hall, activeChar);
 			}
-			if (_isAttacker == 1)
-				castle.getSiege().registerAttacker(activeChar);
 			else
-				castle.getSiege().registerDefender(activeChar);
+				CHSiegeManager.getInstance().unRegisterClan(clan, hall);
+			activeChar.sendPacket(new SiegeInfo(hall));
 		}
-		else
-			castle.getSiege().removeSiegeClan(activeChar);
-		castle.getSiege().listRegisterClan(activeChar);
 	}
 	
 	@Override

+ 6 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestRestartPoint.java

@@ -17,6 +17,7 @@ package com.l2jserver.gameserver.network.clientpackets;
 import java.util.logging.Logger;
 
 import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.instancemanager.CHSiegeManager;
 import com.l2jserver.gameserver.instancemanager.CastleManager;
 import com.l2jserver.gameserver.instancemanager.ClanHallManager;
 import com.l2jserver.gameserver.instancemanager.FortManager;
@@ -30,6 +31,7 @@ import com.l2jserver.gameserver.model.entity.Castle;
 import com.l2jserver.gameserver.model.entity.ClanHall;
 import com.l2jserver.gameserver.model.entity.Fort;
 import com.l2jserver.gameserver.model.entity.TvTEvent;
+import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
 
 /**
  * This class ...
@@ -65,6 +67,7 @@ public final class RequestRestartPoint extends L2GameClientPacket
 			Location loc = null;
 			Castle castle = null;
 			Fort fort = null;
+			SiegableHall hall = null;
 			boolean isInDefense = false;
 			int instanceId = 0;
 			
@@ -144,13 +147,15 @@ public final class RequestRestartPoint extends L2GameClientPacket
 					L2SiegeClan siegeClan = null;
 					castle = CastleManager.getInstance().getCastle(activeChar);
 					fort = FortManager.getInstance().getFort(activeChar);
+					hall = CHSiegeManager.getInstance().getNearbyClanHall(activeChar);
 					L2SiegeFlagInstance flag = TerritoryWarManager.getInstance().getFlagForClan(activeChar.getClan());
 					
 					if (castle != null && castle.getSiege().getIsInProgress())
 						siegeClan = castle.getSiege().getAttackerClan(activeChar.getClan());
 					else if (fort != null && fort.getSiege().getIsInProgress())
 						siegeClan = fort.getSiege().getAttackerClan(activeChar.getClan());
-					
+					else if (hall != null && hall.isInSiege())
+						siegeClan = hall.getSiege().getAttackerClan(activeChar.getClan());
 					if ((siegeClan == null || siegeClan.getFlag().isEmpty()) && flag == null)
 					{
 						_log.warning("Player ["+activeChar.getName()+"] called RestartPointPacket - To Siege HQ and he doesn't have Siege HQ!");

+ 16 - 3
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestSiegeAttackerList.java

@@ -15,8 +15,10 @@
 
 package com.l2jserver.gameserver.network.clientpackets;
 
+import com.l2jserver.gameserver.instancemanager.CHSiegeManager;
 import com.l2jserver.gameserver.instancemanager.CastleManager;
 import com.l2jserver.gameserver.model.entity.Castle;
+import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
 import com.l2jserver.gameserver.network.serverpackets.SiegeAttackerList;
 
 /**
@@ -42,9 +44,20 @@ public final class RequestSiegeAttackerList extends L2GameClientPacket
 	protected void runImpl()
 	{
 		Castle castle = CastleManager.getInstance().getCastleById(_castleId);
-		if (castle == null) return;
-		SiegeAttackerList sal = new SiegeAttackerList(castle);
-		sendPacket(sal);
+		if (castle != null)
+		{
+			SiegeAttackerList sal = new SiegeAttackerList(castle);
+			sendPacket(sal);
+		}
+		else
+		{
+			SiegableHall hall = CHSiegeManager.getInstance().getSiegableHall(_castleId);
+			if(hall != null)
+			{
+				SiegeAttackerList sal = new SiegeAttackerList(hall);
+				sendPacket(sal);
+			}
+		}
 	}
 	
 	@Override

+ 3 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/AgitDecoInfo.java

@@ -16,6 +16,7 @@ package com.l2jserver.gameserver.network.serverpackets;
 
 import com.l2jserver.gameserver.model.entity.ClanHall;
 import com.l2jserver.gameserver.model.entity.ClanHall.ClanHallFunction;
+import com.l2jserver.gameserver.model.entity.clanhall.AuctionableHall;
 /**
  *
  * @author  Steuf
@@ -23,9 +24,9 @@ import com.l2jserver.gameserver.model.entity.ClanHall.ClanHallFunction;
 public class AgitDecoInfo extends L2GameServerPacket
 {
 	private static final String _S__F7_AGITDECOINFO = "[S] fd AgitDecoInfo";
-	private ClanHall _clanHall;
+	private AuctionableHall _clanHall;
 	private ClanHallFunction _function;
-	public AgitDecoInfo(ClanHall ClanHall){
+	public AgitDecoInfo(AuctionableHall ClanHall){
 		_clanHall = ClanHall;
 	}
 	/*

+ 5 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/Die.java

@@ -15,6 +15,7 @@
 package com.l2jserver.gameserver.network.serverpackets;
 
 import com.l2jserver.gameserver.datatables.AccessLevels;
+import com.l2jserver.gameserver.instancemanager.CHSiegeManager;
 import com.l2jserver.gameserver.instancemanager.CastleManager;
 import com.l2jserver.gameserver.instancemanager.FortManager;
 import com.l2jserver.gameserver.instancemanager.TerritoryWarManager;
@@ -28,6 +29,7 @@ import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.entity.Castle;
 import com.l2jserver.gameserver.model.entity.Fort;
 import com.l2jserver.gameserver.model.entity.TvTEvent;
+import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
 import com.l2jserver.gameserver.model.zone.type.L2RespawnZone;
 
 /**
@@ -94,6 +96,7 @@ public class Die extends L2GameServerPacket
 			L2SiegeClan siegeClan = null;
 			Castle castle = CastleManager.getInstance().getCastle(_activeChar);
 			Fort fort = FortManager.getInstance().getFort(_activeChar);
+			SiegableHall hall = CHSiegeManager.getInstance().getNearbyClanHall(_activeChar);
 			if (castle != null && castle.getSiege().getIsInProgress())
 			{
 				//siege in progress
@@ -116,7 +119,8 @@ public class Die extends L2GameServerPacket
 					isInCastleDefense? 0x01 : 0x00);             		// 6d 02 00 00 00 - to castle
 			writeD((TerritoryWarManager.getInstance().getFlagForClan(_clan) != null)
 					|| (siegeClan != null && !isInCastleDefense && !isInFortDefense
-							&& !siegeClan.getFlag().isEmpty()) ? 0x01 : 0x00);       // 6d 03 00 00 00 - to siege HQ
+						&& !siegeClan.getFlag().isEmpty())
+						|| (hall != null && hall.getSiege().checkIsAttacker(_clan))? 0x01 : 0x00);       // 6d 03 00 00 00 - to siege HQ
 			writeD(_sweepable ? 0x01 : 0x00);                               // sweepable  (blue glow)
 			writeD(_access.allowFixedRes() ? 0x01: 0x00);                  // 6d 04 00 00 00 - to FIXED
 			writeD(_clan.getHasFort() > 0  || isInFortDefense? 0x01 : 0x00);    // 6d 05 00 00 00 - to fortress

+ 3 - 3
L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/ExShowAgitInfo.java

@@ -18,7 +18,7 @@ import java.util.Map;
 
 import com.l2jserver.gameserver.datatables.ClanTable;
 import com.l2jserver.gameserver.instancemanager.ClanHallManager;
-import com.l2jserver.gameserver.model.entity.ClanHall;
+import com.l2jserver.gameserver.model.entity.clanhall.AuctionableHall;
 
 
 /**
@@ -45,9 +45,9 @@ public class ExShowAgitInfo extends L2GameServerPacket
 	{
 		writeC(0xfe);
 		writeH(0x16);
-		Map<Integer, ClanHall> clannhalls = ClanHallManager.getInstance().getAllClanHalls();
+		Map<Integer, AuctionableHall> clannhalls = ClanHallManager.getInstance().getAllAuctionableClanHalls();
 		writeD(clannhalls.size());
-		for (ClanHall ch : clannhalls.values())
+		for (AuctionableHall ch : clannhalls.values())
 		{
 			writeD(ch.getId());
 			writeS(ch.getOwnerId() <= 0 ? "" : ClanTable.getInstance().getClan(ch.getOwnerId()).getName()); // owner clan name

+ 73 - 25
L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/SiegeAttackerList.java

@@ -17,10 +17,14 @@ package com.l2jserver.gameserver.network.serverpackets;
 //import java.util.Calendar; //signed time related
 //import java.util.logging.Logger;
 
+import java.util.Collection;
+
 import com.l2jserver.gameserver.datatables.ClanTable;
+import com.l2jserver.gameserver.instancemanager.CHSiegeManager;
 import com.l2jserver.gameserver.model.L2Clan;
 import com.l2jserver.gameserver.model.L2SiegeClan;
 import com.l2jserver.gameserver.model.entity.Castle;
+import com.l2jserver.gameserver.model.entity.ClanHall;
 /**
  * Populates the Siege Attacker List in the SiegeInfo Window<BR>
  * <BR>
@@ -52,47 +56,91 @@ public final class SiegeAttackerList extends L2GameServerPacket
 	private static final String _S__CA_SiegeAttackerList = "[S] ca SiegeAttackerList";
 	//private static Logger _log = Logger.getLogger(SiegeAttackerList.class.getName());
 	private Castle _castle;
+	private ClanHall _hall;
 	
 	public SiegeAttackerList(Castle castle)
 	{
 		_castle = castle;
 	}
 	
+	public SiegeAttackerList(ClanHall hall)
+	{
+		_hall = hall;
+	}
+	
 	@Override
 	protected final void writeImpl()
 	{
 		writeC(0xca);
-		writeD(_castle.getCastleId());
-		writeD(0x00); //0
-		writeD(0x01); //1
-		writeD(0x00); //0
-		int size = _castle.getSiege().getAttackerClans().size();
-		if (size > 0)
+		
+		if(_castle != null)
 		{
-			L2Clan clan;
-			
-			writeD(size);
-			writeD(size);
-			for(L2SiegeClan siegeclan : _castle.getSiege().getAttackerClans())
+			writeD(_castle.getCastleId());
+			writeD(0x00); //0
+			writeD(0x01); //1
+			writeD(0x00); //0
+			int size = _castle.getSiege().getAttackerClans().size();
+			if (size > 0)
 			{
-				clan = ClanTable.getInstance().getClan(siegeclan.getClanId());
-				if (clan == null) continue;
+				L2Clan clan;
+			
+				writeD(size);
+				writeD(size);
+				for(L2SiegeClan siegeclan : _castle.getSiege().getAttackerClans())
+				{
+					clan = ClanTable.getInstance().getClan(siegeclan.getClanId());
+					if (clan == null) continue;
 				
-				writeD(clan.getClanId());
-				writeS(clan.getName());
-				writeS(clan.getLeaderName());
-				writeD(clan.getCrestId());
-				writeD(0x00); //signed time (seconds) (not storated by L2J)
-				writeD(clan.getAllyId());
-				writeS(clan.getAllyName());
-				writeS(""); //AllyLeaderName
-				writeD(clan.getAllyCrestId());
+					writeD(clan.getClanId());
+					writeS(clan.getName());
+					writeS(clan.getLeaderName());
+					writeD(clan.getCrestId());
+					writeD(0x00); //signed time (seconds) (not storated by L2J)
+					writeD(clan.getAllyId());
+					writeS(clan.getAllyName());
+					writeS(""); //AllyLeaderName
+					writeD(clan.getAllyCrestId());
+				}
+			}
+			else
+			{
+				writeD(0x00);
+				writeD(0x00);
 			}
 		}
-		else
+		else 
 		{
-			writeD(0x00);
-			writeD(0x00);
+			writeD(_hall.getId());
+			writeD(0x00); //0
+			writeD(0x01); //1
+			writeD(0x00); //0
+			final Collection<L2SiegeClan> attackers = CHSiegeManager.getInstance().getSiegableHall(_hall.getId()).getAttackers();
+			final int size = attackers.size();
+			if (size > 0)
+			{
+				writeD(size);
+				writeD(size);
+				for(L2SiegeClan sClan : attackers)
+				{
+					final L2Clan clan = ClanTable.getInstance().getClan(sClan.getClanId());
+					if (clan == null) continue;
+				
+					writeD(clan.getClanId());
+					writeS(clan.getName());
+					writeS(clan.getLeaderName());
+					writeD(clan.getCrestId());
+					writeD(0x00); //signed time (seconds) (not storated by L2J)
+					writeD(clan.getAllyId());
+					writeS(clan.getAllyName());
+					writeS(""); //AllyLeaderName
+					writeD(clan.getAllyCrestId());
+				}
+			}
+			else
+			{
+				writeD(0x00);
+				writeD(0x00);
+			}
 		}
 	}
 	

+ 66 - 19
L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/SiegeInfo.java

@@ -18,9 +18,11 @@ import java.util.Calendar;
 import java.util.logging.Logger;
 
 import com.l2jserver.gameserver.datatables.ClanTable;
+import com.l2jserver.gameserver.instancemanager.CHSiegeManager;
 import com.l2jserver.gameserver.model.L2Clan;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.entity.Castle;
+import com.l2jserver.gameserver.model.entity.ClanHall;
 
 
 /**
@@ -48,12 +50,18 @@ public class SiegeInfo extends L2GameServerPacket
 	private static final String _S__C9_SIEGEINFO = "[S] c9 SiegeInfo";
 	private static Logger _log = Logger.getLogger(SiegeInfo.class.getName());
 	private Castle _castle;
+	private ClanHall _hall;
 	
 	public SiegeInfo(Castle castle)
 	{
 		_castle = castle;
 	}
 	
+	public SiegeInfo(ClanHall hall)
+	{
+		_hall = hall;
+	}
+	
 	@Override
 	protected final void writeImpl()
 	{
@@ -61,33 +69,72 @@ public class SiegeInfo extends L2GameServerPacket
 		if (activeChar == null) return;
 		
 		writeC(0xc9);
-		writeD(_castle.getCastleId());
-		writeD(((_castle.getOwnerId() == activeChar.getClanId()) && (activeChar.isClanLeader())) ? 0x01 : 0x00);
-		writeD(_castle.getOwnerId());
-		if (_castle.getOwnerId() > 0)
+		if(_castle != null)
 		{
-			L2Clan owner = ClanTable.getInstance().getClan(_castle.getOwnerId());
-			if (owner != null)
+			writeD(_castle.getCastleId());
+			
+			final int ownerId = _castle.getOwnerId();
+			
+			writeD(((ownerId == activeChar.getClanId()) && (activeChar.isClanLeader())) ? 0x01 : 0x00);
+			writeD(ownerId);
+			if (ownerId > 0)
 			{
-				writeS(owner.getName());        // Clan Name
-				writeS(owner.getLeaderName());  // Clan Leader Name
-				writeD(owner.getAllyId());      // Ally ID
-				writeS(owner.getAllyName());    // Ally Name
+				L2Clan owner = ClanTable.getInstance().getClan(ownerId);
+				if (owner != null)
+				{
+					writeS(owner.getName());        // Clan Name
+					writeS(owner.getLeaderName());  // Clan Leader Name
+					writeD(owner.getAllyId());      // Ally ID
+					writeS(owner.getAllyName());    // Ally Name
+				}
+				else
+					_log.warning("Null owner for castle: " + _castle.getName());
 			}
 			else
-				_log.warning("Null owner for castle: " + _castle.getName());
+			{
+				writeS("");  // Clan Name
+				writeS("");     // Clan Leader Name
+				writeD(0);      // Ally ID
+				writeS("");     // Ally Name
+			}
+		
+			writeD((int) (Calendar.getInstance().getTimeInMillis()/1000));
+			writeD((int) (_castle.getSiege().getSiegeDate().getTimeInMillis()/1000));
+			writeD(0x00); //number of choices?
 		}
 		else
 		{
-			writeS("");  // Clan Name
-			writeS("");     // Clan Leader Name
-			writeD(0);      // Ally ID
-			writeS("");     // Ally Name
-		}
+			writeD(_hall.getId());
+			
+			final int ownerId = _hall.getOwnerId();
+			
+			writeD(((ownerId == activeChar.getClanId()) && (activeChar.isClanLeader())) ? 0x01 : 0x00);
+			writeD(ownerId);
+			if (ownerId > 0)
+			{
+				L2Clan owner = ClanTable.getInstance().getClan(ownerId);
+				if (owner != null)
+				{
+					writeS(owner.getName());        // Clan Name
+					writeS(owner.getLeaderName());  // Clan Leader Name
+					writeD(owner.getAllyId());      // Ally ID
+					writeS(owner.getAllyName());    // Ally Name
+				}
+				else
+					_log.warning("Null owner for siegable hall: " + _hall.getName());
+			}
+			else
+			{
+				writeS("");  // Clan Name
+				writeS("");     // Clan Leader Name
+				writeD(0);      // Ally ID
+				writeS("");     // Ally Name
+			}
 		
-		writeD((int) (Calendar.getInstance().getTimeInMillis()/1000));
-		writeD((int) (_castle.getSiege().getSiegeDate().getTimeInMillis()/1000));
-		writeD(0x00); //number of choices?
+			writeD((int) (Calendar.getInstance().getTimeInMillis()/1000));
+			writeD((int) ((CHSiegeManager.getInstance().getSiegableHall(_hall.getId()).getNextSiegeTime())/1000));
+			writeD(0x00); //number of choices?
+		}
 	}
 	
 	/* (non-Javadoc)

+ 41 - 3
L2J_Server_BETA/java/com/l2jserver/gameserver/skills/l2skills/L2SkillSiegeFlag.java

@@ -16,8 +16,10 @@ package com.l2jserver.gameserver.skills.l2skills;
 
 import java.util.logging.Level;
 
+import com.l2jserver.Config;
 import com.l2jserver.gameserver.datatables.NpcTable;
 import com.l2jserver.gameserver.idfactory.IdFactory;
+import com.l2jserver.gameserver.instancemanager.CHSiegeManager;
 import com.l2jserver.gameserver.instancemanager.CastleManager;
 import com.l2jserver.gameserver.instancemanager.FortManager;
 import com.l2jserver.gameserver.instancemanager.FortSiegeManager;
@@ -30,6 +32,7 @@ import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2SiegeFlagInstance;
 import com.l2jserver.gameserver.model.entity.Castle;
 import com.l2jserver.gameserver.model.entity.Fort;
+import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
 import com.l2jserver.gameserver.templates.StatsSet;
 
 public class L2SkillSiegeFlag extends L2Skill
@@ -95,10 +98,13 @@ public class L2SkillSiegeFlag extends L2Skill
 			flag.spawnMe(player.getX(), player.getY(), player.getZ() + 50);
 			Castle castle = CastleManager.getInstance().getCastle(activeChar);
 			Fort fort = FortManager.getInstance().getFort(activeChar);
+			SiegableHall hall = CHSiegeManager.getInstance().getNearbyClanHall(activeChar);
 			if (castle != null)
 				castle.getSiege().getFlag(player.getClan()).add(flag);
-			else
+			else if(fort != null)
 				fort.getSiege().getFlag(player.getClan()).add(flag);
+			else 
+				hall.getSiege().getFlag(player.getClan()).add(flag);
 			
 		}
 		catch (Exception e)
@@ -123,12 +129,15 @@ public class L2SkillSiegeFlag extends L2Skill
 			return false;
 		Castle castle = CastleManager.getInstance().getCastle(activeChar);
 		Fort fort = FortManager.getInstance().getFort(activeChar);
+		SiegableHall hall = CHSiegeManager.getInstance().getNearbyClanHall(activeChar);
 		
-		if ((castle == null) && (fort == null))
+		if ((castle == null) && (fort == null) && (hall == null))
 			return false;
 		if (castle != null)
 			return checkIfOkToPlaceFlag(activeChar, castle, isCheckOnly);
-		return checkIfOkToPlaceFlag(activeChar, fort, isCheckOnly);
+		else if(fort != null)
+			return checkIfOkToPlaceFlag(activeChar, fort, isCheckOnly);
+		return checkIfOkToPlaceFlag(activeChar, hall, isCheckOnly);
 	}
 	
 	/**
@@ -201,6 +210,35 @@ public class L2SkillSiegeFlag extends L2Skill
 		return false;
 	}
 	
+	public static boolean checkIfOkToPlaceFlag(L2Character activeChar, SiegableHall hall, boolean isCheckOnly)
+	{
+		if (!(activeChar instanceof L2PcInstance))
+			return false;
+		
+		String text = "";
+		L2PcInstance player = (L2PcInstance) activeChar;
+		final int hallId = hall.getId();
+		
+		if (hallId <= 0)
+			text = "You must be on Siegable clan hall ground to place a flag.";
+		else if (!hall.isInSiege())
+			text = "You can only place a flag during a siege.";
+		else if (player.getClan() == null || !player.isClanLeader())
+			text = "You must be a clan leader to place a flag.";
+		else if (!hall.isRegistered(player.getClan()))
+			text = "You must be an attacker to place a flag.";
+		else if (hall.getSiege().getAttackerClan(player.getClan()).getNumFlags() > Config.CHS_MAX_FLAGS_PER_CLAN)
+			text = "You have already placed the maximum number of flags possible.";
+		else if (player.isInsideZone(L2Character.ZONE_NOHQ))
+			text = "You cannot place flag here.";
+		else
+			return true;
+		
+		if (!isCheckOnly)
+			player.sendMessage(text);
+		return false;
+	}
+	
 	/**
 	 * Return true if character clan place a flag<BR><BR>
 	 *

+ 13 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/templates/item/L2Item.java

@@ -28,6 +28,7 @@ import com.l2jserver.gameserver.model.L2ItemInstance;
 import com.l2jserver.gameserver.model.L2Object;
 import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.actor.L2Summon;
+import com.l2jserver.gameserver.model.quest.Quest;
 import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
 import com.l2jserver.gameserver.skills.Env;
@@ -192,6 +193,8 @@ public abstract class L2Item
 	protected static final Func[] _emptyFunctionSet = new Func[0];
 	protected static final L2Effect[] _emptyEffectSet = new L2Effect[0];
 	
+	private List<Quest> _questEvents = new FastList<Quest>();
+	
 	protected static final Logger _log = Logger.getLogger(L2Item.class.getName());
 	
 	/**
@@ -940,4 +943,14 @@ public abstract class L2Item
 	{
 		return _icon;
 	}
+	
+	public void addQuestEvent(Quest q)
+	{
+		_questEvents.add(q);
+	}
+	
+	public List<Quest> getQuestEvents()
+	{
+		return _questEvents;
+	}
 }