2929import me .tofaa .entitylib .wrapper .WrapperPlayer ;
3030import me .tofaa .entitylib .wrapper .hologram .Hologram ;
3131import net .kyori .adventure .text .Component ;
32+ import net .kyori .adventure .text .minimessage .MiniMessage ;
3233import org .bukkit .Bukkit ;
3334import org .bukkit .World ;
3435import org .bukkit .entity .Player ;
@@ -319,9 +320,32 @@ public void remove() {
319320 NPCRegistry .unregister (this );
320321 }
321322
323+ /**
324+ * Splits a Component into multiple lines on {@code <br>} tags.
325+ * MiniMessage keeps {@code <br>} as a tag token through serialize/deserialize round-trips,
326+ * so we serialize back to a MiniMessage string and split on the literal {@code <br>} token
327+ * before re-deserializing each fragment into its own Component. This allows multi-line NPC
328+ * name tags to be rendered as separate hologram line entities, since armor stands and text
329+ * displays do not visually break a single component on newlines.
330+ */
331+ private List <Component > splitDisplayNameLines (Component component ) {
332+ MiniMessage mm = MiniMessage .miniMessage ();
333+ String serialized = mm .serialize (component );
334+ // MiniMessage round-trips <br> as the literal tag string "<br>"
335+ String [] parts = serialized .split ("(?i)<br>" , -1 );
336+ if (parts .length == 1 ) {
337+ return Collections .singletonList (component );
338+ }
339+ List <Component > lines = new ArrayList <>(parts .length );
340+ for (String part : parts ) {
341+ lines .add (mm .deserialize (part ));
342+ }
343+ return lines ;
344+ }
345+
322346 private void createHologram () {
323347 Location loc = getPosition ();
324- double yOffset = options .isSitting () ? 2.76 : 2.26 ;
348+ double yOffset = options .isSitting () ? 1.1 : 1.0 ;
325349 Location hologramLoc = new Location (
326350 loc .getX (),
327351 loc .getY () + yOffset ,
@@ -330,24 +354,15 @@ private void createHologram() {
330354 loc .getPitch ()
331355 );
332356
333- int protocolVersion = EntityLib .getApi ()
334- .getPacketEvents ()
335- .getServerManager ()
336- .getVersion ()
337- .getProtocolVersion ();
357+ Hologram .Legacy hologram = Hologram .legacy (hologramLoc );
358+ hologram .setLineOffset (-0.28f );
338359
339- Hologram hologram ;
340- if ( protocolVersion >= 760 ) {
341- hologram = Hologram . modern ( hologramLoc );
342- } else {
343- hologram = Hologram . legacy ( hologramLoc );
360+ Component displayName = options . getDisplayName () != null
361+ ? options . getDisplayName ()
362+ : Component . text ( name );
363+ for ( Component line : splitDisplayNameLines ( displayName )) {
364+ hologram . addLine ( line );
344365 }
345-
346- hologram .addLine (
347- options .getDisplayName () != null
348- ? options .getDisplayName ()
349- : Component .text (name )
350- );
351366 hologram .show ();
352367// if (hologram.getEntity().getEntityMeta() instanceof AbstractDisplayMeta displayMeta) {
353368//// displayMeta.setTranslation(new Vector3f(0, 0.5f, 0));
@@ -358,12 +373,10 @@ private void createHologram() {
358373
359374 private void updateHologram () {
360375 if (hologram != null ) {
361- hologram .setLine (
362- 0 ,
363- options .getDisplayName () != null
364- ? options .getDisplayName ()
365- : Component .text (name )
366- );
376+ Component displayName = options .getDisplayName () != null
377+ ? options .getDisplayName ()
378+ : Component .text (name );
379+ hologram .setLines (splitDisplayNameLines (displayName ));
367380 }
368381 }
369382
0 commit comments