Skip to content

Commit 7746c93

Browse files
authored
feature: weighted locks (#97)
* feature: weighted locks Allow resource packs to change lock weights with optional lock metadata (e.g. lock-42.png.mcdata). * feat: defaultWeight for lock textures Add a default lock texture weight settable in lock.png.mcmeta.
1 parent f3c8db7 commit 7746c93

4 files changed

Lines changed: 114 additions & 5 deletions

File tree

src/main/java/me/contaria/seedqueue/customization/LockTexture.java

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import me.contaria.speedrunapi.util.IdentifierUtil;
55
import net.minecraft.client.MinecraftClient;
66
import net.minecraft.client.texture.NativeImage;
7+
import net.minecraft.resource.Resource;
8+
import net.minecraft.resource.ResourceManager;
79
import net.minecraft.util.Identifier;
810

911
import java.io.IOException;
@@ -13,29 +15,68 @@
1315
public class LockTexture extends AnimatedTexture {
1416
private final int width;
1517
private final int height;
18+
private final LockTextureMetadata metadata;
1619

17-
public LockTexture(Identifier id) throws IOException {
20+
public LockTexture(Identifier id, int defaultWeight) throws IOException {
1821
super(id);
19-
try (NativeImage image = NativeImage.read(MinecraftClient.getInstance().getResourceManager().getResource(id).getInputStream())) {
22+
23+
Resource resource = MinecraftClient.getInstance()
24+
.getResourceManager()
25+
.getResource(id);
26+
27+
try (NativeImage image = NativeImage.read(resource.getInputStream())) {
2028
this.width = image.getWidth();
2129
this.height = image.getHeight() / (this.animation != null ? this.animation.getFrameIndexSet().size() : 1);
2230
}
31+
32+
LockTextureMetadata metadata = resource.getMetadata(LockTextureMetadata.READER);
33+
34+
if (metadata == null) {
35+
metadata = new LockTextureMetadata();
36+
}
37+
38+
if (metadata.weight == 0) {
39+
metadata.weight = defaultWeight;
40+
}
41+
42+
this.metadata = metadata;
2343
}
2444

2545
public double getAspectRatio() {
2646
return (double) this.width / this.height;
2747
}
2848

49+
public int getWeight() {
50+
return Math.max(1, this.metadata.weight);
51+
}
52+
2953
public static List<LockTexture> createLockTextures() {
54+
ResourceManager resourceManager = MinecraftClient.getInstance().getResourceManager();
55+
3056
List<LockTexture> lockTextures = new ArrayList<>();
57+
3158
Identifier lock = IdentifierUtil.of("seedqueue", "textures/gui/wall/lock.png");
59+
60+
int defaultWeight = 1;
61+
try {
62+
MainLockTextureMetadata metadata = resourceManager
63+
.getResource(lock)
64+
.getMetadata(MainLockTextureMetadata.READER);
65+
66+
if (metadata != null) {
67+
defaultWeight = metadata.defaultWeight;
68+
}
69+
} catch (IOException e) {
70+
SeedQueue.LOGGER.warn("Failed to read the main lock texture", e);
71+
}
72+
3273
do {
3374
try {
34-
lockTextures.add(new LockTexture(lock));
75+
lockTextures.add(new LockTexture(lock, defaultWeight));
3576
} catch (IOException e) {
3677
SeedQueue.LOGGER.warn("Failed to read lock image texture: {}", lock, e);
3778
}
38-
} while (MinecraftClient.getInstance().getResourceManager().containsResource(lock = IdentifierUtil.of("seedqueue", "textures/gui/wall/lock-" + lockTextures.size() + ".png")));
79+
} while (resourceManager.containsResource(lock = IdentifierUtil.of("seedqueue", "textures/gui/wall/lock-" + lockTextures.size() + ".png")));
3980
return lockTextures;
4081
}
4182
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package me.contaria.seedqueue.customization;
2+
3+
import com.google.gson.Gson;
4+
import com.google.gson.JsonObject;
5+
import net.minecraft.resource.metadata.ResourceMetadataReader;
6+
7+
@SuppressWarnings("unused") // fields set by GSON
8+
class LockTextureMetadata {
9+
public static final ResourceMetadataReader<LockTextureMetadata> READER = new Reader();
10+
11+
public int weight;
12+
13+
private static class Reader implements ResourceMetadataReader<LockTextureMetadata> {
14+
private static final Gson GSON = new Gson();
15+
16+
@Override
17+
public String getKey() {
18+
return "seedqueue";
19+
}
20+
21+
@Override
22+
public LockTextureMetadata fromJson(JsonObject json) {
23+
return GSON.fromJson(json, LockTextureMetadata.class);
24+
}
25+
}
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package me.contaria.seedqueue.customization;
2+
3+
import com.google.gson.Gson;
4+
import com.google.gson.JsonObject;
5+
import net.minecraft.resource.metadata.ResourceMetadataReader;
6+
7+
class MainLockTextureMetadata {
8+
public static final ResourceMetadataReader<MainLockTextureMetadata> READER = new Reader();
9+
10+
@SuppressWarnings("unused") // set by GSON
11+
public int defaultWeight;
12+
13+
private static class Reader implements ResourceMetadataReader<MainLockTextureMetadata> {
14+
private static final Gson GSON = new Gson();
15+
16+
@Override
17+
public String getKey() {
18+
return "seedqueue";
19+
}
20+
21+
@Override
22+
public MainLockTextureMetadata fromJson(JsonObject json) {
23+
return GSON.fromJson(json, MainLockTextureMetadata.class);
24+
}
25+
}
26+
}

src/main/java/me/contaria/seedqueue/gui/wall/SeedQueueWallScreen.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ public class SeedQueueWallScreen extends Screen {
7474
private boolean playedScheduledEnterWarning;
7575

7676
private List<LockTexture> lockTextures;
77+
private int lockTexturesWeightSum;
7778
@Nullable
7879
private AnimatedTexture background;
7980
@Nullable
@@ -113,14 +114,29 @@ protected void init() {
113114
this.lockedPreviews = this.layout.locked != null ? new ArrayList<>() : null;
114115
this.preparingPreviews = new ArrayList<>();
115116
this.lockTextures = LockTexture.createLockTextures();
117+
this.lockTexturesWeightSum = this.lockTextures.stream()
118+
.mapToInt(LockTexture::getWeight)
119+
.reduce(0, Math::addExact);
116120
this.background = AnimatedTexture.of(WALL_BACKGROUND);
117121
this.overlay = AnimatedTexture.of(WALL_OVERLAY);
118122
this.instanceBackground = AnimatedTexture.of(INSTANCE_BACKGROUND);
119123
this.instanceOverlay = AnimatedTexture.of(INSTANCE_OVERLAY);
120124
}
121125

122126
protected LockTexture getRandomLockTexture() {
123-
return this.lockTextures.get(this.random.nextInt(this.lockTextures.size()));
127+
int target = this.random.nextInt(this.lockTexturesWeightSum);
128+
129+
int i = 0;
130+
131+
for (LockTexture lockTexture : this.lockTextures) {
132+
i += lockTexture.getWeight();
133+
134+
if (i > target) {
135+
return lockTexture;
136+
}
137+
}
138+
139+
throw new AssertionError("unreachable");
124140
}
125141

126142
@Override

0 commit comments

Comments
 (0)