DREAMFIRE Docs ← Back to site
Loading...
Searching...
No Matches
DreamTextDisplay.java
Go to the documentation of this file.
1/*
2 * MIT License
3 *
4 * Copyright (c) 2025 Dreamfire Studio
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24package com.dreamfirestudios.dreamcore.DreamTextDisplay;
25
26import com.dreamfirestudios.dreamcore.DreamChat.DreamMessageFormatter;
27import com.dreamfirestudios.dreamcore.DreamChat.DreamMessageSettings;
28import org.bukkit.*;
29import org.bukkit.entity.Display;
30import org.bukkit.entity.TextDisplay;
31import org.jetbrains.annotations.NotNull;
32import org.jetbrains.annotations.Nullable;
33import org.joml.Vector3f;
34
46public final class DreamTextDisplay {
47
48 private DreamTextDisplay() {}
49
51 public static TextDisplayBuilder textDisplay() { return new TextDisplayBuilder(); }
52
55
56 public static final class TextDisplayBuilder {
57 // -------- defaults (safe fallbacks) --------
58 private World world = firstLoadedWorld();
59 private Location location = world.getSpawnLocation();
60
61 // Display transform/appearance
62 private double scale = 1.0D;
63 private Vector3f leftRotation = new Vector3f(0f, 0f, 0f);
64 private float viewRange = 0.1f; // 0.1 ~= 16 blocks
65 private float shadowRadius = 0.3f; // 1.0 ~= 1 block
66 private float shadowStrength = 5f; // >=5 looks very dark
67 private float displayWidth = 50f;
68 private float displayHeight = 50f;
69 private Display.Billboard billboard = Display.Billboard.CENTER;
70 private Color glowColor = Color.RED;
71 private Display.Brightness brightness = new Display.Brightness(15, 15); // force max block/sky
72
73 // Text styling
74 private Color backgroundColor = Color.RED;
75 private int lineWidth = 50;
76 private byte textOpacity = (byte) 0xFF; // 0..255
77
78 private static @NotNull World firstLoadedWorld() {
79 return Bukkit.getWorlds().isEmpty()
80 ? Bukkit.createWorld(new WorldCreator("world")) // last-resort create
81 : Bukkit.getWorlds().get(0);
82 }
83
84 // ---------------------------------------------------------------------
85 // Fluent configuration
86 // ---------------------------------------------------------------------
87
89 public TextDisplayBuilder world(@NotNull World world) {
90 this.world = java.util.Objects.requireNonNull(world, "world");
91 if (this.location == null || this.location.getWorld() == null) {
92 this.location = world.getSpawnLocation();
93 }
94 return this;
95 }
96
98 public TextDisplayBuilder location(@NotNull Location location) {
99 this.location = java.util.Objects.requireNonNull(location, "location");
100 if (this.location.getWorld() != null) {
101 this.world = this.location.getWorld();
102 }
103 return this;
104 }
105
107 public TextDisplayBuilder itemScale(double scale) {
108 if (scale <= 0) throw new IllegalArgumentException("Scale must be > 0");
109 this.scale = scale;
110 return this;
111 }
112
117 public TextDisplayBuilder leftRotation(@NotNull Vector3f leftRotation) {
118 this.leftRotation = java.util.Objects.requireNonNull(leftRotation, "leftRotation");
119 return this;
120 }
121
123 public TextDisplayBuilder viewRange(float viewRange) {
124 if (viewRange < 0f) throw new IllegalArgumentException("viewRange must be >= 0");
125 this.viewRange = viewRange;
126 return this;
127 }
128
130 public TextDisplayBuilder shadowRadius(float shadowRadius) {
131 if (shadowRadius < 0f) throw new IllegalArgumentException("shadowRadius must be >= 0");
132 this.shadowRadius = shadowRadius;
133 return this;
134 }
135
137 public TextDisplayBuilder shadowStrength(float shadowStrength) {
138 if (shadowStrength < 0f) throw new IllegalArgumentException("shadowStrength must be >= 0");
139 this.shadowStrength = shadowStrength;
140 return this;
141 }
142
143 public TextDisplayBuilder displayHeight(float displayHeight) {
144 if (displayHeight <= 0f) throw new IllegalArgumentException("displayHeight must be > 0");
145 this.displayHeight = displayHeight;
146 return this;
147 }
148
149 public TextDisplayBuilder displayWidth(float displayWidth) {
150 if (displayWidth <= 0f) throw new IllegalArgumentException("displayWidth must be > 0");
151 this.displayWidth = displayWidth;
152 return this;
153 }
154
155 public TextDisplayBuilder billboard(@NotNull Display.Billboard billboard) {
156 this.billboard = java.util.Objects.requireNonNull(billboard, "billboard");
157 return this;
158 }
159
160 public TextDisplayBuilder itemGlowColor(@NotNull Color glowColor) {
161 this.glowColor = java.util.Objects.requireNonNull(glowColor, "glowColor");
162 return this;
163 }
164
165 public TextDisplayBuilder backgroundColor(@NotNull Color backgroundColor) {
166 this.backgroundColor = java.util.Objects.requireNonNull(backgroundColor, "backgroundColor");
167 return this;
168 }
169
170 public TextDisplayBuilder lineWidth(int lineWidth) {
171 if (lineWidth < 0) throw new IllegalArgumentException("lineWidth must be >= 0");
172 this.lineWidth = lineWidth;
173 return this;
174 }
175
180 public TextDisplayBuilder itemBrightness(@NotNull Display.Brightness brightness) {
181 this.brightness = java.util.Objects.requireNonNull(brightness, "brightness");
182 return this;
183 }
184
186 public TextDisplayBuilder textOpacity(int opacity0to255) {
187 if (opacity0to255 < 0 || opacity0to255 > 255) {
188 throw new IllegalArgumentException("textOpacity must be in range 0..255");
189 }
190 this.textOpacity = (byte) (opacity0to255 & 0xFF);
191 return this;
192 }
193
194 // ---------------------------------------------------------------------
195 // Spawning
196 // ---------------------------------------------------------------------
197
204 public @NotNull TextDisplay spawn(@NotNull String text) {
205 java.util.Objects.requireNonNull(text, "text");
206 if (world == null) throw new IllegalStateException("World is null");
207 if (location == null || location.getWorld() == null) {
208 throw new IllegalStateException("Location/world must be set before spawning");
209 }
210
211 final TextDisplay td = world.spawn(location, TextDisplay.class);
212
213 // content
214 td.text(DreamMessageFormatter.format(text, DreamMessageSettings.all()));
215
216 // transform
217 var t = td.getTransformation();
218 t.getScale().set(scale);
219 // Fill quaternion components from provided vector (convenience approach)
220 t.getLeftRotation().x = leftRotation.x;
221 t.getLeftRotation().y = leftRotation.y;
222 t.getLeftRotation().z = leftRotation.z;
223 td.setTransformation(t);
224
225 // display params
226 td.setViewRange(viewRange);
227 td.setShadowRadius(shadowRadius); // fixed: radius setter
228 td.setShadowStrength(shadowStrength);
229 td.setDisplayHeight(displayHeight);
230 td.setDisplayWidth(displayWidth);
231 td.setBillboard(billboard);
232 td.setGlowColorOverride(glowColor);
233 td.setBrightness(brightness);
234 td.setBackgroundColor(backgroundColor);
235 td.setLineWidth(lineWidth);
236 td.setTextOpacity(textOpacity);
237
238 new TextDisplaySpawnEvent(td);
239 return td;
240 }
241 }
242}
TextDisplayBuilder location(@NotNull Location location)
Sets the spawn location (world taken from the location).
TextDisplayBuilder leftRotation(@NotNull Vector3f leftRotation)
Left-rotation convenience vector (mapped into the underlying quaternion's xyz components).
TextDisplay spawn(@NotNull String text)
Spawns a TextDisplay with the configured properties and the given MiniMessage text.
TextDisplayBuilder itemScale(double scale)
Uniform scale applied to the text display transform.
TextDisplayBuilder shadowStrength(float shadowStrength)
Shadow strength; higher = darker.
TextDisplayBuilder textOpacity(int opacity0to255)
Sets text opacity (0..255).
TextDisplayBuilder shadowRadius(float shadowRadius)
Shadow radius in blocks.
TextDisplayBuilder viewRange(float viewRange)
View range; 0.1 ~ 16 blocks.
TextDisplayBuilder itemBrightness(@NotNull Display.Brightness brightness)
Sets explicit brightness (block, sky).
TextDisplayBuilder world(@NotNull World world)
Sets the world where the display will be spawned.
Builder utility for spawning configured TextDisplay entities.
static TextDisplayBuilder textDisplay()
Preferred factory name.
static TextDisplayBuilder BlockDisplayBuilder()
Backward-compatible alias (was misnamed previously).
Event fired after a TextDisplay is spawned by DreamTextDisplay.