-
Notifications
You must be signed in to change notification settings - Fork 2
ZoneHelper
A utility class for zone/region management and discovery tracking in Hytale. Provides methods for tracking player zone discoveries, querying current zones, and managing zone-related data.
What are Zones?
Zones in Hytale are named regions of the world that players can discover. When a player enters a new zone for the first time, a discovery event is triggered. ZoneHelper provides utilities to:
- Track which zones each player has discovered
- Query a player's current zone
- Find all players in a specific zone
- Get statistics about zone discoveries
Important: Zone tracking must be initialized when the world loads using initializeZoneTracking().
Initialize zone discovery tracking for a world. This should be called once when the world loads.
Parameters:
-
world- The world to track zones in
Example:
@Override
public void onWorldLoad(AddPlayerToWorldEvent event) {
World world = event.getWorld();
// Initialize zone tracking
ZoneHelper.initializeZoneTracking(world);
LOGGER.log("Zone tracking initialized");
}Important: Call this in your AddPlayerToWorldEvent handler to ensure zone tracking works properly.
Get the current zone a player is in.
Parameters:
-
player- The player entity
Returns: String - The zone name, or null if not in a tracked zone
Example:
String currentZone = ZoneHelper.getCurrentZone(player);
if (currentZone != null) {
PlayerHelper.sendMessage(player, "You are in: " + currentZone);
} else {
PlayerHelper.sendMessage(player, "You are not in a named zone");
}Set the current zone for a player. This is typically called automatically by zone tracking systems.
Parameters:
-
player- The player entity -
zoneName- The zone name (null to clear)
Example:
// Manually set player's current zone
ZoneHelper.setCurrentZone(player, "Forest_Clearing");
// Clear current zone
ZoneHelper.setCurrentZone(player, null);Check if a player is in a specific zone.
Parameters:
-
player- The player entity -
zoneName- The zone name to check
Returns: boolean - true if the player is in the specified zone
Example:
if (ZoneHelper.isInZone(player, "Dangerous_Cave")) {
PlayerHelper.sendMessage(player, "⚠ Warning: This area is dangerous!");
}
// Quest requirement
if (ZoneHelper.isInZone(player, "Ancient_Temple")) {
// Complete quest objective
PlayerHelper.sendMessage(player, "Quest objective complete!");
}Get all zones a player has discovered.
Parameters:
-
player- The player entity
Returns: List<String> - List of discovered zone names
Example:
List<String> discovered = ZoneHelper.getDiscoveredZones(player);
PlayerHelper.sendMessage(player, "You have discovered " + discovered.size() + " zones:");
for (String zone : discovered) {
PlayerHelper.sendMessage(player, " - " + zone);
}Mark a zone as discovered for a player.
Parameters:
-
player- The player entity -
zoneName- The zone name to mark as discovered
Returns: boolean - true if this is a new discovery, false if already discovered
Example:
// Manually trigger zone discovery
boolean isNew = ZoneHelper.discoverZone(player, "Hidden_Cave");
if (isNew) {
PlayerHelper.sendMessage(player, "🎉 You discovered: Hidden_Cave!");
InventoryHelper.giveItem(player, "Item_Discovery_Token", 1);
} else {
PlayerHelper.sendMessage(player, "You've been here before.");
}Use Cases:
- Custom discovery triggers
- Quest rewards
- Secret area discoveries
- Achievement systems
Check if a player has discovered a specific zone.
Parameters:
-
player- The player entity -
zoneName- The zone name to check
Returns: boolean - true if the player has discovered this zone
Example:
// Quest requirement
if (ZoneHelper.hasDiscoveredZone(player, "Mountain_Peak")) {
PlayerHelper.sendMessage(player, "You may now access the summit quest!");
}
// Unlock fast travel
if (ZoneHelper.hasDiscoveredZone(player, "Village_Square")) {
// Enable teleport to village
}Clear all discovered zones for a player. Useful for resetting player progress.
Parameters:
-
player- The player entity
Example:
// Reset player's exploration progress
ZoneHelper.clearDiscoveredZones(player);
PlayerHelper.sendMessage(player, "Your exploration progress has been reset.");Get the number of zones a player has discovered.
Parameters:
-
player- The player entity
Returns: int - The count of discovered zones
Example:
int count = ZoneHelper.getDiscoveredZoneCount(player);
PlayerHelper.sendMessage(player, "Zones discovered: " + count + "/50");
// Achievement check
if (count >= 25) {
PlayerHelper.sendMessage(player, "🏆 Achievement: Explorer!");
}Get all unique zones that have been discovered by any player.
Returns: Set<String> - Set of all discovered zone names
Example:
Set<String> allZones = ZoneHelper.getAllDiscoveredZones();
WorldHelper.log(world, "Total zones discovered by all players: " + allZones.size());
for (String zone : allZones) {
WorldHelper.log(world, " - " + zone);
}Get the total number of players who have discovered a specific zone.
Parameters:
-
zoneName- The zone name
Returns: int - The count of players who discovered this zone
Example:
int count = ZoneHelper.getZoneDiscoveryCount("Secret_Dungeon");
WorldHelper.log(world, count + " players have found the secret dungeon");
// Rare zone tracking
if (count < 5) {
PlayerHelper.sendMessage(player, "You're one of the first to discover this place!");
}Get all players currently in a specific zone.
Parameters:
-
world- The world to search in -
zoneName- The zone name
Returns: List<Entity> - List of players in the zone
Example:
List<Entity> playersInZone = ZoneHelper.getPlayersInZone(world, "Arena");
if (playersInZone.size() >= 2) {
// Start PvP match
for (Entity player : playersInZone) {
PlayerHelper.sendMessage(player, "⚔ Arena match starting!");
}
}
// Zone event
if (playersInZone.size() > 0) {
WorldHelper.log(world, "Event starting in Arena with " + playersInZone.size() + " players");
}Use Cases:
- Zone-based events
- PvP arena management
- Group quests
- Zone population monitoring
@Override
public void onWorldLoad(AddPlayerToWorldEvent event) {
World world = event.getWorld();
// Initialize zone tracking
ZoneHelper.initializeZoneTracking(world);
// Set up zone discovery event
EcsEventHelper.onZoneDiscovery(world, (discoveryInfo) -> {
String zoneName = discoveryInfo.zoneName();
// Find the player who discovered it
// Note: You'd need to track this from the event context
// For now, this logs the discovery
WorldHelper.log(world, "Zone discovered: " + zoneName);
});
}
// Manual zone tracking with player movement
WorldHelper.onTickInterval(world, 20, tick -> {
List<Entity> players = EntityHelper.getAllEntities(world);
for (Entity player : players) {
if (!(player instanceof Player)) continue;
// Check player position and update current zone
// This is a simplified example
Vector3d pos = EntityHelper.getPosition(player);
if (pos.x > 100 && pos.x < 200 && pos.z > 100 && pos.z < 200) {
String oldZone = ZoneHelper.getCurrentZone(player);
String newZone = "Forest_Clearing";
if (!newZone.equals(oldZone)) {
ZoneHelper.setCurrentZone(player, newZone);
// Check if it's a new discovery
if (ZoneHelper.discoverZone(player, newZone)) {
PlayerHelper.sendMessage(player, "🎉 Discovered: " + newZone);
}
}
}
}
});// Quest: Discover 5 specific zones
String[] requiredZones = {
"Ancient_Temple",
"Dark_Forest",
"Mountain_Peak",
"Hidden_Cave",
"Coastal_Village"
};
EventHelper.onPlayerChat(plugin, (username, message) -> {
if (message.equals("!quest")) {
Entity player = EntityHelper.getPlayerByName(world, username);
if (player == null) return;
int discovered = 0;
List<String> missing = new ArrayList<>();
for (String zone : requiredZones) {
if (ZoneHelper.hasDiscoveredZone(player, zone)) {
discovered++;
} else {
missing.add(zone);
}
}
PlayerHelper.sendMessage(player, "Quest Progress: " + discovered + "/" + requiredZones.length);
if (discovered == requiredZones.length) {
PlayerHelper.sendMessage(player, "✅ Quest Complete! Reward: 10 Diamonds");
InventoryHelper.giveItem(player, "Gem_Diamond", 10);
} else {
PlayerHelper.sendMessage(player, "Missing zones:");
for (String zone : missing) {
PlayerHelper.sendMessage(player, " - " + zone);
}
}
}
});// Check arena population every 5 seconds
WorldHelper.onTickInterval(world, 100, tick -> {
List<Entity> playersInArena = ZoneHelper.getPlayersInZone(world, "PvP_Arena");
if (playersInArena.size() >= 2) {
// Start match
for (Entity player : playersInArena) {
PlayerHelper.sendMessage(player, "⚔ PvP Match Starting!");
PlayerHelper.sendMessage(player, "Players: " + playersInArena.size());
}
} else if (playersInArena.size() == 1) {
Entity player = playersInArena.get(0);
PlayerHelper.sendMessage(player, "Waiting for opponent...");
}
});EventHelper.onPlayerChat(plugin, (username, message) -> {
if (message.equals("!explorer")) {
Entity player = EntityHelper.getPlayerByName(world, username);
if (player == null) return;
int count = ZoneHelper.getDiscoveredZoneCount(player);
List<String> zones = ZoneHelper.getDiscoveredZones(player);
PlayerHelper.sendMessage(player, "=== Explorer Stats ===");
PlayerHelper.sendMessage(player, "Zones Discovered: " + count);
// Award titles based on discovery count
if (count >= 50) {
PlayerHelper.sendMessage(player, "🏆 Title: Master Explorer");
} else if (count >= 25) {
PlayerHelper.sendMessage(player, "🏆 Title: Adventurer");
} else if (count >= 10) {
PlayerHelper.sendMessage(player, "🏆 Title: Wanderer");
}
// Show recent discoveries
PlayerHelper.sendMessage(player, "Recent discoveries:");
int shown = Math.min(5, zones.size());
for (int i = 0; i < shown; i++) {
PlayerHelper.sendMessage(player, " - " + zones.get(i));
}
}
});-
Initialize tracking early - Call
initializeZoneTracking()in your world load event -
Combine with EcsEventHelper - Use
onZoneDiscovery()for automatic tracking -
Manual zone updates - Use
setCurrentZone()for custom zone systems -
Quest integration - Use
hasDiscoveredZone()for quest requirements - Statistics tracking - Use discovery counts for achievements and leaderboards
-
Zone events - Use
getPlayersInZone()for zone-based multiplayer events
- Thread Safety: All methods are thread-safe using concurrent collections
- Persistence: Zone discoveries are stored in memory and reset on server restart
- Player Identification: Uses player UUID for tracking (deprecated but functional)
- Zone Names: Case-sensitive, use exact zone names from discovery events
- EcsEventHelper - For zone discovery events
- EntityHelper - For player queries and management
- PlayerHelper - For player messaging and utilities
- WorldHelper - For world operations and tick scheduling