Skip to content

Commit 5b836e4

Browse files
cryptobenchclaude
andcommitted
Add title banner when entering/leaving claimed zones
Shows a title notification when players walk into or out of claimed areas, displaying "Wilderness" (green) for unclaimed land, "Your Claim" (cyan) for own claims, or "[Owner]'s Claim" (white) for others' claims. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 473b79c commit 5b836e4

2 files changed

Lines changed: 108 additions & 0 deletions

File tree

src/main/java/com/easyclaims/EasyClaims.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import com.easyclaims.systems.BlockDamageProtectionSystem;
1515
import com.easyclaims.systems.BlockPlaceProtectionSystem;
1616
import com.easyclaims.systems.BlockUseProtectionSystem;
17+
import com.easyclaims.systems.ClaimTitleSystem;
1718
import com.hypixel.hytale.server.core.event.events.player.PlayerConnectEvent;
1819
import com.hypixel.hytale.server.core.event.events.player.PlayerDisconnectEvent;
1920
import com.hypixel.hytale.server.core.plugin.JavaPlugin;
@@ -49,6 +50,7 @@ public class EasyClaims extends JavaPlugin {
4950
private PlaytimeManager playtimeManager;
5051
private ClaimProtectionListener protectionListener;
5152
private ClaimMapOverlayProvider mapOverlayProvider;
53+
private ClaimTitleSystem claimTitleSystem;
5254

5355
// Track registered worlds for map provider
5456
public static final Map<String, World> WORLDS = new HashMap<>();
@@ -110,6 +112,11 @@ public void setup() {
110112
getEntityStoreRegistry().registerSystem(new BlockBreakProtectionSystem(claimManager, getLogger()));
111113
getEntityStoreRegistry().registerSystem(new BlockPlaceProtectionSystem(claimManager, getLogger()));
112114
getEntityStoreRegistry().registerSystem(new BlockUseProtectionSystem(claimManager, getLogger()));
115+
116+
// Register claim title system (shows banner when entering/leaving claims)
117+
claimTitleSystem = new ClaimTitleSystem(claimStorage);
118+
getEntityStoreRegistry().registerSystem(claimTitleSystem);
119+
113120
getLogger().atInfo().log("All ECS systems registered successfully!");
114121
} catch (Exception e) {
115122
getLogger().atSevere().withCause(e).log("ERROR registering ECS systems");
@@ -306,6 +313,11 @@ private void onPlayerDisconnect(PlayerDisconnectEvent event) {
306313
mapOverlayProvider.clearPlayerCache(playerId);
307314
}
308315

316+
// Clear title tracking for this player
317+
if (claimTitleSystem != null) {
318+
claimTitleSystem.removePlayer(playerId);
319+
}
320+
309321
getLogger().atFine().log("Player disconnected: %s", playerId);
310322
}
311323
} catch (Exception e) {
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package com.easyclaims.systems;
2+
3+
import com.easyclaims.data.ClaimStorage;
4+
import com.easyclaims.util.ChunkUtil;
5+
import com.hypixel.hytale.component.ArchetypeChunk;
6+
import com.hypixel.hytale.component.CommandBuffer;
7+
import com.hypixel.hytale.component.Ref;
8+
import com.hypixel.hytale.component.Store;
9+
import com.hypixel.hytale.component.query.Query;
10+
import com.hypixel.hytale.component.system.tick.EntityTickingSystem;
11+
import com.hypixel.hytale.server.core.Message;
12+
import com.hypixel.hytale.server.core.entity.entities.Player;
13+
import com.hypixel.hytale.server.core.universe.PlayerRef;
14+
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
15+
import com.hypixel.hytale.server.core.util.EventTitleUtil;
16+
17+
import javax.annotation.Nullable;
18+
import java.awt.Color;
19+
import java.util.Map;
20+
import java.util.UUID;
21+
import java.util.concurrent.ConcurrentHashMap;
22+
23+
/**
24+
* Ticking system that shows a title banner when players enter or leave claimed zones.
25+
* Runs every tick for all players and displays a title when the claim status changes.
26+
*/
27+
public class ClaimTitleSystem extends EntityTickingSystem<EntityStore> {
28+
29+
private static final Message WILDERNESS_MESSAGE = Message.raw("Wilderness").color(new Color(85, 255, 85));
30+
private static final Message EASY_CLAIMS_MESSAGE = Message.raw("EasyClaims");
31+
private static final String WILDERNESS_TEXT = "Wilderness";
32+
33+
private final ClaimStorage claimStorage;
34+
private final Map<UUID, String> playerLastTitle;
35+
36+
public ClaimTitleSystem(ClaimStorage claimStorage) {
37+
this.claimStorage = claimStorage;
38+
this.playerLastTitle = new ConcurrentHashMap<>();
39+
}
40+
41+
@Override
42+
public void tick(float deltaTime, int index, ArchetypeChunk<EntityStore> archetypeChunk,
43+
Store<EntityStore> store, CommandBuffer<EntityStore> commandBuffer) {
44+
Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index);
45+
if (ref == null) return;
46+
47+
PlayerRef playerRef = store.getComponent(ref, PlayerRef.getComponentType());
48+
Player player = store.getComponent(ref, Player.getComponentType());
49+
if (playerRef == null || player == null) return;
50+
51+
// Get player's current position and convert to chunk coordinates
52+
double posX = playerRef.getTransform().getPosition().getX();
53+
double posZ = playerRef.getTransform().getPosition().getZ();
54+
int chunkX = ChunkUtil.toChunkX(posX);
55+
int chunkZ = ChunkUtil.toChunkZ(posZ);
56+
String worldName = player.getWorld().getName();
57+
58+
// Check if this chunk is claimed
59+
Message titleMessage = WILDERNESS_MESSAGE;
60+
String titleText = WILDERNESS_TEXT;
61+
62+
UUID claimOwner = claimStorage.getClaimOwner(worldName, chunkX, chunkZ);
63+
if (claimOwner != null) {
64+
String ownerName = claimStorage.getPlayerName(claimOwner);
65+
titleText = ownerName + "'s Claim";
66+
67+
// Use different colors for own claims vs others
68+
if (claimOwner.equals(playerRef.getUuid())) {
69+
titleMessage = Message.raw("Your Claim").color(new Color(85, 255, 255)); // Cyan for own claim
70+
} else {
71+
titleMessage = Message.raw(ownerName + "'s Claim").color(Color.WHITE);
72+
}
73+
}
74+
75+
// Only show title if the claim has changed
76+
String previousTitle = playerLastTitle.get(playerRef.getUuid());
77+
if (!titleText.equals(previousTitle)) {
78+
playerLastTitle.put(playerRef.getUuid(), titleText);
79+
EventTitleUtil.showEventTitleToPlayer(playerRef, titleMessage, EASY_CLAIMS_MESSAGE,
80+
false, null, 2, 0.5f, 0.5f);
81+
}
82+
}
83+
84+
/**
85+
* Remove player from tracking when they disconnect.
86+
*/
87+
public void removePlayer(UUID playerId) {
88+
playerLastTitle.remove(playerId);
89+
}
90+
91+
@Nullable
92+
@Override
93+
public Query<EntityStore> getQuery() {
94+
return PlayerRef.getComponentType();
95+
}
96+
}

0 commit comments

Comments
 (0)