Noticias:

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

Menú Principal

L2MultiFunctionZone / Para Zona pvp

Iniciado por Neron, Sep 04, 2025, 08:08 PM

Tema anterior - Siguiente tema

Neron

Características principales:

- PvP configurable: Activación automática al entrar a la zona.

- Resurrección automática: Respawn en puntos fijos o aleatorios, con curación y noblesse opcional.

- Restricciones de jugadores: Bloqueo de logout, restart, tiendas y crafting según configuración.

- Gestión de items y equipamiento: Items, grades o encantamientos prohibidos se desactivan o desequipan automáticamente.

- Clases restringidas: Algunas clases pueden ser bloqueadas para entrar a la zona.

- Recompensas automáticas: Otorga items o premios configurables por matar dentro de la zona.

- Integración completa: Funciona con teletransportes, "To Village", y lógica de muerte y resurrección del servidor.

- Flexible y configurable: Todos los parámetros se manejan desde archivos .properties o .xml sin modificar el código

### Eclipse Workspace Patch 1.0
#P OrionRev28
diff --git files/game/config/FlagZone.properties files/game/config/FlagZone.properties
new file mode 100644
index 0000000..c214ec8
--- /dev/null
+++ files/game/config/FlagZone.properties
@@ -0,0 +1,60 @@
+ # ---------------------------------------------------------------------------
+ # MultiFunctionZone - custom addon for your server
+ # ---------------------------------------------------------------------------
+ # This option will turn on PvP flag to all people when entering to the zone
+ EnablePvP = True
+ 
+ # If set to false, zone will be no-restart zone
+ NoRestartZone = False
+ 
+ # If set to false, zone will be no-logout zone
+ NoLogoutZone = True
+ 
+ # If set to false, zone will be no-store zone
+ NoStoreZone = False
+ 
+ # Give noblesse after revive?
+ ReviveNoblesse = True
+ 
+ # Heal after revive?
+ ReviveHeal = False
+ 
+ # Delay, in seconds, to wait before revive
+ # 0 to disable --- ( Revivir Fixed )
+ ReviveDelay = 0
+ 
+ # Set the spawn points where players will be teleported on revive, if enabled
+ # example:150111,144740,-12248;143665,144418,-12022;144443,147685,-12139
+ SpawnLoc = 11489,-24578,-3644;11187,-22722,-3600;9986,-22541,-3695;9685,-23650,-3696;8202,-22880,-3723;6968,-22259,-3366;5654,-23824,-3728
+ 
+ # Random respawn radius
+ RespawnRadius = 10
+ 
+ # If set to true, players will take noblesse blessing when entering
+ GiveNoblesse = True
+ 
+ # Remove buffs when entering to the zone
+ RemoveBuffs = False
+ 
+ # Remove pets when entering to the zone
+ RemovePets = False
+ 
+ # Special rewards when hunting inside this zone
+ # example: 57,100000;14720,1
+ Rewards = 57,100000
+ 
+ # List of Items(id's) that won't be usable inside this area and also will be unequiped when entering
+ # (armor, weapons, scrolls, potions, etc), example: 728,7575, 6383, 1538
+ Items = 
+ 
+ # List of Grades that won't be usable inside this area and also will be unequiped when entering
+ # example: D,C,B,A,S,S80,S84
+ Grades = 
+ 
+ # Items with this enchant or more won't be usable inside this area and also will be unequiped when entering
+ # 0 to disable
+ Enchant = 0
+ 
+ # Players with one of that classes won't be able to enter to the zone
+ # example: 93,85,12
+ Classes = 16,97

\ No newline at end of file
diff --git src/l2jorion/game/model/actor/instance/L2PcInstance.java src/l2jorion/game/model/actor/instance/L2PcInstance.java
index d257582..4fdf225 100644
--- src/l2jorion/game/model/actor/instance/L2PcInstance.java
+++ src/l2jorion/game/model/actor/instance/L2PcInstance.java
@@ -145,6 +145,7 @@
 import l2jorion.game.model.quest.Quest;
 import l2jorion.game.model.quest.QuestState;
 import l2jorion.game.model.zone.ZoneId;
+import l2jorion.game.model.zone.type.L2MultiFunctionZone;
 import l2jorion.game.model.zone.type.L2TownZone;
 import l2jorion.game.network.L2GameClient;
 import l2jorion.game.network.PacketServer;
@@ -7529,6 +7530,7 @@
 	{
 		// Add karma to attacker and increase its PK counter
 		setPvpKills(getPvpKills() + 1);
+		L2MultiFunctionZone.givereward(this);
 		setWeeklyBoardPvpKills(getWeeklyBoardPvpKills() + 1);
 		getAchievement().increase(AchType.PVP);
 		// Daily
diff --git src/l2jorion/game/model/zone/ZoneId.java src/l2jorion/game/model/zone/ZoneId.java
index 334ed06..615d256 100644
--- src/l2jorion/game/model/zone/ZoneId.java
+++ src/l2jorion/game/model/zone/ZoneId.java
@@ -42,6 +42,7 @@
 	ZONE_CASTLE,
 	ZONE_PARTY,
 	ZONE_FLAG,
+	ZONE_MULTIFUNCTION,
 	ZONE_RAID_LIMIT;
 	
 	public static int getZoneCount()
diff --git src/l2jorion/game/model/zone/type/L2MultiFunctionZone.java src/l2jorion/game/model/zone/type/L2MultiFunctionZone.java
new file mode 100644
index 0000000..4fae2d1
--- /dev/null
+++ src/l2jorion/game/model/zone/type/L2MultiFunctionZone.java
@@ -0,0 +1,404 @@
+package l2jorion.game.model.zone.type;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import javolution.util.FastList;
+import l2jorion.game.datatables.SkillTable;
+import l2jorion.game.model.L2Character;
+import l2jorion.game.model.L2Skill;
+import l2jorion.game.model.L2Summon;
+import l2jorion.game.model.PcInventory;
+import l2jorion.game.model.actor.instance.L2ItemInstance;
+import l2jorion.game.model.actor.instance.L2PcInstance;
+import l2jorion.game.model.zone.L2ZoneType;
+import l2jorion.game.model.zone.ZoneId;
+import l2jorion.game.thread.ThreadPoolManager;
+import l2jorion.util.random.Rnd;
+
+/**
+ * @author Wyatt
+ * @version 1.3
+ */
+
+public class L2MultiFunctionZone extends L2ZoneType
+{
+	
+	public L2MultiFunctionZone(int id)
+	{
+		super(id);
+		loadConfigs();
+	}
+	
+	public static boolean pvp_enabled, restart_zone, store_zone, logout_zone, revive_noblesse, revive_heal, revive, remove_buffs, remove_pets, give_noblesse, Hero_Aura, Heal_OnEnter_Enable, SET_TEAM_ENABLE;
+	static int radius, enchant, revive_delay;
+	static String RewardName = ("");
+	static int[][] spawn_loc;
+	static int amount = 1;
+	
+	public static int RepCount;
+	L2Skill noblesse = SkillTable.getInstance().getInfo(1323, 1);
+	private static List<String> items = new FastList<>();
+	private static List<String> grades = new FastList<>(), classes = new FastList<>();
+	public static List<int[]> rewards;
+	static String[] gradeNames =
+	{
+		"",
+		"D",
+		"C",
+		"B",
+		"A",
+		"S",
+		"S80",
+		"S84"
+	};
+	
+	@Override
+	protected void onEnter(L2Character character)
+	{
+		character.setInsideZone(ZoneId.ZONE_NOSUMMONFRIEND, true);
+		character.setInsideZone(ZoneId.ZONE_MULTIFUNCTION, true);
+		
+		if (character instanceof L2PcInstance)
+		{
+			L2PcInstance activeChar = ((L2PcInstance) character);
+			if (classes != null && classes.contains("" + activeChar.getClassId().getId()))
+			{
+				activeChar.teleToLocation(83597, 147888, -3405);
+				activeChar.sendMessage("Your class is not allowed in the MultiFunction zone.");
+				return;
+			}
+			
+			for (L2ItemInstance o : activeChar.getInventory()._items)
+			{
+				if (o.isEquipable() && o.isEquipped() && !checkItem(o))
+				{
+					int slot = activeChar.getInventory().getSlotFromItem(o);
+					activeChar.getInventory().unEquipItemInBodySlotAndRecord(slot);
+					activeChar.sendMessage(o.getItemName() + " unequiped because is not allowed inside this zone.");
+				}
+			}
+			
+			// activeChar.sendPacket(new ExShowScreenMessage("Has entrado a la PvP Zone.", 2000, SMPOS.TOP_CENTER, true));
+			clear(activeChar);
+			
+			if (Heal_OnEnter_Enable)
+			{
+				heal(activeChar);
+			}
+			
+			if (Hero_Aura)
+			{
+				activeChar.setHeroAura(true);
+			}
+			
+			if (give_noblesse)
+			{
+				noblesse.getEffects(activeChar, activeChar);
+			}
+			if (pvp_enabled)
+			{
+				activeChar.stopPvPFlag();
+				activeChar.updatePvPFlag(1);
+			}
+			
+		}
+	}
+	
+	@Override
+	protected void onExit(L2Character character)
+	{
+		character.setInsideZone(ZoneId.ZONE_NOSUMMONFRIEND, false);
+		character.setInsideZone(ZoneId.ZONE_MULTIFUNCTION, false);
+		
+		if (character instanceof L2PcInstance)
+		{
+			L2PcInstance activeChar = ((L2PcInstance) character);
+			// activeChar.sendPacket(new ExShowScreenMessage("Has salido de la PvP Zone.", 2000, SMPOS.TOP_CENTER, true));
+			
+			if (Hero_Aura)
+			{
+				activeChar.setHeroAura(false);
+			}
+			if (pvp_enabled)
+			{
+				activeChar.stopPvPFlag();
+				activeChar.updatePvPStatus();
+			}
+		}
+	}
+	
+	@Override
+	public void onDieInside(final L2Character character)
+	{
+		if (character instanceof L2PcInstance)
+		{
+			final L2PcInstance activeChar = ((L2PcInstance) character);
+			if (revive)
+			{
+				ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
+				{
+					@Override
+					public void run()
+					{
+						activeChar.doRevive();
+						heal(activeChar);
+						int[] loc = spawn_loc[Rnd.get(spawn_loc.length)];
+						activeChar.teleToLocation(loc[0] + Rnd.get(-radius, radius), loc[1] + Rnd.get(-radius, radius), loc[2]);
+					}
+				}, revive_delay * 1000);
+			}
+		}
+	}
+	
+	@Override
+	public void onReviveInside(L2Character character)
+	{
+		if (character instanceof L2PcInstance)
+		{
+			L2PcInstance activeChar = ((L2PcInstance) character);
+			if (revive_noblesse)
+			{
+				noblesse.getEffects(activeChar, activeChar);
+			}
+			if (revive_heal)
+			{
+				heal(activeChar);
+			}
+		}
+	}
+	
+	static void heal(L2PcInstance activeChar)
+	{
+		activeChar.setCurrentHp(activeChar.getMaxHp());
+		activeChar.setCurrentCp(activeChar.getMaxCp());
+		activeChar.setCurrentMp(activeChar.getMaxMp());
+	}
+	
+	private void clear(L2PcInstance player)
+	{
+		if (remove_buffs)
+		{
+			player.stopAllEffects();
+			if (remove_pets)
+			{
+				L2Summon pet = player.getPet();
+				if (pet != null)
+				{
+					pet.stopAllEffects();
+					pet.unSummon(player);
+				}
+			}
+		}
+		else
+		{
+			if (remove_pets)
+			{
+				L2Summon pet = player.getPet();
+				if (pet != null)
+				{
+					pet.unSummon(player);
+				}
+			}
+		}
+	}
+	
+	public static void givereward(L2PcInstance player)
+	{
+		if (player.isInsideZone(ZoneId.ZONE_MULTIFUNCTION))
+		{
+			for (int[] reward : rewards)
+			{
+				PcInventory inv = player.getInventory();
+				inv.addItem("Rewards", reward[0], reward[1], player, player);
+				player.sendMessage("Has Recibido: " + amount + " Item de " + RewardName + ".");
+			}
+		}
+	}
+	
+	public static boolean checkItem(L2ItemInstance item)
+	{
+		int o = item.getItem().getCrystalType();
+		int e = item.getEnchantLevel();
+		
+		if (enchant != 0 && e >= enchant)
+		{
+			return false;
+		}
+		
+		if (grades.contains(gradeNames[o]))
+		{
+			return false;
+		}
+		
+		if (items != null && items.contains("" + item.getItemId()))
+		{
+			return false;
+		}
+		return true;
+	}
+	
+	private static void loadConfigs()
+	{
+		try
+		{
+			Properties prop = new Properties();
+			prop.load(new FileInputStream(new File("./config/FlagZone.properties")));
+			pvp_enabled = Boolean.parseBoolean(prop.getProperty("EnablePvP", "False"));
+			spawn_loc = parseItemsList(prop.getProperty("SpawnLoc", "150111,144740,-12248"));
+			revive_delay = Integer.parseInt(prop.getProperty("ReviveDelay", "10"));
+			if (revive_delay != 0)
+			{
+				revive = true;
+			}
+			give_noblesse = Boolean.parseBoolean(prop.getProperty("GiveNoblesse", "False"));
+			String[] propertySplit = prop.getProperty("Items", "").split(",");
+			if (propertySplit.length != 0)
+			{
+				for (String i : propertySplit)
+				{
+					items.add(i);
+				}
+			}
+			propertySplit = prop.getProperty("Grades", "").split(",");
+			if (propertySplit.length != 0)
+			{
+				for (String i : propertySplit)
+				{
+					if (i.equals("D") || i.equals("C") || i.equals("B") || i.equals("A") || i.equals("S") || i.equals("S80") || i.equals("S84"))
+					{
+						grades.add(i);
+					}
+				}
+			}
+			propertySplit = prop.getProperty("Classes", "").split(",");
+			if (propertySplit.length != 0)
+			{
+				for (String i : propertySplit)
+				{
+					classes.add(i);
+				}
+			}
+			radius = Integer.parseInt(prop.getProperty("RespawnRadius", "500"));
+			enchant = Integer.parseInt(prop.getProperty("Enchant", "0"));
+			RepCount = Integer.parseInt(prop.getProperty("RepCount", "10"));
+			RewardName = prop.getProperty("RewardName", "");
+			remove_buffs = Boolean.parseBoolean(prop.getProperty("RemoveBuffs", "False"));
+			remove_pets = Boolean.parseBoolean(prop.getProperty("RemovePets", "False"));
+			restart_zone = Boolean.parseBoolean(prop.getProperty("NoRestartZone", "False"));
+			store_zone = Boolean.parseBoolean(prop.getProperty("NoStoreZone", "False"));
+			logout_zone = Boolean.parseBoolean(prop.getProperty("NoLogoutZone", "False"));
+			revive_noblesse = Boolean.parseBoolean(prop.getProperty("ReviveNoblesse", "False"));
+			revive_heal = Boolean.parseBoolean(prop.getProperty("ReviveHeal", "False"));
+			Hero_Aura = Boolean.parseBoolean(prop.getProperty("HeroAura", "False"));
+			SET_TEAM_ENABLE = Boolean.parseBoolean(prop.getProperty("SetTeams", "False"));
+			Heal_OnEnter_Enable = Boolean.parseBoolean(prop.getProperty("HealOnEnterEnable", "False"));
+			rewards = new ArrayList<>();
+			propertySplit = prop.getProperty("Rewards", "57,100000").split(";");
+			for (String reward : propertySplit)
+			{
+				String[] rewardSplit = reward.split(",");
+				if (rewardSplit.length == 2)
+				{
+					try
+					{
+						rewards.add(new int[]
+						{
+							Integer.parseInt(rewardSplit[0]),
+							Integer.parseInt(rewardSplit[1])
+						});
+					}
+					catch (NumberFormatException nfe)
+					{
+					}
+				}
+			}
+		}
+		catch (Exception e)
+		{
+			e.printStackTrace();
+		}
+	}
+	
+	private static int[][] parseItemsList(String line)
+	{
+		final String[] propertySplit = line.split(";");
+		if (propertySplit.length == 0)
+		{
+			return null;
+		}
+		
+		int i = 0;
+		String[] valueSplit;
+		final int[][] result = new int[propertySplit.length][];
+		for (String value : propertySplit)
+		{
+			valueSplit = value.split(",");
+			if (valueSplit.length != 3)
+			{
+				return null;
+			}
+			
+			result[i] = new int[3];
+			try
+			{
+				result[i][0] = Integer.parseInt(valueSplit[0]);
+			}
+			catch (NumberFormatException e)
+			{
+				return null;
+			}
+			try
+			{
+				result[i][1] = Integer.parseInt(valueSplit[1]);
+			}
+			catch (NumberFormatException e)
+			{
+				return null;
+			}
+			try
+			{
+				result[i][2] = Integer.parseInt(valueSplit[2]);
+			}
+			catch (NumberFormatException e)
+			{
+				return null;
+			}
+			i++;
+		}
+		return result;
+	}
+	
+	public static int[][] getSpawnLoc()
+	{
+		return spawn_loc;
+	}
+	
+	public static int getRadius()
+	{
+		return radius;
+	}
+	
+}
+
\ No newline at end of file
diff --git src/l2jorion/game/network/clientpackets/Logout.java src/l2jorion/game/network/clientpackets/Logout.java
index fe190db..6b4d01b 100644
--- src/l2jorion/game/network/clientpackets/Logout.java
+++ src/l2jorion/game/network/clientpackets/Logout.java
@@ -21,6 +21,8 @@
 import l2jorion.game.model.actor.instance.L2PcInstance;
 import l2jorion.game.model.entity.sevensigns.SevenSignsFestival;
 import l2jorion.game.model.olympiad.OlympiadManager;
+import l2jorion.game.model.zone.ZoneId;
+import l2jorion.game.model.zone.type.L2MultiFunctionZone;
 import l2jorion.game.network.PacketClient;
 import l2jorion.game.network.SystemMessageId;
 import l2jorion.game.network.serverpackets.ActionFailed;
@@ -61,6 +63,13 @@
 			return;
 		}
 		
+		if (player.isInsideZone(ZoneId.ZONE_MULTIFUNCTION) && !L2MultiFunctionZone.logout_zone)
+		{
+			player.sendMessage("You cannot Logout while inside a Multifunction zone.");
+			player.sendPacket(ActionFailed.STATIC_PACKET);
+			return;
+		}
+		
 		player.getInventory().updateDatabase();
 		
 		if (AttackStanceTaskManager.getInstance().getAttackStanceTask(player) && !(player.isGM() && Config.GM_RESTART_FIGHTING))
diff --git src/l2jorion/game/network/clientpackets/RequestRecipeShopListSet.java src/l2jorion/game/network/clientpackets/RequestRecipeShopListSet.java
index 1a64efa..02d1e49 100644
--- src/l2jorion/game/network/clientpackets/RequestRecipeShopListSet.java
+++ src/l2jorion/game/network/clientpackets/RequestRecipeShopListSet.java
@@ -23,6 +23,7 @@
 import l2jorion.game.model.L2ManufactureList;
 import l2jorion.game.model.actor.instance.L2PcInstance;
 import l2jorion.game.model.zone.ZoneId;
+import l2jorion.game.model.zone.type.L2MultiFunctionZone;
 import l2jorion.game.network.PacketClient;
 import l2jorion.game.network.SystemMessageId;
 import l2jorion.game.network.serverpackets.ActionFailed;
@@ -78,6 +79,12 @@
 			return;
 		}
 		
+		if (player.isInsideZone(ZoneId.ZONE_MULTIFUNCTION) && !L2MultiFunctionZone.store_zone)
+		{
+			player.sendMessage("You cannot craft while inside Multifunction zone.");
+			return;
+		}
+		
 		if (player.isInsideZone(ZoneId.ZONE_NOSTORE))
 		{
 			player.sendPacket(SystemMessageId.NO_PRIVATE_STORE_HERE);
diff --git src/l2jorion/game/network/clientpackets/RequestRestart.java src/l2jorion/game/network/clientpackets/RequestRestart.java
index 631b707..ec8018f 100644
--- src/l2jorion/game/network/clientpackets/RequestRestart.java
+++ src/l2jorion/game/network/clientpackets/RequestRestart.java
@@ -26,9 +26,11 @@
 import l2jorion.game.model.actor.instance.L2PcInstance;
 import l2jorion.game.model.entity.sevensigns.SevenSignsFestival;
 import l2jorion.game.model.olympiad.OlympiadManager;
+import l2jorion.game.model.zone.ZoneId;
+import l2jorion.game.model.zone.type.L2MultiFunctionZone;
 import l2jorion.game.network.L2GameClient;
-import l2jorion.game.network.PacketClient;
 import l2jorion.game.network.L2GameClient.GameClientState;
+import l2jorion.game.network.PacketClient;
 import l2jorion.game.network.SystemMessageId;
 import l2jorion.game.network.serverpackets.ActionFailed;
 import l2jorion.game.network.serverpackets.CharSelectInfo;
@@ -65,6 +67,13 @@
 			return;
 		}
 		
+		if (player.isInsideZone(ZoneId.ZONE_MULTIFUNCTION) && !L2MultiFunctionZone.restart_zone)
+		{
+			player.sendMessage("You cannot restart while inside a Multifunction zone.");
+			sendPacket(RestartResponse.valueOf(false));
+			return;
+		}
+		
 		// Check if player are changing class
 		if (player.isLocked())
 		{
diff --git src/l2jorion/game/network/clientpackets/SetPrivateStoreListBuy.java src/l2jorion/game/network/clientpackets/SetPrivateStoreListBuy.java
index 7d402f1..30faed6 100644
--- src/l2jorion/game/network/clientpackets/SetPrivateStoreListBuy.java
+++ src/l2jorion/game/network/clientpackets/SetPrivateStoreListBuy.java
@@ -22,6 +22,7 @@
 import l2jorion.game.model.TradeList;
 import l2jorion.game.model.actor.instance.L2PcInstance;
 import l2jorion.game.model.zone.ZoneId;
+import l2jorion.game.model.zone.type.L2MultiFunctionZone;
 import l2jorion.game.network.PacketClient;
 import l2jorion.game.network.SystemMessageId;
 import l2jorion.game.network.serverpackets.ActionFailed;
@@ -94,6 +95,13 @@
 			return;
 		}
 		
+		if (player.isInsideZone(ZoneId.ZONE_MULTIFUNCTION) && !L2MultiFunctionZone.store_zone)
+		{
+			player.sendPacket(new PrivateStoreManageListBuy(player));
+			player.sendMessage("You cannot start store while inside Multifunction zone.");
+			return;
+		}
+		
 		if (Config.RON_CUSTOM && !player.isInsideZone(ZoneId.ZONE_PEACE))
 		{
 			player.sendPacket(new PrivateStoreManageListBuy(player));
diff --git src/l2jorion/game/network/clientpackets/SetPrivateStoreListSell.java src/l2jorion/game/network/clientpackets/SetPrivateStoreListSell.java
index b0a057a..7d9b1f7 100644
--- src/l2jorion/game/network/clientpackets/SetPrivateStoreListSell.java
+++ src/l2jorion/game/network/clientpackets/SetPrivateStoreListSell.java
@@ -22,6 +22,7 @@
 import l2jorion.game.model.TradeList;
 import l2jorion.game.model.actor.instance.L2PcInstance;
 import l2jorion.game.model.zone.ZoneId;
+import l2jorion.game.model.zone.type.L2MultiFunctionZone;
 import l2jorion.game.network.PacketClient;
 import l2jorion.game.network.SystemMessageId;
 import l2jorion.game.network.serverpackets.ActionFailed;
@@ -87,6 +88,13 @@
 			return;
 		}
 		
+		if (player.isInsideZone(ZoneId.ZONE_MULTIFUNCTION) && !L2MultiFunctionZone.store_zone)
+		{
+			player.sendPacket(new PrivateStoreManageListSell(player));
+			player.sendMessage("You cannot start store while inside Multifunction zone.");
+			return;
+		}
+		
 		if (player.isCastingNow() || player.isCastingPotionNow() || player.isMovementDisabled() || player.inObserverMode() || player.getActiveEnchantItem() != null)
 		{
 			player.sendMessage("You cannot start store now.");
diff --git src/l2jorion/game/network/clientpackets/UseItem.java src/l2jorion/game/network/clientpackets/UseItem.java
index 8ba07e5..acbaedb 100644
--- src/l2jorion/game/network/clientpackets/UseItem.java
+++ src/l2jorion/game/network/clientpackets/UseItem.java
@@ -36,6 +36,8 @@
 import l2jorion.game.model.L2Object;
 import l2jorion.game.model.actor.instance.L2ItemInstance;
 import l2jorion.game.model.actor.instance.L2PcInstance;
+import l2jorion.game.model.zone.ZoneId;
+import l2jorion.game.model.zone.type.L2MultiFunctionZone;
 import l2jorion.game.network.PacketClient;
 import l2jorion.game.network.SystemMessageId;
 import l2jorion.game.network.serverpackets.ActionFailed;
@@ -111,6 +113,12 @@
 			}
 		}
 		
+		if (getClient().getActiveChar().isInsideZone(ZoneId.ZONE_MULTIFUNCTION) && !L2MultiFunctionZone.checkItem(item))
+		{
+			getClient().getActiveChar().sendMessage("You cannot use " + item.getName() + " inside this zone.");
+			return;
+		}
+		
 		// Like L2OFF you can't use soulshots while sitting
 		final int[] shots_ids =
 		{
diff --git src/l2jorion/game/network/serverpackets/Die.java src/l2jorion/game/network/serverpackets/Die.java
index cb67140..6a52479 100644
--- src/l2jorion/game/network/serverpackets/Die.java
+++ src/l2jorion/game/network/serverpackets/Die.java
@@ -31,6 +31,7 @@
 import l2jorion.game.model.entity.siege.Castle;
 import l2jorion.game.model.entity.siege.Fort;
 import l2jorion.game.model.zone.ZoneId;
+import l2jorion.game.model.zone.type.L2MultiFunctionZone;
 import l2jorion.game.network.PacketServer;
 
 public class Die extends PacketServer
@@ -53,7 +54,8 @@
			L2PcInstance player = (L2PcInstance) cha;
			
			final Base.Autofarm.AutofarmPlayerRoutine bot = player.getBot();
-			_allowFixedRes = (player.getAccessLevel().allowFixedRes() || player.isInsideZone(ZoneId.ZONE_RANDOM) || player.isInsideZone(ZoneId.ZONE_ENCHANT) || Dungeon.isPlayerInside(player));
			_clan = player.getClan();
	
			final Base.Autofarm.AutofarmPlayerRoutine bot = player.getBot();
+			_allowFixedRes = (player.getAccessLevel().allowFixedRes() || player.isInsideZone(ZoneId.ZONE_RANDOM) || player.isInsideZone(ZoneId.ZONE_ENCHANT) || player.isInsideZone(ZoneId.ZONE_MULTIFUNCTION) || Dungeon.isPlayerInside(player));
			_clan = player.getClan();
-			_canTeleport = !((TvT.is_started() && player._inEventTvT) || (DM.is_started() && player._inEventDM) || (CTF.is_started() && player._inEventCTF) || player.isInFunEvent() || player.isInArenaEvent() || player.isPendingRevive());
+			_canTeleport = !((TvT.is_started() && player._inEventTvT) || (DM.is_started() && player._inEventDM) || (CTF.is_started() && player._inEventCTF) || player.isInFunEvent() || player.isInArenaEvent() || player.isPendingRevive()
+				|| (player.isInsideZone(ZoneId.ZONE_MULTIFUNCTION) && L2MultiFunctionZone.revive));
 		}
 		
 		_charObjId = cha.getObjectId();


diff --git src/l2jorion/game/network/clientpackets/Die.java src/l2jorion/game/network/clientpackets/RequestRestartPoint.java
index cb67140..6a52479 100644
--- src/l2jorion/game/network/clientpackets/RequestRestartPoint.java
+++ src/l2jorion/game/network/clientpackets/RequestRestartPoint.java

+ import l2jorion.game.model.zone.type.L2MultiFunctionZone;
+ import l2jorion.game.model.zone.ZoneId;


					case 4: // Fixed or Player is a festival participant
-						if (!activeChar.isGM() && !activeChar.isFestivalParticipant() && !activeChar.isInsideZone(ZoneId.ZONE_RANDOM) && !activeChar.isInsideZone(ZoneId.ZONE_ENCHANT) && !Dungeon.isPlayerInside(activeChar))
						{

					case 4: // Fixed or Player is a festival participant
+						if (!activeChar.isGM() && !activeChar.isFestivalParticipant() && !activeChar.isInsideZone(ZoneId.ZONE_RANDOM) && !activeChar.isInsideZone(ZoneId.ZONE_ENCHANT) && !activeChar.isInsideZone(ZoneId.ZONE_MULTIFUNCTION) && !Dungeon.isPlayerInside(activeChar))
						{
						
						if (activeChar.isInsideZone(ZoneId.ZONE_RANDOM))
						{
							loc = RandomZoneTaskManager.getInstance().getCurrentZone().getLoc();
							activeChar.setIsIn7sDungeon(false);
							activeChar.setIsPendingRevive(true);
							activeChar.teleToLocation(loc, 50, true);
							return;
						}
						if (!activeChar.isGM() && Dungeon.isPlayerInside(activeChar))
						{
							activeChar.setIsIn7sDungeon(false);
							activeChar.setIsPendingRevive(true);
							activeChar.teleToLocation(Dungeon.getRandomLoc(), 50);
							return;
						}
						
+						if (activeChar.isInsideZone(ZoneId.ZONE_MULTIFUNCTION))
+						{
+							// 🔹 Fixed respawn dentro de la zona
+							int[] coords = L2MultiFunctionZone.getSpawnLoc()[Rnd.get(L2MultiFunctionZone.getSpawnLoc().length)];
+							loc = new Location(coords[0] + Rnd.get(-L2MultiFunctionZone.getRadius(), L2MultiFunctionZone.getRadius()), coords[1] + Rnd.get(-L2MultiFunctionZone.getRadius(), L2MultiFunctionZone.getRadius()), coords[2]);
+							
+							activeChar.setIsIn7sDungeon(false);
+							activeChar.setIsPendingRevive(true);
+							activeChar.teleToLocation(loc, 50, false);
+							return;
+						}
						
						loc = new Location(activeChar.getX(), activeChar.getY(), activeChar.getZ());
						break;
					
					case 27: // to jail
						if (!activeChar.isInJail())
						{
							return;
						}
						loc = new Location(-114356, -249645, -2984);
						break;
					
+					default:
+						// 🔹 Si está en Multifunction y eligió "To Village", sacarlo al pueblo
+						if (activeChar.isInsideZone(ZoneId.ZONE_MULTIFUNCTION))
+						{
+							loc = new Location(83347, 148049, -3405); // <<--- Tus coords fijas
+							break;
						}
						
						if (activeChar.getKarma() > 0 && Config.ALT_KARMA_TELEPORT_TO_FLORAN)
						{
							loc = new Location(17836, 170178, -3507); // Floran Village
							break;
						}						
						
						
						
diff --git files\game\data\xml\zones\FlagZone.properties files\game\data\xml\zones\MultiFunctionZone.xml
new file mode 100644
index 0000000..c214ec8
--- /dev/null
+++ files\game\data\xml\zones\MultiFunctionZone.xml

+ <?xml version="1.0" encoding="UTF-8"?>
+ <list enabled="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/zones.xsd">
+ 	<zone name='PvPZone'  type="MultiFunctionZone" shape="NPoly" minZ='-4388' maxZ='-2388'>
+ 	<node X="10391" Y="-27101" />
+ 	<node X="6602" Y="-26227" />
+ 	<node X="2527" Y="-23524" />
+ 	<node X="751" Y="-20450" />
+ 	<node X="-189" Y="-15484" />
+ 	<node X="541" Y="-8282" />
+ 	<node X="2137" Y="-3154" />
+ 	<node X="5323" Y="-701" />
+ 	<node X="11860" Y="-416" />
+ 	<node X="17442" Y="-619" />
+ 	<node X="21748" Y="-356" />
+ 	<node X="31253" Y="-2665" />
+ 	<node X="32959" Y="-12882" />
+ 	<node X="31556" Y="-24127" />
+ 	<node X="27313" Y="-26228" />
+ 	<node X="19912" Y="-26890" />
+ 	<node X="12887" Y="-27269" />
+ 	<node X="11151" Y="-27385" />
+ 	</zone>
+ </list>