Jump to content

Recommended Posts

Posted

 

[Release] Solo PvP Zone System
🔹 Compatible with: aCis 401+

📜 Features:
✅ Automatic Exit on Restart: Players are removed from the zone if a restart occurs or logout.
✅ Custom Exit Command: Players can exit the Solo Zone with the voice command .exit.
✅ Teleport NPC Command: new bypass solopvp for gatekeeper.
✅ Random Name Generator: Generates random names.
✅ PvP Flag: The players are flagged within this zone.

 

xml preview & java code

backup code -> https://pastebin.com/974V2p2p

 

SoloZone.xml

<?xml version="1.0" encoding="UTF-8"?>
<list>
	<zone shape="NPoly" minZ="-5200" maxZ="-4680"><!-- Frintezza Solo Zone -->
	<stat name="name" val="Solo PvP Zone" />
	<stat name="locs" val="174244,-89089,-5112;174260,-86881,-5112;173184,-88090,-5112;175309,-88018,-5112;174231,-88019,-5112;175136,-88828,-5104;174962,-87025,-5104;173149,-87142,-5104;173470,-88908,-5112" />
	<stat name="restrictedClasses" val="15,16,97" />
		<node x="172031" y="-90127"/>
		<node x="176428" y="-90089"/>
		<node x="176428" y="-74051"/>
		<node x="172057" y="-74108"/>
	</zone>
</list>

SoloZone Code:

diff --git a/java/net/sf/l2j/gameserver/taskmanager/SoloZoneTaskManager.java b/java/net/sf/l2j/gameserver/taskmanager/SoloZoneTaskManager.java
new file mode 100644
index 0000000..6b7ef6f
--- /dev/null
+++ a/java/net/sf/l2j/gameserver/taskmanager/SoloZoneTaskManager.java
@@ -0,0 +1,98 @@
+package net.sf.l2j.gameserver.taskmanager;
+
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.logging.Logger;
+
+import net.sf.l2j.commons.random.Rnd;
+
+import net.sf.l2j.gameserver.data.manager.ZoneManager;
+import net.sf.l2j.gameserver.enums.ZoneId;
+import net.sf.l2j.gameserver.handler.voicecommandhandlers.VoiceExitSoloZone;
+import net.sf.l2j.gameserver.model.World;
+import net.sf.l2j.gameserver.model.actor.Player;
+import net.sf.l2j.gameserver.model.location.Location;
+import net.sf.l2j.gameserver.model.zone.type.SoloZone;
+
+
+/**
+ * @author MarGaZeaS
+ */
+public class SoloZoneTaskManager implements Runnable {
+
+    private static final Location EXIT_LOCATION = VoiceExitSoloZone.getExitLocation(); // Λαμβάνουμε την έξοδο από το VoiceExitSoloZone
+
+    @Override
+    public void run()
+    {
+        // Διασχίζουμε όλους τους παίκτες του κόσμου
+        for (Player player : World.getInstance().getPlayers())
+        {
+            // Ελέγχουμε αν ο παίκτης είναι στο SoloZone
+            if (player.isInsideZone(ZoneId.SOLO))
+            {
+                // Μεταφέρουμε τον παίκτη στην έξοδο
+                player.teleportTo(EXIT_LOCATION.getX(), EXIT_LOCATION.getY(), EXIT_LOCATION.getZ(), 0);
+                player.sendMessage("The server is restarting, you have been moved out of the Solo Zone.");
+            }
+        }
+    }
+    
+	private int _id;
+	
+    private static final Logger _log = Logger.getLogger(SoloZoneTaskManager.class.getName());
+    private static final ArrayList<String> _rndNames = new ArrayList<>();
+    private static final int RANDOM_NAMES = 500;
+    private static final String CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+    private int _playersInSoloZone = 0;
+
+    public int getPlayersInside() {
+        return _playersInSoloZone;
+    }
+
+    public void setPlayersInside(int val) {
+        _playersInSoloZone = val;
+    }
+
+    public SoloZoneTaskManager() {
+        _log.info("Solo Zone System: Loading...");
+        for (int i = 0; i < RANDOM_NAMES; i++) {
+            String name = generateName();
+            _rndNames.add(name);
+            _log.info("Generated name: " + name);
+        }
+        _log.info("Solo Zone System: Loaded " + _rndNames.size() + " names.");
+    }
+
+    public String getAName() {
+        if (_rndNames.isEmpty()) {
+            _log.warning("SoloZoneManager: No random names available.");
+            return "Unknown";
+        }
+        return _rndNames.get(Rnd.get(5, RANDOM_NAMES - 5));
+    }
+    
+    private static String generateName() {
+        SecureRandom rnd = new SecureRandom();
+        StringBuilder sb = new StringBuilder(15);
+        for (int i = 0; i < 15; i++) {
+            sb.append(CHARS.charAt(rnd.nextInt(CHARS.length())));
+        }
+        return sb.toString();
+    }
+    
+ 	public int getZoneId()
+ 	{
+ 		return _id;
+ 	}
+ 	
+ 	public final static SoloZone getCurrentZone() {
+ 	    return ZoneManager.getInstance().getAllZones(SoloZone.class)
+ 	        .stream()
+ 	        .findFirst() // Επιστρέφει την πρώτη SoloZone (αν υπάρχει μόνο μία)
+ 	        .orElse(null);
+ 	}
+	
+    public static SoloZoneTaskManager getInstance() {
+        return SingletonHolder._instance;
+    }
+
+    private static class SingletonHolder {
+        private static final SoloZoneTaskManager _instance = new SoloZoneTaskManager();
+    }
+}
diff --git a/aCis_gameserver/java/net/sf/l2j/gameserver/taskmanager/PvpFlagTaskManager.java b/aCis_gameserver/java/net/sf/l2j/gameserver/taskmanager/PvpFlagTaskManager.java
index a707ce5..d247e2e 100644
--- a/aCis_gameserver/java/net/sf/l2j/gameserver/taskmanager/PvpFlagTaskManager.java
			final Player player = entry.getKey();
			final long timeLeft = entry.getValue();
			
+			if(player.isInsideZone(ZoneId.SOLO))
+				continue;
			
			if(player.isInsideZone(ZoneId.BOSS))
				continue;
			
			// Time is running out, clear PvP flag and remove from list.
			if (currentTime > timeLeft)
diff --git a/aCis_gameserver/java/net/sf/l2j/gameserver/network/clientpackets/RequestCharacterCreate.java b/aCis_gameserver/java/net/sf/l2j/gameserver/network/clientpackets/RequestCharacterCreate.java
index a707ce5..d247e2e 100644
+++ b/aCis_gameserver/java/net/sf/l2j/gameserver/network/clientpackets/RequestCharacterCreate.java

		if (Config.ALLOW_FISH_CHAMPIONSHIP)
			FishingChampionshipManager.getInstance();

+		if (Config.ENABLE_STARTUP)
+		StartupManager.getInstance();			

diff --git a/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminMaintenance.java b/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminMaintenance.java
new file mode 100644
index 0000000..6b7ef6f
--- /dev/null
+++ a/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminMaintenance.java
		if (!st.hasMoreTokens())
		{
			sendHtmlForm(player);
			return;
		}
		
		try
		{
			switch (st.nextToken())
			{
				case "shutdown":
+	                SoloZoneTaskManager exitTask = new SoloZoneTaskManager();
+	                ThreadPool.schedule(exitTask, 0); 
					Shutdown.getInstance().startShutdown(player, null, Integer.parseInt(st.nextToken()), false);
					break;
				
				case "restart":
+	                exitTask = new SoloZoneTaskManager();
+	                ThreadPool.schedule(exitTask, 0); 
					Shutdown.getInstance().startShutdown(player, null, Integer.parseInt(st.nextToken()), true);
					break;
				
				case "abort":
					Shutdown.getInstance().abort(player);
					break;
diff --git a/java/net/sf/l2j/gameserver/handler/voicecommandhandlers/VoiceExitSoloZone.java b/java/net/sf/l2j/gameserver/handler/voicecommandhandlers/VoiceExitSoloZone.java
new file mode 100644
index 0000000..6b7ef6f
--- /dev/null
+++ a/java/net/sf/l2j/gameserver/handler/voicecommandhandlers/VoiceExitSoloZone.java
+package net.sf.l2j.gameserver.handler.voicecommandhandlers;
+
+import net.sf.l2j.commons.pool.ThreadPool;
+
+import net.sf.l2j.gameserver.enums.ZoneId;
+import net.sf.l2j.gameserver.handler.IVoiceCommandHandler;
+import net.sf.l2j.gameserver.model.actor.Player;
+import net.sf.l2j.gameserver.model.location.Location;
+import net.sf.l2j.gameserver.network.serverpackets.MagicSkillUse;
+
+/**
+ * Handles the voice command for exiting the Solo Zone with delay and effects.
+ * 
+ * @author MarGaZeaS
+ */
+public class VoiceExitSoloZone implements IVoiceCommandHandler
+{
+    private static final String[] VOICE_COMMANDS =
+    {
+        "exit"
+    };
+
+    // Default location to teleport players when exiting the Solo Zone
+    private static final Location EXIT_LOCATION = new Location(81318, 148064, -3464); // Replace with your desired coordinates
+
+    // Προσθήκη της μεθόδου για να πάρουμε την τοποθεσία εξόδου
+    public static Location getExitLocation() {
+        return EXIT_LOCATION;
+    }
+
+    @Override
+    public void useVoiceCommand(Player player, String command)
+    {
+        if (command.equalsIgnoreCase("exit"))
+        {
+            if (!player.isInsideZone(ZoneId.SOLO))
+            {
+                player.sendMessage("You are not inside the Solo Zone.");
+                return;
+            }
+
+            // Notify the player about the delay
+            player.sendMessage("You will be teleported out of the Solo Zone in 2 seconds.");
+            
+            // Cast skill effect (Skill ID: 2100, Level: 1)
+            player.broadcastPacket(new MagicSkillUse(player, player, 2100, 1, 2000, 0));
+            
+            // Schedule the teleportation after a 2-second delay
+            ThreadPool.schedule(() -> {
+                // Teleport the player to the designated exit location
+                player.teleportTo(EXIT_LOCATION.getX(), EXIT_LOCATION.getY(), EXIT_LOCATION.getZ(), 0);
+
+                // Inform the player
+                player.sendMessage("You have exited the Solo Zone.");
+            }, 2000); // Delay in milliseconds (2000ms = 2 seconds)
+        }
+    }
+
+    @Override
+    public String[] getVoiceCommandList()
+    {
+        return VOICE_COMMANDS;
+    }
+}
diff --git a/java/net/sf/l2j/gameserver/handler/VoiceCommandHandler.java b/java/net/sf/l2j/gameserver/handler/VoiceCommandHandler.java
new file mode 100644
index 0000000..6b7ef6f
--- /dev/null
+++ a/java/net/sf/l2j/gameserver/handler/VoiceCommandHandler.java
public class VoiceCommandHandler
{
	private final Map<String, IVoiceCommandHandler> _entries = new HashMap<>();
	
	protected VoiceCommandHandler()
	{
		............
		............
+		registerHandler(new VoiceExitSoloZone());
		
	}
	
	public void registerHandler(IVoiceCommandHandler handler)
	{
		for (String command : handler.getVoiceCommandList())
			_entries.put(command, handler);
	}
diff --git a/java/net/sf/l2j/gameserver/model/actor/Npc.java b/java/net/sf/l2j/gameserver/model/actor/Npc.java
new file mode 100644
index 0000000..6b7ef6f
--- /dev/null
+++ a/java/net/sf/l2j/gameserver/model/actor/Npc.java
		else if (command.startsWith("Chat"))
		{
			int val = 0;
			try
			{
				val = Integer.parseInt(command.substring(5));
			}
			catch (final IndexOutOfBoundsException ioobe)
			{
			}
			catch (final NumberFormatException nfe)
			{
			}
			
			showChatWindow(player, val);
+		)
+		else if (command.startsWith("solopvp"))
+		{
+		    SoloZoneTaskManager.getInstance();
+		    player.teleportTo(SoloZoneTaskManager.getCurrentZone().getLoc(), 25);
+		}
		else if (command.startsWith("Link"))
		{
			final String path = command.substring(5).trim();
			if (path.indexOf("..") != -1)
				return;
			
			final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
			html.setFile("data/html/" + path);
			html.replace("%objectId%", getObjectId());
			player.sendPacket(html);
		}
diff --git a/java/net/sf/l2j/gameserver/network/clientpackets/RequestRestartPoint.java b/java/net/sf/l2j/gameserver/network/clientpackets/RequestRestartPoint.java
new file mode 100644
index 0000000..6b7ef6f
--- /dev/null
+++ a/java/net/sf/l2j/gameserver/network/clientpackets/RequestRestartPoint.java
		// Fixed.
-		else if (_requestType == 4)
-		{
-			if (!player.isGM() && !player.isFestivalParticipant())
-				return;
-			
-			loc = player.getPosition();
-		}
+		if (_requestType == 4) 
+		{
+		    // Έλεγχος αν ο παίκτης δεν είναι GM, δεν είναι μέρος του φεστιβάλ και δεν είναι στην Solo Zone
+		    if (!player.isGM() && !player.isFestivalParticipant() && !player.isInsideZone(ZoneId.SOLO)) 
+		    {
+		        return;
+		    }
+
+		    SoloZoneTaskManager.getInstance();
+			SoloZone currentZone = SoloZoneTaskManager.getCurrentZone();
+		    if (currentZone != null && currentZone.getLoc() != null) 
+		    {
+		        // Αν υπάρχει ζώνη και οι τοποθεσίες δεν είναι κενές, χρησιμοποιούμε τυχαία τοποθεσία από την ζώνη
+		        loc = currentZone.getLoc();
+		    } else 
+		    {
+		        // Διαφορετικά, κάνουμε respawn στην τρέχουσα θέση του παίκτη
+		        loc = player.getPosition();
+		    }
+		}
diff --git a/java/net/sf/l2j/gameserver/network/clientpackets/RequestRestart.java b/java/net/sf/l2j/gameserver/network/clientpackets/RequestRestart.java
new file mode 100644
index 0000000..6b7ef6f
--- /dev/null
+++ a/java/net/sf/l2j/gameserver/network/clientpackets/RequestRestart.java
		if (player.isFestivalParticipant() && FestivalOfDarknessManager.getInstance().isFestivalInitialized())
		{
			player.sendPacket(SystemMessageId.NO_RESTART_HERE);
			sendPacket(RestartResponse.valueOf(false));
			return;
		}
 		
+        if (player.isInsideZone(ZoneId.SOLO))
+        {
+            player.sendMessage("You cannot restart your character while in Solo Zone. Use .exit to leave");
+            player.setFakeName(null);
+            sendPacket(RestartResponse.valueOf(false));
+            return;
+        }
        
		player.removeFromBossZone();
diff --git a/java/net/sf/l2j/gameserver/network/clientpackets/Logout.java b/java/net/sf/l2j/gameserver/network/clientpackets/Logout.java
new file mode 100644
index 0000000..6b7ef6f
--- /dev/null
+++ a/java/net/sf/l2j/gameserver/network/clientpackets/Logout.java
		player.removeFromBossZone();
		player.logout(true);
	}
}
+
+ 	    if (player.isInsideZone(ZoneId.SOLO))
+ 	    {
+ 	        player.sendMessage("You cannot logout or restart your character while in Solo Zone. Use .exit to leave");
+ 	        player.setFakeName(null); 
+ 	        player.sendPacket(ActionFailed.STATIC_PACKET);
+ 	        return;
+ 	    }
+ 	    
		player.removeFromBossZone();
		player.logout(true);
	}
}
diff --git a/java/net/sf/l2j/gameserver/model/zone/type/SoloZone.java b/java/net/sf/l2j/gameserver/model/zone/type/SoloZone.java
new file mode 100644
index 0000000..6b7ef6f
--- /dev/null
+++ a/java/net/sf/l2j/gameserver/model/zone/type/SoloZone.java
+package net.sf.l2j.gameserver.model.zone.type;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import net.sf.l2j.commons.random.Rnd;
+
+import net.sf.l2j.Config;
+import net.sf.l2j.gameserver.enums.MessageType;
+import net.sf.l2j.gameserver.enums.ZoneId;
+import net.sf.l2j.gameserver.handler.voicecommandhandlers.VoiceExitSoloZone;
+import net.sf.l2j.gameserver.model.World;
+import net.sf.l2j.gameserver.model.actor.Creature;
+import net.sf.l2j.gameserver.model.actor.Player;
+import net.sf.l2j.gameserver.model.location.Location;
+import net.sf.l2j.gameserver.model.zone.type.subtype.ZoneType;
+import net.sf.l2j.gameserver.network.SystemMessageId;
+import net.sf.l2j.gameserver.network.serverpackets.EtcStatusUpdate;
+import net.sf.l2j.gameserver.taskmanager.PvpFlagTaskManager;
+import net.sf.l2j.gameserver.taskmanager.SoloZoneTaskManager;
+
+/**
+ * @author MarGaZeaS
+ *
+ */
+public class SoloZone extends ZoneType
+{
+	private String _name;
+	private List<Location> _locations = new ArrayList<>();
+    
+	public SoloZone(int id)
+	{
+		super(id);
+	}
+	
+ 	@Override
+ 	public void setParameter(String name, String value)
+ 	{
+ 		if (name.equals("name"))
+ 			_name = value;
+        else if (name.equals("locs")) 
+        {
+            for (String locs : value.split(";")) 
+            {
+                String[] coordinates = locs.split(",");
+                if (coordinates.length == 3) 
+                {
+                    int x = Integer.parseInt(coordinates[0]);
+                    int y = Integer.parseInt(coordinates[1]);
+                    int z = Integer.parseInt(coordinates[2]);
+                    _locations.add(new Location(x, y, z));
+                } 
+                else 
+                {
+                    LOGGER.warn("Invalid location format: " + locs);
+                }
+            }
+        }
+    }
+ 	
+
+	@Override
+	protected void onEnter(Creature character) 
+	{
+	    if (character instanceof Player) 
+	    {
+	        final Player player = (Player) character;
+            
+	        if ((player.getClassId().getId() == 15 || player.getClassId().getId() == 16 || player.getClassId().getId() == 97))
+	        {
+	            Location respawnLocation = VoiceExitSoloZone.getExitLocation();
+	            player.instantTeleportTo(respawnLocation, 20);
+	            player.sendMessage("Your class is not allowed in this zone.");
+	            return;
+	        }
+			
+	        String randomName = SoloZoneTaskManager.getInstance().getAName();
+	        if (randomName == null || randomName.isEmpty() || !isValidName(randomName)) 
+	        {
+	            randomName = generateRandomName(); 
+	        }
+	        if (isNameAlreadyTaken(randomName)) 
+	        {
+	            randomName = generateRandomName();
+	        }
+	        player.setFakeName(randomName);
+	        player.sendMessage("Welcome to the Solo Zone, your random name is: " + randomName);
+	        player.sendPacket(SystemMessageId.ENTERED_COMBAT_ZONE);
+	        character.setInsideZone(ZoneId.SOLO, true);
+	        character.setInsideZone(ZoneId.NO_STORE, true);
+	        character.setInsideZone(ZoneId.NO_SUMMON_FRIEND, true);
+	        
+	        if (player.getParty() != null) 
+	        {
+	            player.getParty().removePartyMember(player, MessageType.DISCONNECTED);
+	        }
+	        
+	        if (player.getPvpFlag() > 0) 
+	            PvpFlagTaskManager.getInstance().remove(player, true);
+	        
+	        player.updatePvPStatus();
+	        player.broadcastUserInfo();
+	    }
+	}
+	    
+	private static boolean isValidName(String name) {
+	    return name.matches("[a-zA-Z0-9_]+");
+	}
+
+	private static String generateRandomName() {
+	    Random rand = new Random();
+	    int nameLength = rand.nextInt(12) + 4;
+	    StringBuilder nameBuilder = new StringBuilder();
+	    
+	    for (int i = 0; i < nameLength; i++) {
+	        char randomChar = (char) (rand.nextInt(26) + 'a');
+	        nameBuilder.append(randomChar);
+	    }
+
+	    return nameBuilder.toString();
+	}
+
+	private static boolean isNameAlreadyTaken(String name) {
+	    return World.getInstance().getPlayers().stream().anyMatch(player -> player.getFakeName().equals(name));
+	}
+	
+	@Override
+	protected void onExit(Creature character)
+	{
+		character.setInsideZone(ZoneId.SOLO, false); // Solo zone
+		character.setInsideZone(ZoneId.NO_STORE, false); // Allow making a store
+		character.setInsideZone(ZoneId.NO_SUMMON_FRIEND, false); // Allow summon
+		
+		if (character instanceof Player)
+		{
+			final Player player = (Player) character;
+			
+	        if (player.getFakeName() != null)
+	        {
+	            player.setFakeName(null);
+	        }
+
+	        player.sendPacket(SystemMessageId.LEFT_COMBAT_ZONE);
+			{
+				if(!player.isInObserverMode() && player.getPvpFlag() > 0)
+					PvpFlagTaskManager.getInstance().add(player, Config.PVP_NORMAL_TIME);
+				
+				player.sendPacket(new EtcStatusUpdate(player));
+				player.broadcastUserInfo();
+			}
+		}
+	}
+ 	
+ 	public String getName()
+ 	{
+ 		return _name;
+ 	}
+ 	
+ 	public Location getLoc() 
+ 	{
+ 	    if (_locations.isEmpty()) 
+ 	    {
+ 	        return null;  // Αν η λίστα είναι κενή, επιστρέφουμε null
+ 	    }
+ 	    return _locations.get(Rnd.get(0, _locations.size() - 1));  // Επιλέγουμε τυχαία τοποθεσία
+ 	}
+}
diff --git a/java/net/sf/l2j/gameserver/GameServer.java b/java/net/sf/l2j/gameserver/GameServer.java
new file mode 100644
index 0000000..6b7ef6f
--- /dev/null
+++ a/java/net/sf/l2j/gameserver/GameServer.java
		if (Config.ALLOW_FISH_CHAMPIONSHIP)
			FishingChampionshipManager.getInstance();

+		StringUtil.printSection("Custom Features");
+ 		SoloZoneTaskManager.getInstance();

		StringUtil.printSection("Handlers");
		LOGGER.info("Loaded {} admin command handlers.", AdminCommandHandler.getInstance().size());
diff --git a/java/net/sf/l2j/gameserver/GameServer.java b/java/net/sf/l2j/gameserver/Shutdown.java
new file mode 100644
index 0000000..6b7ef6f
--- /dev/null
+++ a/java/net/sf/l2j/gameserver/Shutdown.java
			// disconnect players
			try
			{
				disconnectAllPlayers();
				LOGGER.info("All players have been disconnected.");
			}
			catch (Exception e)
			{
				// Silent catch.
			}
			        
+			// Restore real names for players in SoloZone
+			restoreRealNamesInSoloZone();
			
			// stop all threadpolls
			ThreadPool.shutdown();
			
			try
			{
				LoginServerThread.getInstance().interrupt();
			}
			catch (Exception e)
			{
				// Silent catch.
			}
			
			
			
				// avoids new players from logging in
				if (_secondsShut <= 60 && LoginServerThread.getInstance().getServerType() != ServerType.DOWN)
					LoginServerThread.getInstance().setServerType(ServerType.DOWN);
				
				_secondsShut--;
				
				Thread.sleep(1000);
			}
		}
		catch (InterruptedException e)
		{
		}
	}
	
+ 	// This method restores the real names of players in SoloZone
+ 	private static void restoreRealNamesInSoloZone()
+ 	{
+ 		for (Player player : World.getInstance().getPlayers())
+ 		{
+ 			// Check if player is inside the SoloZone
+ 			if (player.isInsideZone(ZoneId.SOLO))
+ 			{
+ 				// Restore the real name by removing the fake name
+ 				if (player.getFakeName() != null)
+ 				{
+ 					player.setFakeName(null);  // Restore the real name
+ 					LOGGER.info("Player {}'s fake name has been removed and real name restored.", player.getName());
+ 				}
+ 			}
+ 		}
+ 	}
 	
	private static void sendServerQuit(int seconds)
	{
		World.toAllOnlinePlayers(SystemMessage.getSystemMessage(SystemMessageId.THE_SERVER_WILL_BE_COMING_DOWN_IN_S1_SECONDS).addNumber(seconds));
	}
diff --git a/java/net/sf/l2j/gameserver/enums/ZoneId.java b/java/net/sf/l2j/gameserver/enums/ZoneId.java
new file mode 100644
index 0000000..6b7ef6f
--- /dev/null
+++ a/java/net/sf/l2j/gameserver/enums/ZoneId.java
public enum ZoneId
{
	PVP(0),
	PEACE(1),
	SIEGE(2),
	MOTHER_TREE(3),
	CLAN_HALL(4),
	NO_LANDING(5),
	WATER(6),
	JAIL(7),
	MONSTER_TRACK(8),
	CASTLE(9),
	SWAMP(10),
	NO_SUMMON_FRIEND(11),
	NO_STORE(12),
	TOWN(13),
	HQ(14),
	DANGER_AREA(15),
	CAST_ON_ARTIFACT(16),
	NO_RESTART(17),
	SCRIPT(18),
-	BOSS(19),
+	BOSS(19),
+	SOLO(20);
	
	private final int _id;
	
	private ZoneId(int id)
	{
		_id = id;
	}
diff --git a/java/net/sf/l2j/gameserver/network/serverpackets/Die.java b/java/net/sf/l2j/gameserver/network/serverpackets/Die.java
new file mode 100644
index 0000000..6b7ef6f
--- /dev/null
+++ a/java/net/sf/l2j/gameserver/network/serverpackets/Die.java
		if (creature instanceof Player)
		{
			Player player = (Player) creature;
-			_allowFixedRes = player.getAccessLevel().allowFixedRes();
+			_allowFixedRes = player.getAccessLevel().allowFixedRes() || player.isInsideZone(ZoneId.SOLO);
			_clan = player.getClan();
			
		}
diff --git a/java/net/sf/l2j/gameserver/model/actor/Player.java b/java/net/sf/l2j/gameserver//model/actor/Player.java
new file mode 100644
index 0000000..6b7ef6f
--- /dev/null
+++ a/java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java
		// Attacker or spectator logging into a siege zone will be ported at town.
		if (player.isInsideZone(ZoneId.SIEGE) && player.getSiegeState() < 2)
			player.teleportTo(TeleportType.TOWN);
		
+		if (player.isInsideZone(ZoneId.SOLO)) 
+		{
+		    ThreadPool.schedule(() -> {
+		        Location exitLocation = VoiceExitSoloZone.getExitLocation();
+		        
+		        if (exitLocation != null) 
+		        {
+		            player.teleportTo(exitLocation.getX(), exitLocation.getY(), exitLocation.getZ(), 0);
+		            player.sendMessage("You have been moved to the exit of the SoloZone.");
+		        }
+		    }, 5000); // 5000 milliseconds (5sec)
+		}
diff --git a/java/net/sf/l2j/gameserver/model/actor/Player.java b/java/net/sf/l2j/gameserver/model/actor/Player.java
new file mode 100644
index 0000000..6b7ef6f
--- /dev/null
+++ a/java/net/sf/l2j/gameserver/model/actor/Player.java
	@Override
	public void doRevive()
	{
		super.doRevive();
		
		stopEffects(EffectType.CHARM_OF_COURAGE);
		sendPacket(new EtcStatusUpdate(this));
		
	    getStatus().setCpHpMp(getStatus().getMaxCp(), getStatus().getMaxHp(), getStatus().getMaxMp());

		_reviveRequested = 0;
		_revivePower = 0;
		
		if (isMounted())
			startFeed(_mountNpcId);
+	    if (isInsideZone(ZoneId.SOLO)) 
+	    {
+	        // Give Nobless (1323 ID)
+	        L2Skill no = SkillTable.getInstance().getInfo(1323, 1);
+	        no.getEffects(this, this);
+	        sendMessage("You have received the Nobless status in the Solo Zone.");
+	    }
+	}

 

If anyone thinks the code is wrong, please make an update and upload it here so I can update the post. A part was edited with chatgpt

  • Like 1
  • Thanks 2

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...