DREAMFIRE Docs ← Back to site
Loading...
Searching...
No Matches
DreamItemDisplay.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.DreamItemDisplay;
25
26import org.bukkit.Bukkit;
27import org.bukkit.Color;
28import org.bukkit.Location;
29import org.bukkit.Material;
30import org.bukkit.World;
31import org.bukkit.entity.Display;
32import org.bukkit.entity.ItemDisplay;
33import org.bukkit.inventory.ItemStack;
34import org.bukkit.util.Transformation;
35import org.joml.Quaternionf;
36import org.joml.Vector3f;
37
62public final class DreamItemDisplay {
63
64 private DreamItemDisplay() {}
65
73 public static class ItemDisplayBuilder {
74 // -------------------- Defaults --------------------
75 private World world = Bukkit.getWorlds().isEmpty() ? null : Bukkit.getWorlds().get(0);
76 private Location location = (world == null) ? null : world.getSpawnLocation();
77
78 private float uniformScale = 1.0f;
79 private Vector3f scale = null; // if non-null, overrides uniformScale
80 private Quaternionf leftRotation = new Quaternionf(); // identity
81 private Quaternionf rightRotation = new Quaternionf();// identity
82 private Vector3f translation = new Vector3f(0f, 0f, 0f);
83
84 // Display properties
86 private float viewRange = 16.0f;
87
89 private float shadowRadius = 0.3f;
90
92 private float shadowStrength = 0.5f;
93
95 private float displayWidth = 1f;
96
98 private float displayHeight = 1f;
99
100 private Display.Billboard billboard = Display.Billboard.CENTER;
101 private Color itemGlowColor = null; // null = no override
102 private Display.Brightness itemBrightness = null; // null = default brightness
103
104 // -------------------- World / position --------------------
105
115 public ItemDisplayBuilder world(World world) {
116 if (world == null) throw new IllegalArgumentException("World cannot be null");
117 this.world = world;
118 if (this.location == null) this.location = world.getSpawnLocation();
119 return this;
120 }
121
132 public ItemDisplayBuilder location(Location location) {
133 if (location == null) throw new IllegalArgumentException("Location cannot be null");
134 this.location = location;
135 if (location.getWorld() != null) this.world = location.getWorld();
136 return this;
137 }
138
148 public ItemDisplayBuilder translation(Vector3f translation) {
149 if (translation == null) throw new IllegalArgumentException("translation cannot be null");
150 this.translation = new Vector3f(translation);
151 return this;
152 }
153
154 // -------------------- Scale --------------------
155
165 public ItemDisplayBuilder scale(float uniform) {
166 if (uniform <= 0f) throw new IllegalArgumentException("Scale must be > 0");
167 this.uniformScale = uniform;
168 this.scale = null;
169 return this;
170 }
171
181 public ItemDisplayBuilder scale(Vector3f scale) {
182 if (scale == null) throw new IllegalArgumentException("scale cannot be null");
183 if (scale.x <= 0f || scale.y <= 0f || scale.z <= 0f)
184 throw new IllegalArgumentException("scale components must be > 0");
185 this.scale = new Vector3f(scale);
186 return this;
187 }
188
189 // -------------------- Rotation --------------------
190
201 public ItemDisplayBuilder leftRotation(Quaternionf q) {
202 if (q == null) throw new IllegalArgumentException("leftRotation cannot be null");
203 this.leftRotation = new Quaternionf(q);
204 return this;
205 }
206
216 public ItemDisplayBuilder rightRotation(Quaternionf q) {
217 if (q == null) throw new IllegalArgumentException("rightRotation cannot be null");
218 this.rightRotation = new Quaternionf(q);
219 return this;
220 }
221
235 public ItemDisplayBuilder eulerDegrees(float yawDeg, float pitchDeg, float rollDeg) {
236 final float yaw = (float) Math.toRadians(yawDeg);
237 final float pitch = (float) Math.toRadians(pitchDeg);
238 final float roll = (float) Math.toRadians(rollDeg);
239
240 this.leftRotation = new Quaternionf()
241 .rotateZ(yaw)
242 .rotateX(pitch)
243 .rotateY(roll);
244 return this;
245 }
246
247 // -------------------- Display props --------------------
248
258 public ItemDisplayBuilder viewRange(float viewRange) {
259 if (viewRange < 0f) throw new IllegalArgumentException("viewRange must be >= 0");
260 this.viewRange = viewRange;
261 return this;
262 }
263
270 public ItemDisplayBuilder shadowRadius(float shadowRadius) {
271 if (shadowRadius < 0f) throw new IllegalArgumentException("shadowRadius must be >= 0");
272 this.shadowRadius = shadowRadius;
273 return this;
274 }
275
281 public ItemDisplayBuilder shadowStrength(float shadowStrength) {
282 this.shadowStrength = shadowStrength;
283 return this;
284 }
285
292 public ItemDisplayBuilder displayHeight(float displayHeight) {
293 if (displayHeight <= 0f) throw new IllegalArgumentException("displayHeight must be > 0");
294 this.displayHeight = displayHeight;
295 return this;
296 }
297
304 public ItemDisplayBuilder displayWidth(float displayWidth) {
305 if (displayWidth <= 0f) throw new IllegalArgumentException("displayWidth must be > 0");
306 this.displayWidth = displayWidth;
307 return this;
308 }
309
318 public ItemDisplayBuilder billboard(Display.Billboard billboard) {
319 this.billboard = (billboard == null) ? Display.Billboard.CENTER : billboard;
320 return this;
321 }
322
328 public ItemDisplayBuilder glowColor(Color color) {
329 this.itemGlowColor = color; // null clears
330 return this;
331 }
332
338 public ItemDisplayBuilder brightness(Display.Brightness brightness) {
339 this.itemBrightness = brightness; // null = default
340 return this;
341 }
342
343 // -------------------- Spawn --------------------
344
360 public ItemDisplay spawn(ItemStack itemStack) {
361 if (itemStack == null || itemStack.getType() == Material.AIR)
362 throw new IllegalArgumentException("ItemStack cannot be null or AIR");
363 if (world == null)
364 throw new IllegalStateException("No world available to spawn ItemDisplay");
365 if (location == null)
366 location = world.getSpawnLocation();
367
368 final ItemDisplay display = world.spawn(location, ItemDisplay.class);
369 display.setItemStack(itemStack);
370
371 // Apply transformation
372 final Vector3f sc = (scale != null) ? new Vector3f(scale) : new Vector3f(uniformScale);
373 final Transformation tf = new Transformation(
374 new Vector3f(translation),
375 new Quaternionf(leftRotation),
376 sc,
377 new Quaternionf(rightRotation)
378 );
379 display.setTransformation(tf);
380
381 // Clamp & apply display properties
382 display.setViewRange(Math.max(0f, viewRange));
383 display.setShadowRadius(Math.max(0f, shadowRadius));
384 display.setShadowStrength(Math.max(0f, Math.min(1f, shadowStrength)));
385 display.setDisplayWidth(Math.max(0.0001f, displayWidth));
386 display.setDisplayHeight(Math.max(0.0001f, displayHeight));
387 display.setBillboard(billboard);
388
389 if (itemGlowColor != null) display.setGlowColorOverride(itemGlowColor);
390 if (itemBrightness != null) display.setBrightness(itemBrightness);
391
392 new ItemDisplaySpawnEvent(display);
393 return display;
394 }
395 }
396}
ItemDisplayBuilder rightRotation(Quaternionf q)
Sets the right rotation quaternion.
ItemDisplayBuilder billboard(Display.Billboard billboard)
Sets the billboard mode for the display.
ItemDisplayBuilder shadowRadius(float shadowRadius)
Sets the display's shadow radius.
ItemDisplayBuilder world(World world)
Sets the world where the display will be spawned.
ItemDisplayBuilder displayWidth(float displayWidth)
Sets the display width (world units).
ItemDisplayBuilder displayHeight(float displayHeight)
Sets the display height (world units).
ItemDisplayBuilder brightness(Display.Brightness brightness)
Sets the display brightness override (or clears if null).
ItemDisplayBuilder scale(Vector3f scale)
Sets a non-uniform scale vector.
ItemDisplayBuilder glowColor(Color color)
Sets the glow color override (or clears it if null).
ItemDisplay spawn(ItemStack itemStack)
Spawns the ItemDisplay with the configured properties.
ItemDisplayBuilder shadowStrength(float shadowStrength)
Sets the display's shadow strength.
ItemDisplayBuilder leftRotation(Quaternionf q)
Sets the left rotation quaternion.
ItemDisplayBuilder viewRange(float viewRange)
Sets the render distance in blocks (>= 0).
ItemDisplayBuilder scale(float uniform)
Sets a uniform scale (x=y=z).
ItemDisplayBuilder translation(Vector3f translation)
Applies a local translation (pre-rotation) in the display's local space.
ItemDisplayBuilder eulerDegrees(float yawDeg, float pitchDeg, float rollDeg)
Convenience method to set the left rotation using Euler angles in degrees.
ItemDisplayBuilder location(Location location)
Sets the spawn location (must be in the same world as world(World)).
Fluent builder utilities for spawning configured ItemDisplay entities.
Event fired immediately after an ItemDisplay is spawned and configured by DreamItemDisplay....