Skip to content

Commit 1533423

Browse files
xpplecev-api
authored andcommitted
Display different textures based on structure variants (xpple#106)
* Display different textures based on structure variants * Fix stupid bug * Only calculate necessary variant info * Cache variant computations
1 parent ab73d3b commit 1533423

File tree

10 files changed

+212
-122
lines changed

10 files changed

+212
-122
lines changed

src/main/java/dev/xpple/seedmapper/SeedMapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public class SeedMapper implements ClientModInitializer {
6262
public void onInitializeClient() {
6363
new ModConfigBuilder<>(MOD_ID, Configs.class)
6464
.registerType(SeedResolutionArgument.SeedResolution.class, new SeedResolutionAdapter(), SeedResolutionArgument::seedResolution)
65-
.registerType(MapFeature.class, new MapFeatureAdapter(), MapFeatureArgument::mapFeature)
65+
.registerTypeHierarchy(MapFeature.class, new MapFeatureAdapter(), MapFeatureArgument::mapFeature)
6666
.registerGlobalChangeHook(event -> {
6767
if (event.config().equals("DevMode")) {
6868
try {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package dev.xpple.seedmapper.seedmap;
2+
3+
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
4+
import net.minecraft.world.level.ChunkPos;
5+
6+
public record ChunkStructureData(ChunkPos pos, Int2ObjectMap<StructureData> structures) {
7+
}

src/main/java/dev/xpple/seedmapper/seedmap/FeatureToggleWidget.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public class FeatureToggleWidget extends Button {
1111
private final MapFeature feature;
1212

1313
public FeatureToggleWidget(MapFeature feature, int x, int y) {
14-
super(x, y, feature.getTexture().width(), feature.getTexture().height(), feature.getDisplayName(), FeatureToggleWidget::onButtonPress, DEFAULT_NARRATION);
14+
super(x, y, feature.getDefaultTexture().width(), feature.getDefaultTexture().height(), Component.literal(feature.getName()), FeatureToggleWidget::onButtonPress, DEFAULT_NARRATION);
1515
this.feature = feature;
1616
}
1717

@@ -21,7 +21,7 @@ protected void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, flo
2121
if (!Configs.ToggledFeatures.contains(this.feature)) {
2222
colour = ARGB.color(255 >> 1, 255, 255, 255);
2323
}
24-
SeedMapScreen.FeatureWidget.drawFeatureIcon(guiGraphics, this.feature.getTexture(), this.getX(), this.getY(), colour);
24+
SeedMapScreen.FeatureWidget.drawFeatureIcon(guiGraphics, this.feature.getDefaultTexture(), this.getX(), this.getY(), colour);
2525
}
2626

2727
public Component getTooltip() {

src/main/java/dev/xpple/seedmapper/seedmap/MapFeature.java

Lines changed: 103 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,111 @@
11
package dev.xpple.seedmapper.seedmap;
22

33
import com.github.cubiomes.Cubiomes;
4+
import com.github.cubiomes.Piece;
5+
import com.github.cubiomes.StructureVariant;
46
import dev.xpple.seedmapper.SeedMapper;
5-
import net.minecraft.network.chat.Component;
7+
import dev.xpple.seedmapper.feature.StructureChecks;
8+
import dev.xpple.seedmapper.util.WorldIdentifier;
69
import net.minecraft.resources.ResourceLocation;
710

11+
import java.lang.foreign.Arena;
12+
import java.lang.foreign.MemorySegment;
813
import java.util.Arrays;
914
import java.util.Map;
1015
import java.util.stream.Collectors;
16+
import java.util.stream.IntStream;
1117

1218
public enum MapFeature {
13-
DESERT_PYRAMID("desert_pyramid", Cubiomes.Desert_Pyramid(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_3(), "Desert Pyramid", "cubiomes_viewer_icons", 19, 20),
14-
JUNGLE_PYRAMID("jungle_pyramid", Cubiomes.Jungle_Pyramid(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_3(), "Jungle Pyramid", "cubiomes_viewer_icons", 19, 20),
15-
SWAMP_HUT("swamp_hut", Cubiomes.Swamp_Hut(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_4(), "Swamp Hut", "cubiomes_viewer_icons", 20, 20),
16-
STRONGHOLD("stronghold", -1, Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_B1_8(), "Stronghold", "cubiomes_viewer_icons", 19, 20),
17-
IGLOO("igloo", Cubiomes.Igloo(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_9(), "Igloo", "cubiomes_viewer_icons", 20, 20),
18-
VILLAGE("village", Cubiomes.Village(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_B1_8(), "Village", "cubiomes_viewer_icons", 19, 20),
19-
OCEAN_RUIN("ocean_ruin", Cubiomes.Ocean_Ruin(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_13(), "Ocean Ruin", "cubiomes_viewer_icons", 19, 19),
20-
SHIPWRECK("shipwreck", Cubiomes.Shipwreck(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_13(), "Shipwreck", "cubiomes_viewer_icons", 19, 19),
21-
MONUMENT("monument", Cubiomes.Monument(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_8(), "Ocean Monument", "cubiomes_viewer_icons", 20, 20),
22-
MANSION("mansion", Cubiomes.Mansion(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_11(), "Woodland Mansion", "cubiomes_viewer_icons", 20, 20),
23-
OUTPOST("pillager_outpost", Cubiomes.Outpost(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_14(), "Pillager Outpost", "cubiomes_viewer_icons", 19, 20),
24-
RUINED_PORTAL("ruined_portal", Cubiomes.Ruined_Portal(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_16_1(), "Ruined Portal", "cubiomes_viewer_icons", 20, 20),
25-
RUINED_PORTAL_N("ruined_portal_n", Cubiomes.Ruined_Portal_N(), Cubiomes.DIM_NETHER(), Cubiomes.MC_1_16_1(), "Ruined Portal (Nether)", "cubiomes_viewer_icons", 20, 20),
26-
ANCIENT_CITY("ancient_city", Cubiomes.Ancient_City(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_19_2(), "Ancient City", "cubiomes_viewer_icons", 20, 20),
27-
TREASURE("buried_treasure", Cubiomes.Treasure(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_13(), "Buried Treasure", "cubiomes_viewer_icons", 19, 19),
28-
MINESHAFT("mineshaft", Cubiomes.Mineshaft(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_B1_8(), "Mineshaft", "cubiomes_viewer_icons", 20, 19),
29-
DESERT_WELL("desert_well", Cubiomes.Desert_Well(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_13(), "Desert Well", "cubiomes_viewer_icons", 20, 20),
30-
GEODE("geode", Cubiomes.Geode(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_17(), "Geode", "cubiomes_viewer_icons", 20, 20),
31-
COPPER_ORE_VEIN("copper_ore_vein", -1, Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_18(), "Copper Ore Vein", "feature_icons", 20, 20),
32-
IRON_ORE_VEIN("iron_ore_vein", -1, Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_18(), "Iron Ore Vein", "feature_icons", 20, 20),
33-
CANYON("canyon", -1, Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_13(), "Canyon", "feature_icons", 20, 20),
34-
FORTRESS("fortress", Cubiomes.Fortress(), Cubiomes.DIM_NETHER(), Cubiomes.MC_1_0(), "Nether Fortress", "cubiomes_viewer_icons", 20, 20),
35-
BASTION("bastion_remnant", Cubiomes.Bastion(), Cubiomes.DIM_NETHER(), Cubiomes.MC_1_16_1(), "Bastion Remnant", "cubiomes_viewer_icons", 20, 20),
36-
END_CITY("end_city", Cubiomes.End_City(), Cubiomes.DIM_END(), Cubiomes.MC_1_9(), "End City", "cubiomes_viewer_icons", 20, 20),
37-
END_CITY_SHIP("end_city_ship", Cubiomes.End_City(), Cubiomes.DIM_END(), Cubiomes.MC_1_9(), "Elytra", "cubiomes_viewer_icons", "elytra", 20, 20),
38-
END_GATEWAY("end_gateway", Cubiomes.End_Gateway(), Cubiomes.DIM_END(), Cubiomes.MC_1_13(), "End Gateway", "cubiomes_viewer_icons", 20, 20),
39-
TRAIL_RUINS("trail_ruins", Cubiomes.Trail_Ruins(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_20(), "Trail Ruins", "cubiomes_viewer_icons", 20, 20),
40-
TRIAL_CHAMBERS("trial_chambers", Cubiomes.Trial_Chambers(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_21_1(), "Trial Chambers", "cubiomes_viewer_icons", 20, 20),
41-
SLIME_CHUNK("slime_chunk", -1, Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_B1_7(), "Slime Chunk", "feature_icons", 20, 20),
42-
WORLD_SPAWN("world_spawn", -1, Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_B1_7(), "World Spawn", "cubiomes_viewer_icons", 20, 20),
43-
WAYPOINT("waypoint", -1, Cubiomes.DIM_UNDEF(), Cubiomes.MC_B1_7(), "Waypoint", "feature_icons", 20, 20),
19+
DESERT_PYRAMID("desert_pyramid", Cubiomes.Desert_Pyramid(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_3(), "cubiomes_viewer_icons", 19, 20),
20+
JUNGLE_PYRAMID("jungle_pyramid", Cubiomes.Jungle_Pyramid(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_3(), "cubiomes_viewer_icons", 19, 20),
21+
SWAMP_HUT("swamp_hut", Cubiomes.Swamp_Hut(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_4(), "cubiomes_viewer_icons", 20, 20),
22+
STRONGHOLD("stronghold", -1, Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_B1_8(), "cubiomes_viewer_icons", 19, 20),
23+
IGLOO("igloo", Cubiomes.Igloo(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_9(), "cubiomes_viewer_icons", 20, 20) {
24+
private static final Texture IGLOO_BASEMENT_TEXTURE = new Texture("igloo_basement", "cubiomes_viewer_icons", 20, 20);
25+
@Override
26+
public Texture getVariantTexture(WorldIdentifier identifier, int posX, int posZ, int biome) {
27+
try (Arena arena = Arena.ofConfined()) {
28+
MemorySegment variant = StructureVariant.allocate(arena);
29+
Cubiomes.getVariant(variant, this.getStructureId(), identifier.version(), identifier.seed(), posX, posZ, biome);
30+
if (StructureVariant.basement(variant) == 1) {
31+
return IGLOO_BASEMENT_TEXTURE;
32+
}
33+
return super.getDefaultTexture();
34+
}
35+
}
36+
},
37+
VILLAGE("village", Cubiomes.Village(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_B1_8(), "cubiomes_viewer_icons", 19, 20) {
38+
private static final Texture ZOMBIE_VILLAGE_TEXTURE = new Texture("zombie", "cubiomes_viewer_icons", 19, 20);
39+
@Override
40+
public Texture getVariantTexture(WorldIdentifier identifier, int posX, int posZ, int biome) {
41+
try (Arena arena = Arena.ofConfined()) {
42+
MemorySegment variant = StructureVariant.allocate(arena);
43+
Cubiomes.getVariant(variant, this.getStructureId(), identifier.version(), identifier.seed(), posX, posZ, biome);
44+
if (StructureVariant.abandoned(variant) == 1) {
45+
return ZOMBIE_VILLAGE_TEXTURE;
46+
}
47+
return super.getDefaultTexture();
48+
}
49+
}
50+
},
51+
OCEAN_RUIN("ocean_ruin", Cubiomes.Ocean_Ruin(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_13(), "cubiomes_viewer_icons", 19, 19),
52+
SHIPWRECK("shipwreck", Cubiomes.Shipwreck(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_13(), "cubiomes_viewer_icons", 19, 19),
53+
MONUMENT("monument", Cubiomes.Monument(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_8(), "cubiomes_viewer_icons", 20, 20),
54+
MANSION("mansion", Cubiomes.Mansion(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_11(), "cubiomes_viewer_icons", 20, 20),
55+
OUTPOST("pillager_outpost", Cubiomes.Outpost(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_14(), "cubiomes_viewer_icons", 19, 20),
56+
RUINED_PORTAL("ruined_portal", Cubiomes.Ruined_Portal(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_16_1(), "cubiomes_viewer_icons", 20, 20) {
57+
private static final Texture RUINED_PORTAL_GIANT_TEXTURE = new Texture("portal_giant", "cubiomes_viewer_icons", 20, 20);
58+
@Override
59+
public Texture getVariantTexture(WorldIdentifier identifier, int posX, int posZ, int biome) {
60+
try (Arena arena = Arena.ofConfined()) {
61+
MemorySegment variant = StructureVariant.allocate(arena);
62+
Cubiomes.getVariant(variant, this.getStructureId(), identifier.version(), identifier.seed(), posX, posZ, biome);
63+
if (StructureVariant.giant(variant) == 1) {
64+
return RUINED_PORTAL_GIANT_TEXTURE;
65+
}
66+
return super.getDefaultTexture();
67+
}
68+
}
69+
},
70+
RUINED_PORTAL_N("ruined_portal_n", Cubiomes.Ruined_Portal_N(), Cubiomes.DIM_NETHER(), Cubiomes.MC_1_16_1(), "cubiomes_viewer_icons", 20, 20) {
71+
@Override
72+
public Texture getVariantTexture(WorldIdentifier identifier, int posX, int posZ, int biome) {
73+
return RUINED_PORTAL.getVariantTexture(identifier, posX, posZ, biome);
74+
}
75+
},
76+
ANCIENT_CITY("ancient_city", Cubiomes.Ancient_City(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_19_2(), "cubiomes_viewer_icons", 20, 20),
77+
TREASURE("buried_treasure", Cubiomes.Treasure(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_13(), "cubiomes_viewer_icons", 19, 19),
78+
MINESHAFT("mineshaft", Cubiomes.Mineshaft(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_B1_8(), "cubiomes_viewer_icons", 20, 19),
79+
DESERT_WELL("desert_well", Cubiomes.Desert_Well(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_13(), "cubiomes_viewer_icons", 20, 20),
80+
GEODE("geode", Cubiomes.Geode(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_17(), "cubiomes_viewer_icons", 20, 20),
81+
COPPER_ORE_VEIN("copper_ore_vein", -1, Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_18(), "feature_icons", 20, 20),
82+
IRON_ORE_VEIN("iron_ore_vein", -1, Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_18(), "feature_icons", 20, 20),
83+
CANYON("canyon", -1, Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_13(), "feature_icons", 20, 20),
84+
FORTRESS("fortress", Cubiomes.Fortress(), Cubiomes.DIM_NETHER(), Cubiomes.MC_1_0(), "cubiomes_viewer_icons", 20, 20),
85+
BASTION("bastion_remnant", Cubiomes.Bastion(), Cubiomes.DIM_NETHER(), Cubiomes.MC_1_16_1(), "cubiomes_viewer_icons", 20, 20),
86+
END_CITY("end_city", Cubiomes.End_City(), Cubiomes.DIM_END(), Cubiomes.MC_1_9(), "cubiomes_viewer_icons", 20, 20) {
87+
private static final Texture END_CITY_SHIP_TEXTURE = new Texture("elytra", "cubiomes_viewer_icons", 20, 20);
88+
@Override
89+
public Texture getVariantTexture(WorldIdentifier identifier, int posX, int posZ, int biome) {
90+
try (Arena arena = Arena.ofConfined()) {
91+
MemorySegment pieces = Piece.allocateArray(StructureChecks.MAX_END_CITY_AND_FORTRESS_PIECES, arena);
92+
int numPieces = Cubiomes.getEndCityPieces(pieces, identifier.seed(), posX >> 4, posZ >> 4);
93+
boolean hasShip = IntStream.range(0, numPieces)
94+
.mapToObj(i -> Piece.asSlice(pieces, i))
95+
.anyMatch(piece -> Piece.type(piece) == Cubiomes.END_SHIP());
96+
if (hasShip) {
97+
return END_CITY_SHIP_TEXTURE;
98+
}
99+
return super.getDefaultTexture();
100+
}
101+
}
102+
},
103+
END_GATEWAY("end_gateway", Cubiomes.End_Gateway(), Cubiomes.DIM_END(), Cubiomes.MC_1_13(), "cubiomes_viewer_icons", 20, 20),
104+
TRAIL_RUINS("trail_ruins", Cubiomes.Trail_Ruins(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_20(), "cubiomes_viewer_icons", 20, 20),
105+
TRIAL_CHAMBERS("trial_chambers", Cubiomes.Trial_Chambers(), Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_1_21_1(), "cubiomes_viewer_icons", 20, 20),
106+
SLIME_CHUNK("slime_chunk", -1, Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_B1_7(), "feature_icons", 20, 20),
107+
WORLD_SPAWN("world_spawn", -1, Cubiomes.DIM_OVERWORLD(), Cubiomes.MC_B1_7(), "cubiomes_viewer_icons", 20, 20),
108+
WAYPOINT("waypoint", -1, Cubiomes.DIM_UNDEF(), Cubiomes.MC_B1_7(), "feature_icons", 20, 20),
44109
;
45110

46111
public static final Map<String, MapFeature> BY_NAME = Arrays.stream(values())
@@ -50,9 +115,7 @@ public enum MapFeature {
50115
private final int structureId;
51116
private final int dimension;
52117
private final int availableSince;
53-
private final Component displayName;
54-
private final String translationKey;
55-
private final Texture texture;
118+
private final Texture defaultTexture;
56119

57120
MapFeature(String name, int structureId, int dimension, int availableSince, String displayName, String directory, int textureWidth, int textureHeight) {
58121
this(name, structureId, dimension, availableSince, displayName, directory, name, textureWidth, textureHeight);
@@ -63,9 +126,7 @@ public enum MapFeature {
63126
this.structureId = structureId;
64127
this.dimension = dimension;
65128
this.availableSince = availableSince;
66-
this.translationKey = "seedMap.feature." + name;
67-
this.displayName = Component.translatableWithFallback(this.translationKey, displayName);
68-
this.texture = new Texture(textureName, directory, textureWidth, textureHeight);
129+
this.defaultTexture = new Texture(name, directory, textureWidth, textureHeight);
69130
}
70131

71132
public String getName() {
@@ -84,16 +145,12 @@ public int availableSince() {
84145
return this.availableSince;
85146
}
86147

87-
public Component getDisplayName() {
88-
return this.displayName;
89-
}
90-
91-
public String getTranslationKey() {
92-
return this.translationKey;
148+
public Texture getDefaultTexture() {
149+
return this.defaultTexture;
93150
}
94151

95-
public Texture getTexture() {
96-
return this.texture;
152+
public Texture getVariantTexture(WorldIdentifier identifier, int posX, int posZ, int biome) {
153+
return this.getDefaultTexture();
97154
}
98155

99156
public record Texture(ResourceLocation resourceLocation, int width, int height) {

0 commit comments

Comments
 (0)