Skip to content

Commit d8b3014

Browse files
Add getDescription() to IStructureElement (#57)
1 parent 40edf05 commit d8b3014

4 files changed

Lines changed: 192 additions & 0 deletions

File tree

src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import java.util.Arrays;
77
import java.util.Collections;
8+
import java.util.List;
89
import java.util.function.Consumer;
910
import java.util.function.Predicate;
1011

@@ -42,6 +43,28 @@ default boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack tr
4243
return true;
4344
}
4445

46+
/**
47+
* Returns a human-readable description of what block(s) this element accepts. Used for diagnostic messages when
48+
* structure checks fail (e.g. "expected Input Bus at (1, 2, 3)").
49+
* <p>
50+
* Unlike {@link #getBlocksToPlace}, which returns the full set of concrete block variants for autoplacing (e.g.
51+
* every tier of Input Bus), this method returns <b>category-level</b> descriptions suitable for display to the
52+
* player (e.g. just "Input Bus"). It also requires no parameters, no world, trigger item, or environment, making it
53+
* usable in contexts where those are unavailable.
54+
* <p>
55+
* Implementations should return <b>lang keys</b> (e.g. {@code "tile.blockGlass.name"}) rather than pre-translated
56+
* display names. The caller is responsible for translating these keys on the client side via
57+
* {@code StatCollector.translateToLocal()}. If a key has no matching translation, {@code translateToLocal} returns
58+
* the input string unchanged, so pre-translated fallback strings also work.
59+
*
60+
* @return a list of accepted block descriptions as lang keys (or display names as fallback), or null if no
61+
* description is available
62+
*/
63+
@Nullable
64+
default List<String> getDescription() {
65+
return null;
66+
}
67+
4568
boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger);
4669

4770
boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger);
@@ -204,6 +227,12 @@ public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack tri
204227
public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
205228
return IStructureElement.this.spawnHint(t, world, x, y, z, trigger);
206229
}
230+
231+
@Nullable
232+
@Override
233+
public List<String> getDescription() {
234+
return IStructureElement.this.getDescription();
235+
}
207236
};
208237
}
209238

src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElementChain.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package com.gtnewhorizon.structurelib.structure;
22

33
import java.util.ArrayList;
4+
import java.util.LinkedHashSet;
45
import java.util.List;
6+
import java.util.Set;
57
import java.util.function.Consumer;
68
import java.util.function.Predicate;
79

@@ -61,6 +63,19 @@ default boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trig
6163
return false;
6264
}
6365

66+
@Nullable
67+
@Override
68+
default List<String> getDescription() {
69+
Set<String> descriptions = new LinkedHashSet<>();
70+
for (IStructureElement<T> fallback : fallbacks()) {
71+
List<String> desc = fallback.getDescription();
72+
if (desc != null) {
73+
descriptions.addAll(desc);
74+
}
75+
}
76+
return descriptions.isEmpty() ? null : new ArrayList<>(descriptions);
77+
}
78+
6479
@Nullable
6580
@Override
6681
default BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger,

src/main/java/com/gtnewhorizon/structurelib/structure/LazyStructureElement.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.gtnewhorizon.structurelib.structure;
22

3+
import java.util.List;
34
import java.util.function.Consumer;
45
import java.util.function.Function;
56

@@ -65,4 +66,10 @@ public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, Ite
6566
AutoPlaceEnvironment env) {
6667
return get(t).survivalPlaceBlock(t, world, x, y, z, trigger, env);
6768
}
69+
70+
@Nullable
71+
@Override
72+
public List<String> getDescription() {
73+
return elem != null ? elem.getDescription() : null;
74+
}
6875
}

src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,19 @@ public static <T, TIER> IStructureElementCheckOnly<T> ofBlocksTiered(ITierConver
707707
public static <T, TIER> IStructureElement<T> ofBlocksTiered(ITierConverter<TIER> tierExtractor,
708708
@Nullable List<Pair<Block, Integer>> allKnownTiers, @Nullable TIER notSet, BiConsumer<T, TIER> setter,
709709
Function<T, TIER> getter) {
710+
return ofBlocksTiered(tierExtractor, allKnownTiers, notSet, setter, getter, null);
711+
}
712+
713+
/**
714+
* Like {@link #ofBlocksTiered(ITierConverter, List, Object, BiConsumer, Function)}, but with an explicit
715+
* description that will be returned by {@link IStructureElement#getDescription()}.
716+
*
717+
* @param description the description lang keys to attach to this element, or null for no description
718+
* @see #ofBlocksTiered(ITierConverter, List, Object, BiConsumer, Function)
719+
*/
720+
public static <T, TIER> IStructureElement<T> ofBlocksTiered(ITierConverter<TIER> tierExtractor,
721+
@Nullable List<Pair<Block, Integer>> allKnownTiers, @Nullable TIER notSet, BiConsumer<T, TIER> setter,
722+
Function<T, TIER> getter, @Nullable List<String> description) {
710723
List<Pair<Block, Integer>> hints = allKnownTiers == null ? Collections.emptyList() : allKnownTiers;
711724
if (hints.stream().anyMatch(Objects::isNull)) throw new IllegalArgumentException();
712725
IStructureElementCheckOnly<T> check = ofBlocksTiered(tierExtractor, notSet, setter, getter);
@@ -785,6 +798,13 @@ public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, Ite
785798
env.getActor(),
786799
env.getChatter());
787800
}
801+
802+
@Nullable
803+
@Override
804+
public List<String> getDescription() {
805+
return description;
806+
}
807+
788808
};
789809
}
790810

@@ -1408,6 +1428,14 @@ public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, Ite
14081428
AutoPlaceEnvironment env) {
14091429
return BlocksToPlace.create(block, meta);
14101430
}
1431+
1432+
@Nullable
1433+
@Override
1434+
public List<String> getDescription() {
1435+
Item item = Item.getItemFromBlock(block);
1436+
if (item == null) return null;
1437+
return Collections.singletonList(new ItemStack(item, 1, meta).getUnlocalizedName() + ".name");
1438+
}
14111439
};
14121440
} else {
14131441
return new IStructureElement<T>() {
@@ -1487,6 +1515,14 @@ public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, Ite
14871515
AutoPlaceEnvironment env) {
14881516
return BlocksToPlace.create(block, meta);
14891517
}
1518+
1519+
@Nullable
1520+
@Override
1521+
public List<String> getDescription() {
1522+
Item item = Item.getItemFromBlock(block);
1523+
if (item == null) return null;
1524+
return Collections.singletonList(new ItemStack(item, 1, meta).getUnlocalizedName() + ".name");
1525+
}
14901526
};
14911527
}
14921528
}
@@ -1529,6 +1565,14 @@ public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, Ite
15291565
// there is getSubItems on ItemBlock, but it's client only
15301566
return BlocksToPlace.create(defaultBlock, defaultMeta);
15311567
}
1568+
1569+
@Nullable
1570+
@Override
1571+
public List<String> getDescription() {
1572+
Item item = Item.getItemFromBlock(block);
1573+
if (item == null) return null;
1574+
return Collections.singletonList(new ItemStack(item, 1, 0).getUnlocalizedName() + ".name");
1575+
}
15321576
};
15331577
} else {
15341578
return new IStructureElement<T>() {
@@ -1561,6 +1605,14 @@ public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, Ite
15611605
// there is getSubItems on ItemBlock, but it's client only
15621606
return BlocksToPlace.create(defaultBlock, defaultMeta);
15631607
}
1608+
1609+
@Nullable
1610+
@Override
1611+
public List<String> getDescription() {
1612+
Item item = Item.getItemFromBlock(block);
1613+
if (item == null) return null;
1614+
return Collections.singletonList(new ItemStack(item, 1, 0).getUnlocalizedName() + ".name");
1615+
}
15641616
};
15651617
}
15661618
}
@@ -1824,6 +1876,71 @@ public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, Ite
18241876
AutoPlaceEnvironment env) {
18251877
return element.survivalPlaceBlock(t, world, x, y, z, trigger, env);
18261878
}
1879+
1880+
@Nullable
1881+
@Override
1882+
public List<String> getDescription() {
1883+
return element.getDescription();
1884+
}
1885+
};
1886+
}
1887+
1888+
/**
1889+
* Wraps an element and overrides its description. Useful for providing human-readable names to elements whose
1890+
* underlying implementation doesn't provide a description (e.g. tiered block elements).
1891+
*
1892+
* @param description the description to use, or null to clear any existing description
1893+
* @param element the element to wrap
1894+
*/
1895+
public static <B extends IStructureElement<T>, T> IStructureElement<T> withDescription(
1896+
@Nullable List<String> description, B element) {
1897+
return new IStructureElement<T>() {
1898+
1899+
@Override
1900+
public boolean check(T t, World world, int x, int y, int z) {
1901+
return element.check(t, world, x, y, z);
1902+
}
1903+
1904+
@Override
1905+
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
1906+
return element.couldBeValid(t, world, x, y, z, trigger);
1907+
}
1908+
1909+
@Override
1910+
public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
1911+
return element.placeBlock(t, world, x, y, z, trigger);
1912+
}
1913+
1914+
@Override
1915+
public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
1916+
return element.spawnHint(t, world, x, y, z, trigger);
1917+
}
1918+
1919+
@Nullable
1920+
@Override
1921+
public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger,
1922+
AutoPlaceEnvironment env) {
1923+
return element.getBlocksToPlace(t, world, x, y, z, trigger, env);
1924+
}
1925+
1926+
@Override
1927+
@Deprecated
1928+
public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger,
1929+
IItemSource s, EntityPlayerMP actor, Consumer<IChatComponent> chatter) {
1930+
return element.survivalPlaceBlock(t, world, x, y, z, trigger, s, actor, chatter);
1931+
}
1932+
1933+
@Override
1934+
public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger,
1935+
AutoPlaceEnvironment env) {
1936+
return element.survivalPlaceBlock(t, world, x, y, z, trigger, env);
1937+
}
1938+
1939+
@Nullable
1940+
@Override
1941+
public List<String> getDescription() {
1942+
return description;
1943+
}
18271944
};
18281945
}
18291946

@@ -1880,6 +1997,12 @@ public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, Ite
18801997
AutoPlaceEnvironment env) {
18811998
return element.survivalPlaceBlock(t, world, x, y, z, trigger, env);
18821999
}
2000+
2001+
@Nullable
2002+
@Override
2003+
public List<String> getDescription() {
2004+
return element.getDescription();
2005+
}
18832006
};
18842007
}
18852008

@@ -1949,6 +2072,12 @@ public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, Ite
19492072
if (predicate.test(t)) return downstream.survivalPlaceBlock(t, world, x, y, z, trigger, env);
19502073
return placeResultWhenDisabled;
19512074
}
2075+
2076+
@Nullable
2077+
@Override
2078+
public List<String> getDescription() {
2079+
return downstream.getDescription();
2080+
}
19522081
};
19532082
}
19542083

@@ -2046,6 +2175,12 @@ public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, Ite
20462175
AutoPlaceEnvironment env) {
20472176
return elem.survivalPlaceBlock(t.getCurrentContext(), world, x, y, z, trigger, env);
20482177
}
2178+
2179+
@Nullable
2180+
@Override
2181+
public List<String> getDescription() {
2182+
return elem.getDescription();
2183+
}
20492184
};
20502185
}
20512186
// endregion
@@ -2883,6 +3018,12 @@ public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, Ite
28833018
warnNoExplicitSubChannel(env.getActor());
28843019
return backing.survivalPlaceBlock(t, world, x, y, z, newTrigger, env);
28853020
}
3021+
3022+
@Nullable
3023+
@Override
3024+
public List<String> getDescription() {
3025+
return backing.getDescription();
3026+
}
28863027
};
28873028
}
28883029
// endregion

0 commit comments

Comments
 (0)