U3Games

Games | Desarrollo & Soporte => L2 | Sección de Servidores => Lineage => L2 | Implementaciones => Mensaje iniciado por: Neron en Sep 04, 2025, 08:08 PM

Título: L2MultiFunctionZone / Para Zona pvp
Publicado por: Neron en Sep 04, 2025, 08:08 PM
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>