22
33import java .util .HashSet ;
44import java .util .Set ;
5- import java .util .UUID ;
65
76import org .bukkit .Bukkit ;
87import org .bukkit .Location ;
9- import org .bukkit .World ;
108import org .bukkit .entity .Display .Billboard ;
119import org .bukkit .entity .Entity ;
1210import org .bukkit .entity .EntityType ;
2725
2826/**
2927 * Handles Holographic elements
30- *
31- * @author tastybento, HSGamer
3228 */
3329public class HoloListener implements Listener {
3430 private final AOneBlock addon ;
35- private final Set <Location > holograms ;
31+ private final Set <Location > activeHolograms ;
32+ private static final Vector DEFAULT_OFFSET = new Vector (0.5 , 1.1 , 0.5 );
3633
3734 /**
3835 * @param addon - OneBlock
3936 */
4037 public HoloListener (@ NonNull AOneBlock addon ) {
4138 this .addon = addon ;
42- this .holograms = new HashSet <>();
39+ this .activeHolograms = new HashSet <>();
4340 }
4441
4542 /**
@@ -50,173 +47,149 @@ public HoloListener(@NonNull AOneBlock addon) {
5047 */
5148 @ EventHandler (priority = EventPriority .NORMAL , ignoreCancelled = true )
5249 public void onDeletedIsland (IslandDeleteEvent e ) {
53- deleteHologram (e .getIsland ());
50+ removeHologramAt (e .getIsland ());
5451 }
5552
5653 /**
57- * Creates a new hologram (TextDisplay) at the island's center plus offset.
58- * Caches the hologram for future reference.
59- *
60- * @param island the island to create the hologram for
61- * @return the created TextDisplay
54+ * Clears all cached holograms and removes their entities.
55+ * Called when disabling
6256 */
63- private TextDisplay createHologram (Island island ) {
64- Location pos = island .getCenter ().clone ().add (parseVector (addon .getSettings ().getOffset ()));
65- World world = pos .getWorld ();
66- assert world != null ;
67-
68- TextDisplay newDisplay = world .spawn (pos , TextDisplay .class );
69- newDisplay .setAlignment (TextDisplay .TextAlignment .CENTER );
70- newDisplay .setBillboard (Billboard .CENTER );
71- // Save location so it can be deleted
72- holograms .add (pos );
73-
74- return newDisplay ;
57+ public void onDisable () {
58+ activeHolograms .forEach (this ::cleanupHologram );
59+ activeHolograms .clear ();
7560 }
7661
7762 /**
78- * Parses a string in the format "x,y,z" into a Vector .
79- * If parsing fails, returns a default vector .
63+ * Sets up the hologram for a specific island .
64+ * If it's a new island, sets the starting hologram line .
8065 *
81- * @param str the string to parse
82- * @return the parsed Vector
66+ * @param island the island to set up
67+ * @param is the OneBlockIslands data object
68+ * @param newIsland whether this is a new island
8369 */
84- private static Vector parseVector (String str ) {
85- if (str == null ) {
86- return new Vector (0.5 , 1.1 , 0.5 );
87- }
88- String [] parts = str .split ("," );
89- if (parts .length != 3 ) {
90- return new Vector (0.5 , 1.1 , 0.5 );
70+ protected void setUp (@ NonNull Island island , @ NonNull OneBlockIslands is , boolean newIsland ) {
71+ if (!addon .getSettings ().isUseHolograms () || island .getOwner () == null ) {
72+ return ;
9173 }
9274
93- try {
94- double x = Double .parseDouble (parts [0 ].trim ());
95- double y = Double .parseDouble (parts [1 ].trim ());
96- double z = Double .parseDouble (parts [2 ].trim ());
97- return new Vector (x , y , z );
98- } catch (NumberFormatException e ) {
99- return new Vector (0.5 , 1.1 , 0.5 );
75+ if (newIsland ) {
76+ String startingText = User .getInstance (island .getOwner ())
77+ .getTranslation ("aoneblock.island.starting-hologram" );
78+ is .setHologram (startingText == null ? "" : startingText );
10079 }
80+ updateHologram (island , is .getHologram ());
81+ }
82+
83+ /**
84+ * Processes the phase change for an island and updates its hologram.
85+ *
86+ * @param i the island
87+ * @param is the OneBlockIslands data object
88+ * @param phase the current OneBlockPhase
89+ */
90+ protected void process (@ NonNull Island i , @ NonNull OneBlockIslands is , @ NonNull OneBlockPhase phase ) {
91+ String holoText = phase .getHologramLine (is .getBlockNumber ());
92+ is .setHologram (holoText == null ? "" : Util .translateColorCodes (holoText ));
93+ updateHologram (i , is .getHologram ());
10194 }
10295
10396 /**
10497 * Updates the hologram lines for the given island.
10598 * Handles creation, updating, and scheduled deletion of holograms.
10699 *
107100 * @param island the island to update
108- * @param oneBlockIsland the OneBlockIslands data object
101+ * @param text the text to display
109102 */
110- private void updateLines (Island island , OneBlockIslands oneBlockIsland ) {
111- // Ignore if holograms are disabled
112- if (!addon .getSettings ().isUseHolograms ()) {
113- return ;
114- }
115- // Delete the old hologram, if any
116- this .deleteHologram (island );
117- // Get the new hologram
118- String holoLine = oneBlockIsland .getHologram ();
119-
120- // Return hologram if empty
121- if (holoLine .isBlank ()) {
103+ private void updateHologram (Island island , String text ) {
104+ if (!addon .getSettings ().isUseHolograms () || text .isBlank ()) {
122105 return ;
123106 }
124107
125- // Get or create hologram if needed
126- TextDisplay hologram = createHologram (island );
127-
128- // Doesn't seem to do much but can't harm
129- hologram .setPersistent (true );
130-
131- // Set lines to hologram
132- hologram .setText (holoLine );
108+ removeHologramAt (island );
109+ Location pos = getHologramLocation (island );
110+ createHologram (pos , text );
133111
134112 // Set up auto delete if duration is set
135113 if (addon .getSettings ().getHologramDuration () > 0 ) {
136- Bukkit .getScheduler ().runTaskLater (addon .getPlugin (), () -> deleteHologram (island ), addon .getSettings ().getHologramDuration () * 20L );
114+ Bukkit .getScheduler ().runTaskLater (addon .getPlugin (),
115+ () -> removeHologramAt (island ),
116+ addon .getSettings ().getHologramDuration () * 20L );
137117 }
138118 }
139119
140120 /**
141- * Setup holograms on startup
121+ * Gets the location for the hologram based on the island's center and the configured offset.
122+ *
123+ * @param island the island
124+ * @return the location for the hologram
142125 */
143- public void setUp () {
144- addon .getIslands ().getIslands ().stream ()
145- .filter (i -> addon .inWorld (i .getWorld ()))
146- .forEach (island -> setUp (island , addon .getOneBlocksIsland (island ), false ));
126+ private Location getHologramLocation (Island island ) {
127+ Vector offset = parseVector (addon .getSettings ().getOffset ());
128+ return island .getCenter ().clone ().add (offset );
147129 }
148130
149131 /**
150- * Clears all cached holograms and removes their entities.
151- * Called when disabling
132+ * Creates a new hologram (TextDisplay) at the given location.
133+ * Caches the hologram for future reference.
134+ *
135+ * @param pos the location to create the hologram at
136+ * @param text the text to display
152137 */
153- public void clear () {
154- holograms .forEach (this ::removeHologram );
155- holograms .clear ();
138+ private void createHologram (Location pos , String text ) {
139+ TextDisplay display = pos .getWorld ().spawn (pos , TextDisplay .class );
140+ display .setAlignment (TextDisplay .TextAlignment .CENTER );
141+ display .setBillboard (Billboard .CENTER );
142+ display .setPersistent (true );
143+ display .setText (text );
144+ activeHolograms .add (pos );
156145 }
157146
158147 /**
159148 * Deletes the hologram for the given island and removes any residual holograms nearby.
160149 *
161150 * @param island the island whose hologram should be deleted
162151 */
163- private void deleteHologram (@ NonNull Island island ) {
152+ private void removeHologramAt (@ NonNull Island island ) {
164153 if (island .getWorld () == null || island .getCenter () == null ) {
165154 return ;
166155 }
167- Location pos = island .getCenter ().clone ().add (parseVector (addon .getSettings ().getOffset ()));
168- removeHologram (pos );
156+ cleanupHologram (getHologramLocation (island ));
169157 }
170158
171159 /**
172160 * Removes any holograms at this location
173161 * @param pos location
174162 */
175- private void removeHologram (Location pos ) {
176- holograms .remove (pos );
163+ private void cleanupHologram (Location pos ) {
164+ activeHolograms .remove (pos );
177165 // Chunks have to be loaded for the entity to exist to be deleted
178- Util .getChunkAtAsync (pos ).thenRun (() -> {
179- // Search for entities in a small radius (e.g., 1 block around)
180- for (Entity entity : pos .getWorld ().getNearbyEntities (pos , 1 , 1 , 1 )) {
181- if (entity .getType () == EntityType .TEXT_DISPLAY ) {
182- ((TextDisplay ) entity ).remove ();
183- }
184- }
185- });
166+ Util .getChunkAtAsync (pos ).thenRun (() ->
167+ pos .getWorld ().getNearbyEntities (pos , 1 , 1 , 1 ).stream ()
168+ .filter (e -> e .getType () == EntityType .TEXT_DISPLAY )
169+ .forEach (Entity ::remove ));
186170 }
187171
188172 /**
189- * Sets up the hologram for a specific island .
190- * If it's a new island, sets the starting hologram line .
173+ * Parses a string in the format "x,y,z" into a Vector .
174+ * If parsing fails, returns a default vector .
191175 *
192- * @param island the island to set up
193- * @param is the OneBlockIslands data object
194- * @param newIsland whether this is a new island
176+ * @param str the string to parse
177+ * @return the parsed Vector
195178 */
196- protected void setUp (@ NonNull Island island , @ NonNull OneBlockIslands is , boolean newIsland ) {
197- UUID ownerUUID = island .getOwner ();
198- if (ownerUUID == null ) {
199- return ;
179+ private static Vector parseVector (String str ) {
180+ if (str == null ) {
181+ return DEFAULT_OFFSET ;
200182 }
201-
202- User owner = User .getInstance (ownerUUID );
203- if (newIsland ) {
204- String holoLine = owner .getTranslation ("aoneblock.island.starting-hologram" );
205- is .setHologram (holoLine == null ? "" : holoLine );
183+ try {
184+ String [] parts = str .split ("," );
185+ return parts .length == 3
186+ ? new Vector (
187+ Double .parseDouble (parts [0 ].trim ()),
188+ Double .parseDouble (parts [1 ].trim ()),
189+ Double .parseDouble (parts [2 ].trim ()))
190+ : DEFAULT_OFFSET ;
191+ } catch (NumberFormatException e ) {
192+ return DEFAULT_OFFSET ;
206193 }
207- updateLines (island , is );
208- }
209-
210- /**
211- * Processes the phase change for an island and updates its hologram.
212- *
213- * @param i the island
214- * @param is the OneBlockIslands data object
215- * @param phase the current OneBlockPhase
216- */
217- protected void process (@ NonNull Island i , @ NonNull OneBlockIslands is , @ NonNull OneBlockPhase phase ) {
218- String holoLine = phase .getHologramLine (is .getBlockNumber ());
219- is .setHologram (holoLine == null ? "" : Util .translateColorCodes (holoLine ));
220- updateLines (i , is );
221194 }
222195}
0 commit comments