Skip to content

Commit 969618d

Browse files
committed
Added blockstate command suggested here: #43
1 parent 5bc0239 commit 969618d

File tree

8 files changed

+222
-7
lines changed

8 files changed

+222
-7
lines changed

plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/data/BlockHologramData.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public class BlockHologramData extends DisplayHologramData {
1313
public static Material DEFAULT_BLOCK = Material.GRASS_BLOCK;
1414

1515
private Material block = DEFAULT_BLOCK;
16+
private String blockState = null;
1617

1718
/**
1819
* @param name Name of hologram
@@ -36,11 +37,25 @@ public BlockHologramData setBlock(Material block) {
3637
return this;
3738
}
3839

40+
public String getBlockState() {
41+
return blockState;
42+
}
43+
44+
public BlockHologramData setBlockState(String blockState) {
45+
if (!Objects.equals(this.blockState, blockState)) {
46+
this.blockState = blockState;
47+
setHasChanges(true);
48+
}
49+
50+
return this;
51+
}
52+
3953
@Override
4054
@ApiStatus.Internal
4155
public boolean read(ConfigurationSection section, String name) {
4256
super.read(section, name);
4357
block = Material.getMaterial(section.getString("block", "GRASS_BLOCK").toUpperCase());
58+
blockState = section.getString("block_state", null);
4459

4560
return true;
4661
}
@@ -50,6 +65,7 @@ public boolean read(ConfigurationSection section, String name) {
5065
public boolean write(ConfigurationSection section, String name) {
5166
super.write(section, name);
5267
section.set("block", block.name());
68+
section.set("block_state", blockState);
5369

5470
return true;
5571
}
@@ -59,6 +75,7 @@ public BlockHologramData copy(String name) {
5975
BlockHologramData blockHologramData = new BlockHologramData(name, getLocation());
6076
blockHologramData
6177
.setBlock(this.getBlock())
78+
.setBlockState(this.getBlockState())
6279
.setScale(this.getScale())
6380
.setShadowRadius(this.getShadowRadius())
6481
.setShadowStrength(this.getShadowStrength())

plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/events/HologramUpdateEvent.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ public enum HologramModification {
8585
UPDATE_TEXT_INTERVAL,
8686
UPDATE_VISIBILITY_DISTANCE,
8787
GLOWING,
88-
GLOWING_COLOR;
88+
GLOWING_COLOR,
89+
BLOCK,
90+
BLOCK_STATE;
8991
}
9092

9193
}

plugins/fancyholograms/fh-api/src/main/java/com/fancyinnovations/fancyholograms/api/hologram/HologramType.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
public enum HologramType {
77
TEXT(Arrays.asList("background", "textshadow", "textalignment", "opacity", "seethrough", "setline", "removeline", "addline", "insertbefore", "insertafter", "updatetextinterval")),
88
ITEM(List.of("item")),
9-
BLOCK(List.of("block"));
9+
BLOCK(Arrays.asList("block", "blockstate"));
1010

1111
private final List<String> commands;
1212

plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/HologramCMD.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public final class HologramCMD extends Command {
5555
<%primary_color%>- /hologram edit <hologram> shadowStrength <value> <dark_gray>- <white>Changes the shadow strength of the hologram
5656
<%primary_color%>- /hologram edit <hologram> brightness <block|sky> <0-15> <dark_gray>- <white>Changes the brightness of the hologram
5757
<%primary_color%>- /hologram edit <hologram> updateTextInterval <seconds> <dark_gray>- <white>Sets the interval for updating the text
58+
<%primary_color%>- /hologram edit <hologram> blockState <property> <value> <dark_gray>- <white>Changes the block state (e.g., "facing north" for block holograms)
5859
<%primary_color%>- /hologram edit <hologram> traits <add|remove> <trait name> <dark_gray>- <white>Adds or removes a trait to the hologram
5960
""".replace("%primary_color%", MessageHelper.getPrimaryColor());
6061

@@ -382,6 +383,7 @@ private boolean edit(@NotNull final CommandSender player, @NotNull final Hologra
382383

383384
// block data
384385
case "block" -> new BlockCMD().run(player, hologram, args);
386+
case "blockstate" -> new BlockStateCMD().run(player, hologram, args);
385387

386388
default -> false;
387389
};
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
package com.fancyinnovations.fancyholograms.commands.hologram;
2+
3+
import com.fancyinnovations.fancyholograms.api.data.BlockHologramData;
4+
import com.fancyinnovations.fancyholograms.api.events.HologramUpdateEvent;
5+
import com.fancyinnovations.fancyholograms.api.hologram.Hologram;
6+
import com.fancyinnovations.fancyholograms.commands.HologramCMD;
7+
import com.fancyinnovations.fancyholograms.commands.Subcommand;
8+
import com.fancyinnovations.fancyholograms.main.FancyHologramsPlugin;
9+
import de.oliver.fancylib.MessageHelper;
10+
import org.bukkit.Bukkit;
11+
import org.bukkit.block.data.BlockData;
12+
import org.bukkit.command.CommandSender;
13+
import org.jetbrains.annotations.NotNull;
14+
import org.jetbrains.annotations.Nullable;
15+
16+
import java.util.*;
17+
import java.util.stream.Collectors;
18+
19+
public class BlockStateCMD implements Subcommand {
20+
21+
@Override
22+
public List<String> tabcompletion(@NotNull CommandSender player, @Nullable Hologram hologram, @NotNull String[] args) {
23+
if (hologram == null || !(hologram.getData() instanceof BlockHologramData blockData)) {
24+
return Collections.emptyList();
25+
}
26+
27+
try {
28+
BlockData defaultBlockData = blockData.getBlock().createBlockData();
29+
30+
if (args.length == 4) {
31+
return Arrays.stream(defaultBlockData.getAsString(true)
32+
.replaceAll("^[^\\[]*\\[", "")
33+
.replaceAll("\\]$", "")
34+
.split(","))
35+
.map(s -> s.split("=")[0])
36+
.filter(prop -> prop.toLowerCase().startsWith(args[3].toLowerCase()))
37+
.collect(Collectors.toList());
38+
} else if (args.length == 5) {
39+
String propertyName = args[3];
40+
String currentState = defaultBlockData.getAsString(true);
41+
42+
for (String prop : currentState.replaceAll("^[^\\[]*\\[", "").replaceAll("\\]$", "").split(",")) {
43+
String[] parts = prop.split("=");
44+
if (parts[0].equals(propertyName)) {
45+
List<String> possibleValues = new ArrayList<>();
46+
47+
possibleValues.add("true");
48+
possibleValues.add("false");
49+
50+
possibleValues.addAll(Arrays.asList("north", "south", "east", "west", "up", "down"));
51+
52+
for (int i = 0; i <= 15; i++) {
53+
possibleValues.add(String.valueOf(i));
54+
}
55+
56+
return possibleValues.stream()
57+
.filter(val -> {
58+
try {
59+
Bukkit.createBlockData(blockData.getBlock(), propertyName + "=" + val);
60+
return true;
61+
} catch (IllegalArgumentException e) {
62+
return false;
63+
}
64+
})
65+
.filter(val -> val.toLowerCase().startsWith(args[4].toLowerCase()))
66+
.collect(Collectors.toList());
67+
}
68+
}
69+
}
70+
} catch (Exception e) {
71+
return Collections.emptyList();
72+
}
73+
74+
return Collections.emptyList();
75+
}
76+
77+
@Override
78+
public boolean run(@NotNull CommandSender player, @Nullable Hologram hologram, @NotNull String[] args) {
79+
80+
if (!(player.hasPermission("fancyholograms.hologram.edit.block_state"))) {
81+
MessageHelper.error(player, "You don't have the required permission to change the block state of this hologram");
82+
return false;
83+
}
84+
85+
if (!(hologram.getData() instanceof BlockHologramData blockData)) {
86+
MessageHelper.error(player, "This command can only be used on block holograms");
87+
return false;
88+
}
89+
90+
// If no additional args, clear the block state
91+
if (args.length < 4) {
92+
final var copied = blockData.copy(blockData.getName());
93+
copied.setBlockState(null);
94+
95+
if (!HologramCMD.callModificationEvent(hologram, player, copied, HologramUpdateEvent.HologramModification.BLOCK_STATE)) {
96+
return false;
97+
}
98+
99+
blockData.setBlockState(null);
100+
101+
if (FancyHologramsPlugin.get().getHologramConfiguration().isSaveOnChangedEnabled()) {
102+
FancyHologramsPlugin.get().getStorage().save(hologram.getData());
103+
}
104+
105+
MessageHelper.success(player, "Cleared block state (using default)");
106+
return true;
107+
}
108+
109+
// Parse property=value pairs from args
110+
// Format: /hologram edit <name> blockstate <property> <value> [property] [value] ...
111+
112+
// Start with existing properties or create default
113+
Map<String, String> existingProperties = new HashMap<>();
114+
115+
// Parse existing block state if present
116+
if (blockData.getBlockState() != null && !blockData.getBlockState().isEmpty()) {
117+
String[] props = blockData.getBlockState().split(",");
118+
for (String prop : props) {
119+
String[] parts = prop.split("=", 2);
120+
if (parts.length == 2) {
121+
existingProperties.put(parts[0].trim(), parts[1].trim());
122+
}
123+
}
124+
}
125+
126+
// Apply the new properties (overwriting existing ones)
127+
for (int i = 3; i < args.length; i += 2) {
128+
if (i + 1 >= args.length) {
129+
MessageHelper.error(player, "Missing value for property: " + args[i]);
130+
return false;
131+
}
132+
133+
String property = args[i];
134+
String value = args[i + 1];
135+
existingProperties.put(property, value);
136+
}
137+
138+
// Build the block state string with brackets format
139+
String blockStateString = existingProperties.entrySet().stream()
140+
.sorted(Map.Entry.comparingByKey()) // Sort for consistency
141+
.map(e -> e.getKey() + "=" + e.getValue())
142+
.collect(Collectors.joining(","));
143+
144+
// Validate the block state by creating block data with full string format
145+
try {
146+
String fullBlockString = blockData.getBlock().getKey().toString() + "[" + blockStateString + "]";
147+
Bukkit.createBlockData(fullBlockString);
148+
} catch (IllegalArgumentException e) {
149+
MessageHelper.error(player, "Invalid block state: " + e.getMessage());
150+
return false;
151+
}
152+
153+
if (java.util.Objects.equals(blockStateString, blockData.getBlockState())) {
154+
MessageHelper.warning(player, "This block state is already set");
155+
return false;
156+
}
157+
158+
final var copied = blockData.copy(blockData.getName());
159+
copied.setBlockState(blockStateString);
160+
161+
if (!HologramCMD.callModificationEvent(hologram, player, copied, HologramUpdateEvent.HologramModification.BLOCK_STATE)) {
162+
return false;
163+
}
164+
165+
if (java.util.Objects.equals(blockStateString, blockData.getBlockState())) {
166+
MessageHelper.warning(player, "This block state is already set");
167+
return false;
168+
}
169+
170+
blockData.setBlockState(blockStateString);
171+
172+
if (FancyHologramsPlugin.get().getHologramConfiguration().isSaveOnChangedEnabled()) {
173+
FancyHologramsPlugin.get().getStorage().save(hologram.getData());
174+
}
175+
176+
MessageHelper.success(player, "Set block state: " + blockStateString);
177+
178+
return true;
179+
}
180+
}

plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/hologram/HologramImpl.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,20 @@ private void syncWithData() {
166166
itemDisplay.setItem(itemData.getItemStack());
167167
} else if (fsDisplay instanceof FS_BlockDisplay blockDisplay && data instanceof com.fancyinnovations.fancyholograms.api.data.BlockHologramData blockData) {
168168
// block
169-
170-
// BlockType blockType = RegistryAccess.registryAccess().getRegistry(RegistryKey.BLOCK).get(blockData.getBlock().getKey());
171-
blockDisplay.setBlock(blockData.getBlock().createBlockData().createBlockState());
169+
try {
170+
// If blockState is set, use it; otherwise use default
171+
if (blockData.getBlockState() != null && !blockData.getBlockState().isEmpty()) {
172+
// Create block data using full format: namespace:block[properties]
173+
String fullBlockString = blockData.getBlock().getKey().toString() + "[" + blockData.getBlockState() + "]";
174+
blockDisplay.setBlock(org.bukkit.Bukkit.createBlockData(fullBlockString).createBlockState());
175+
} else {
176+
blockDisplay.setBlock(blockData.getBlock().createBlockData().createBlockState());
177+
}
178+
} catch (IllegalArgumentException e) {
179+
// If block state is invalid, fall back to default
180+
FancyHolograms.get().getFancyLogger().warn("Invalid block state for hologram " + blockData.getName() + ": " + e.getMessage());
181+
blockDisplay.setBlock(blockData.getBlock().createBlockData().createBlockState());
182+
}
172183
}
173184

174185
if (data instanceof com.fancyinnovations.fancyholograms.api.data.DisplayHologramData displayData) {

plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/storage/json/JsonAdapter.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ public static JsonTextHologramData textHologramDataToJson(com.fancyinnovations.f
8181

8282
public static JsonBlockHologramData blockHologramDataToJson(com.fancyinnovations.fancyholograms.api.data.BlockHologramData data) {
8383
return new JsonBlockHologramData(
84-
data.getBlock().name()
84+
data.getBlock().name(),
85+
data.getBlockState()
8586
);
8687
}
8788

@@ -213,6 +214,7 @@ public static com.fancyinnovations.fancyholograms.api.data.HologramData fromJson
213214
case BLOCK ->
214215
new com.fancyinnovations.fancyholograms.api.data.BlockHologramData(data.hologram_data().name(), loc)
215216
.setBlock(Material.getMaterial(data.block_data().block_material())) // block data
217+
.setBlockState(data.block_data().block_state())
216218
.setBillboard(data.display_data().billboard()) // display data
217219
.setScale(scale)
218220
.setTranslation(translation)
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.fancyinnovations.fancyholograms.storage.json.model;
22

33
public record JsonBlockHologramData(
4-
String block_material
4+
String block_material,
5+
String block_state
56
) {
67
}

0 commit comments

Comments
 (0)