Skip to content

Commit a45fc01

Browse files
committed
4.2.0: allow obstructed spawns if every other spawn is obstructed
1 parent a1ce3ab commit a45fc01

File tree

4 files changed

+40
-12
lines changed

4 files changed

+40
-12
lines changed

1.13.x/src/main/java/net/set/spawn/mod/mixin/ServerPlayerEntityMixin.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public abstract class ServerPlayerEntityMixin {
3333
public abstract ServerWorld getServerWorld();
3434

3535
@WrapOperation(method = "method_21281", at = @At(value = "INVOKE", target = "Ljava/util/Random;nextInt(I)I"))
36-
private int setSpawn(Random random, int bounds, Operation<Integer> original, @Local(ordinal = 0) BlockPos worldSpawn, @Local(ordinal = 0) int spawnRadius, @Share("seed") LocalRef<Seed> seed, @Share("originalRandomResult") LocalRef<Integer> originalRandomResult) {
36+
private int setSpawn(Random random, int bounds, Operation<Integer> original, @Local(ordinal = 0) BlockPos worldSpawn, @Local(ordinal = 0) int spawnRadius, @Share("seed") LocalRef<Seed> seed, @Share("originalRandomResult") LocalRef<Integer> originalRandomResult, @Share("newRandomValue") LocalRef<Integer> newRandomValue) {
3737
int originalResult = original.call(random, bounds);
3838

3939
if (((MinecraftServerExtended) this.server).setspawnmod$shouldModifySpawn()) {
@@ -54,8 +54,9 @@ private int setSpawn(Random random, int bounds, Operation<Integer> original, @Lo
5454

5555
if (xLocal >=0 && xLocal < spawnDiameter && result >= 0 && result < bounds) {
5656
// we save the original result in case the set spawn is invalid, see fallbackOnInvalidSpawn
57-
System.out.println("Setting spawn");
5857
originalRandomResult.set(originalResult);
58+
newRandomValue.set(result);
59+
System.out.println("Setting spawn");
5960
return result;
6061
} else {
6162
this.setSpawnError = "The X or Z coordinates given (" + seed.get().getX() + ", " + seed.get().getZ() + ") are more than the worlds spawn radius (" + spawnRadius + " blocks) away from the world spawn. Not overriding player spawnpoint.";
@@ -64,7 +65,7 @@ private int setSpawn(Random random, int bounds, Operation<Integer> original, @Lo
6465
}
6566

6667
@ModifyVariable(method = "method_21281", at = @At(value = "LOAD", ordinal = 0), ordinal = 5)
67-
private int fallbackOnInvalidSpawn(int p, @Local(ordinal = 4) LocalIntRef o, @Share("seed") LocalRef<Seed> seed, @Share("originalRandomResult") LocalRef<Integer> originalRandomResult) {
68+
private int fallbackOnInvalidSpawn(int p, @Local(ordinal = 2) int k, @Local(ordinal = 4) LocalIntRef o, @Share("seed") LocalRef<Seed> seed, @Share("originalRandomResult") LocalRef<Integer> originalRandomResult, @Share("newRandomValue") LocalRef<Integer> newRandomValue) {
6869
// checks if the for loop is on its second iteration (p == 1), meaning the setspawn given spawn was invalid
6970
// and restores the original result of Random#nextInt
7071
if (p == 1 && originalRandomResult.get() != null) {
@@ -74,6 +75,14 @@ private int fallbackOnInvalidSpawn(int p, @Local(ordinal = 4) LocalIntRef o, @Sh
7475

7576
this.setSpawnError = "There is no valid spawning location at the specified coordinates (" + seed.get().getX() + ", " + seed.get().getZ() + "). Not overriding player spawnpoint.";
7677
}
78+
// if we made it to the end of the loop after an obstructed spawn and didn't find another non-obstructed spawn
79+
// redo the last iteration of the loop with the choice obstructed spawn
80+
if (p == k && originalRandomResult.get() == null && newRandomValue.get() != null) {
81+
o.set(newRandomValue.get());
82+
newRandomValue.set(null);
83+
p = k - 1;
84+
this.setSpawnError = null;
85+
}
7786
return p;
7887
}
7988

1.14-1.18.2/src/main/java/net/set/spawn/mod/mixin/ServerPlayerEntityMixin.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public abstract class ServerPlayerEntityMixin {
3333
public abstract ServerWorld getServerWorld();
3434

3535
@WrapOperation(method = "moveToSpawn", at = @At(value = "INVOKE", target = "Ljava/util/Random;nextInt(I)I"))
36-
private int setSpawn(Random random, int bounds, Operation<Integer> original, @Local(ordinal = 0) BlockPos worldSpawn, @Local(ordinal = 0) int spawnRadius, @Share("seed") LocalRef<Seed> seed, @Share("originalRandomResult") LocalRef<Integer> originalRandomResult) {
36+
private int setSpawn(Random random, int bounds, Operation<Integer> original, @Local(ordinal = 0) BlockPos worldSpawn, @Local(ordinal = 0) int spawnRadius, @Share("seed") LocalRef<Seed> seed, @Share("originalRandomResult") LocalRef<Integer> originalRandomResult, @Share("newRandomValue") LocalRef<Integer> newRandomValue) {
3737
int originalResult = original.call(random, bounds);
3838

3939
if (((MinecraftServerExtended) this.server).setspawnmod$shouldModifySpawn()) {
@@ -53,8 +53,9 @@ private int setSpawn(Random random, int bounds, Operation<Integer> original, @Lo
5353

5454
if (xLocal >=0 && xLocal < spawnDiameter && result >= 0 && result < bounds) {
5555
// we save the original result in case the set spawn is invalid, see fallbackOnInvalidSpawn
56-
System.out.println("Setting spawn");
5756
originalRandomResult.set(originalResult);
57+
newRandomValue.set(result);
58+
System.out.println("Setting spawn");
5859
return result;
5960
} else {
6061
this.setSpawnError = "The X or Z coordinates given (" + seed.get().getX() + ", " + seed.get().getZ() + ") are more than the worlds spawn radius (" + spawnRadius + " blocks) away from the world spawn. Not overriding player spawnpoint.";
@@ -63,7 +64,7 @@ private int setSpawn(Random random, int bounds, Operation<Integer> original, @Lo
6364
}
6465

6566
@ModifyVariable(method = "moveToSpawn", at = @At(value = "LOAD", ordinal = 0), ordinal = 5)
66-
private int fallbackOnInvalidSpawn(int p, @Local(ordinal = 4) LocalIntRef o, @Share("seed") LocalRef<Seed> seed, @Share("originalRandomResult") LocalRef<Integer> originalRandomResult) {
67+
private int fallbackOnInvalidSpawn(int p, @Local(ordinal = 2) int k, @Local(ordinal = 4) LocalIntRef o, @Share("seed") LocalRef<Seed> seed, @Share("originalRandomResult") LocalRef<Integer> originalRandomResult, @Share("newRandomValue") LocalRef<Integer> newRandomValue) {
6768
// checks if the for loop is on its second iteration (p == 1), meaning the setspawn given spawn was invalid
6869
// and restores the original result of Random#nextInt
6970
if (p == 1 && originalRandomResult.get() != null) {
@@ -73,6 +74,14 @@ private int fallbackOnInvalidSpawn(int p, @Local(ordinal = 4) LocalIntRef o, @Sh
7374

7475
this.setSpawnError = "There is no valid spawning location at the specified coordinates (" + seed.get().getX() + ", " + seed.get().getZ() + "). Not overriding player spawnpoint.";
7576
}
77+
// if we made it to the end of the loop after an obstructed spawn and didn't find another non-obstructed spawn
78+
// redo the last iteration of the loop with the choice obstructed spawn
79+
if (p == k && originalRandomResult.get() == null && newRandomValue.get() != null) {
80+
o.set(newRandomValue.get());
81+
newRandomValue.set(null);
82+
p = k - 1;
83+
this.setSpawnError = null;
84+
}
7685
return p;
7786
}
7887

@@ -84,22 +93,23 @@ private void failOnNonRandomSpawns(CallbackInfo ci, @Share("seed") LocalRef<Seed
8493
}
8594

8695
@Group(min = 1, max = 1)
96+
// 1.14-1.16.5
8797
@Inject(method = "onSpawn", at = @At("TAIL"), require = 0)
8898
private void sendErrorMessage(CallbackInfo ci) {
8999
if (this.setSpawnError != null) {
100+
// it is not possible to fix this without more subprojects. you are warned.
90101
this.sendMessage(new LiteralText("§c" + this.setSpawnError + " This run is not verifiable."), false);
91102
this.setSpawnError = null;
92103
}
93104
}
94105

95106
@Dynamic
96107
@Group
108+
// 1.17-1.18.2
97109
@Inject(method = "method_14235(Lnet/minecraft/class_1703;)V", at = @At("TAIL"), require = 0, remap = false)
98110
private void sendErrorMessage2(CallbackInfo ci) {
99111
if (this.setSpawnError != null) {
100-
// MutableText#formatted moved from BaseText in 1.16, can't compile against it
101-
BaseText message = new LiteralText(this.setSpawnError + " This run is not verifiable.");
102-
this.sendMessage(message.setStyle(message.getStyle().withFormatting(Formatting.RED)), false);
112+
this.sendMessage(new LiteralText(this.setSpawnError + " This run is not verifiable.").formatted(Formatting.RED), false);
103113
this.setSpawnError = null;
104114
}
105115
}

1.19-1.21.4/src/main/java/net/set/spawn/mod/mixin/ServerPlayerEntityMixin.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public abstract class ServerPlayerEntityMixin {
3333

3434
@Dynamic
3535
@WrapOperation(method = {"moveToSpawn", "method_14245(Lnet/minecraft/class_3218;Lnet/minecraft/class_2338;)Lnet/minecraft/class_2338;"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/random/Random;nextInt(I)I"))
36-
private int setSpawn(Random random, int bounds, Operation<Integer> original, @Local(ordinal = 0) BlockPos worldSpawn, @Local(ordinal = 0) int spawnRadius, @Share("seed") LocalRef<Seed> seed, @Share("originalRandomResult") LocalRef<Integer> originalRandomResult, @Share("isRandomSpawn") LocalBooleanRef isRandomSpawn) {
36+
private int setSpawn(Random random, int bounds, Operation<Integer> original, @Local(ordinal = 0) BlockPos worldSpawn, @Local(ordinal = 0) int spawnRadius, @Share("seed") LocalRef<Seed> seed, @Share("originalRandomResult") LocalRef<Integer> originalRandomResult, @Share("isRandomSpawn") LocalBooleanRef isRandomSpawn, @Share("newRandomValue") LocalRef<Integer> newRandomValue) {
3737
// fallback for 1.21 with no else statement in the skylight check
3838
isRandomSpawn.set(true);
3939
int originalResult = original.call(random, bounds);
@@ -57,6 +57,7 @@ private int setSpawn(Random random, int bounds, Operation<Integer> original, @Lo
5757
if (xLocal >=0 && xLocal < spawnDiameter && result >= 0 && result < bounds) {
5858
// we save the original result in case the set spawn is invalid, see fallbackOnInvalidSpawn
5959
originalRandomResult.set(originalResult);
60+
newRandomValue.set(result);
6061
System.out.println("Setting spawn");
6162
return result;
6263
} else {
@@ -67,7 +68,7 @@ private int setSpawn(Random random, int bounds, Operation<Integer> original, @Lo
6768

6869
@Dynamic
6970
@ModifyVariable(method = {"moveToSpawn", "method_14245(Lnet/minecraft/class_3218;Lnet/minecraft/class_2338;)Lnet/minecraft/class_2338;"}, at = @At(value = "LOAD", ordinal = 0), ordinal = 5)
70-
private int fallbackOnInvalidSpawn(int p, @Local(ordinal = 4) LocalIntRef o, @Share("seed") LocalRef<Seed> seed, @Share("originalRandomResult") LocalRef<Integer> originalRandomResult) {
71+
private int fallbackOnInvalidSpawn(int p, @Local(ordinal = 2) int k, @Local(ordinal = 4) LocalIntRef o, @Share("seed") LocalRef<Seed> seed, @Share("originalRandomResult") LocalRef<Integer> originalRandomResult, @Share("newRandomValue") LocalRef<Integer> newRandomValue) {
7172
// checks if the for loop is on its second iteration (p == 1), meaning the setspawn given spawn was invalid
7273
// and restores the original result of Random#nextInt
7374
if (p == 1 && originalRandomResult.get() != null) {
@@ -77,6 +78,14 @@ private int fallbackOnInvalidSpawn(int p, @Local(ordinal = 4) LocalIntRef o, @Sh
7778

7879
this.setSpawnError = "There is no valid spawning location at the specified coordinates (" + seed.get().getX() + ", " + seed.get().getZ() + "). Not overriding player spawnpoint.";
7980
}
81+
// if we made it to the end of the loop after an obstructed spawn and didn't find another non-obstructed spawn
82+
// redo the last iteration of the loop with the choice obstructed spawn
83+
if (p == k && originalRandomResult.get() == null && newRandomValue.get() != null) {
84+
o.set(newRandomValue.get());
85+
newRandomValue.set(null);
86+
p = k - 1;
87+
this.setSpawnError = null;
88+
}
8089
return p;
8190
}
8291

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ org.gradle.jvmargs = -Xmx2G
22
org.gradle.parallel = true
33
org.gradle.caching = true
44

5-
mod_version = 4.1.2
5+
mod_version = 4.2.0
66
archives_name = setspawnmod
77
base_archives_name = setspawnmod-common
88
maven_group = me.bdamja

0 commit comments

Comments
 (0)