Skip to content

Commit a7f0b3b

Browse files
committed
4.2.1: fix obstructed spawns not checking for grass and not reversing all modifications to the random call, formatting
1 parent 8c9b258 commit a7f0b3b

File tree

5 files changed

+196
-26
lines changed

5 files changed

+196
-26
lines changed

1.13.x/gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
minecraft_version=1.13.2
2-
yarn_build=565
2+
yarn_build=571

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

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package net.set.spawn.mod.mixin;
22

3+
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
34
import com.llamalad7.mixinextras.injector.wrapoperation.*;
45
import com.llamalad7.mixinextras.sugar.*;
56
import com.llamalad7.mixinextras.sugar.ref.*;
@@ -13,7 +14,7 @@
1314
import net.set.spawn.mod.interfaces.MinecraftServerExtended;
1415
import org.spongepowered.asm.mixin.*;
1516
import org.spongepowered.asm.mixin.injection.*;
16-
import org.spongepowered.asm.mixin.injection.callback.*;
17+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
1718

1819
import java.util.Random;
1920

@@ -33,7 +34,16 @@ public abstract class ServerPlayerEntityMixin {
3334
public abstract ServerWorld getServerWorld();
3435

3536
@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, @Share("newRandomValue") LocalRef<Integer> newRandomValue) {
37+
private int setSpawn(
38+
Random random,
39+
int bounds,
40+
Operation<Integer> original,
41+
@Local(ordinal = 0) BlockPos worldSpawn,
42+
@Local(ordinal = 0) int spawnRadius,
43+
@Share("seed") LocalRef<Seed> seed,
44+
@Share("originalRandomResult") LocalRef<Integer> originalRandomResult,
45+
@Share("newRandomValue") LocalRef<Integer> newRandomValue
46+
) {
3747
int originalResult = original.call(random, bounds);
3848

3949
if (((MinecraftServerExtended) this.server).setspawnmod$shouldModifySpawn()) {
@@ -52,7 +62,7 @@ private int setSpawn(Random random, int bounds, Operation<Integer> original, @Lo
5262
int xLocal = x - worldSpawn.getX() + spawnRadius;
5363
int result = xLocal + (z - worldSpawn.getZ() + spawnRadius) * spawnDiameter;
5464

55-
if (xLocal >=0 && xLocal < spawnDiameter && result >= 0 && result < bounds) {
65+
if (xLocal >= 0 && xLocal < spawnDiameter && result >= 0 && result < bounds) {
5666
// we save the original result in case the set spawn is invalid, see fallbackOnInvalidSpawn
5767
originalRandomResult.set(originalResult);
5868
newRandomValue.set(result);
@@ -64,8 +74,36 @@ private int setSpawn(Random random, int bounds, Operation<Integer> original, @Lo
6474
return originalResult;
6575
}
6676

77+
@ModifyExpressionValue(
78+
method = "method_21281",
79+
at = @At(
80+
value = "INVOKE",
81+
target = "Lnet/minecraft/world/dimension/Dimension;method_17190(IIZ)Lnet/minecraft/util/math/BlockPos;"
82+
)
83+
)
84+
private BlockPos captureIfHasGrassBlock(
85+
BlockPos blockPos,
86+
@Share("originalRandomResult") LocalRef<Integer> originalRandomResult,
87+
@Share("validIncludingObstructed") LocalBooleanRef validIncludingObstructed
88+
) {
89+
if (originalRandomResult.get() != null) {
90+
// whether or not the spawn is obstructed, it has a grass block above sea level and is valid as an obstructed spawn if all other spawns are obstructed or invalid
91+
validIncludingObstructed.set(blockPos != null);
92+
}
93+
return blockPos;
94+
}
95+
6796
@ModifyVariable(method = "method_21281", at = @At(value = "LOAD", ordinal = 0), ordinal = 5)
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) {
97+
private int fallbackOnInvalidSpawn(
98+
int p,
99+
@Local(ordinal = 2) int k,
100+
@Local(ordinal = 3) int n,
101+
@Local(ordinal = 4) LocalIntRef o,
102+
@Share("seed") LocalRef<Seed> seed,
103+
@Share("originalRandomResult") LocalRef<Integer> originalRandomResult,
104+
@Share("newRandomValue") LocalRef<Integer> newRandomValue,
105+
@Share("validIncludingObstructed") LocalBooleanRef validIncludingObstructed
106+
) {
69107
// checks if the for loop is on its second iteration (p == 1), meaning the setspawn given spawn was invalid
70108
// and restores the original result of Random#nextInt
71109
if (p == 1 && originalRandomResult.get() != null) {
@@ -77,16 +115,23 @@ private int fallbackOnInvalidSpawn(int p, @Local(ordinal = 2) int k, @Local(ordi
77115
}
78116
// if we made it to the end of the loop after an obstructed spawn and didn't find another non-obstructed spawn
79117
// 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());
118+
if (p == k && originalRandomResult.get() == null && newRandomValue.get() != null && validIncludingObstructed.get()) {
119+
o.set(newRandomValue.get() - n * (p - 1));
82120
newRandomValue.set(null);
83121
p = k - 1;
84122
this.setSpawnError = null;
85123
}
86124
return p;
87125
}
88126

89-
@Inject(method = "method_21281", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/ServerPlayerEntity;refreshPositionAndAngles(Lnet/minecraft/util/math/BlockPos;FF)V", ordinal = 1))
127+
@Inject(
128+
method = "method_21281",
129+
at = @At(
130+
value = "INVOKE",
131+
target = "Lnet/minecraft/entity/player/ServerPlayerEntity;refreshPositionAndAngles(Lnet/minecraft/util/math/BlockPos;FF)V",
132+
ordinal = 1
133+
)
134+
)
90135
private void failOnNonRandomSpawns(CallbackInfo ci, @Share("seed") LocalRef<Seed> seed) {
91136
if (seed.get() != null) {
92137
this.setSpawnError = "Failed to apply SetSpawn configuration because the spawn was not random. Not overriding player spawnpoint.";

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

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package net.set.spawn.mod.mixin;
22

3+
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
34
import com.llamalad7.mixinextras.injector.wrapoperation.*;
45
import com.llamalad7.mixinextras.sugar.*;
56
import com.llamalad7.mixinextras.sugar.ref.*;
@@ -33,7 +34,16 @@ public abstract class ServerPlayerEntityMixin {
3334
public abstract ServerWorld getServerWorld();
3435

3536
@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, @Share("newRandomValue") LocalRef<Integer> newRandomValue) {
37+
private int setSpawn(
38+
Random random,
39+
int bounds,
40+
Operation<Integer> original,
41+
@Local(ordinal = 0) BlockPos worldSpawn,
42+
@Local(ordinal = 0) int spawnRadius,
43+
@Share("seed") LocalRef<Seed> seed,
44+
@Share("originalRandomResult") LocalRef<Integer> originalRandomResult,
45+
@Share("newRandomValue") LocalRef<Integer> newRandomValue
46+
) {
3747
int originalResult = original.call(random, bounds);
3848

3949
if (((MinecraftServerExtended) this.server).setspawnmod$shouldModifySpawn()) {
@@ -51,7 +61,7 @@ private int setSpawn(Random random, int bounds, Operation<Integer> original, @Lo
5161
int xLocal = x - worldSpawn.getX() + spawnRadius;
5262
int result = xLocal + (z - worldSpawn.getZ() + spawnRadius) * spawnDiameter;
5363

54-
if (xLocal >=0 && xLocal < spawnDiameter && result >= 0 && result < bounds) {
64+
if (xLocal >= 0 && xLocal < spawnDiameter && result >= 0 && result < bounds) {
5565
// we save the original result in case the set spawn is invalid, see fallbackOnInvalidSpawn
5666
originalRandomResult.set(originalResult);
5767
newRandomValue.set(result);
@@ -63,8 +73,36 @@ private int setSpawn(Random random, int bounds, Operation<Integer> original, @Lo
6373
return originalResult;
6474
}
6575

76+
@ModifyExpressionValue(
77+
method = "moveToSpawn",
78+
at = @At(
79+
value = "INVOKE",
80+
target = "Lnet/minecraft/server/network/SpawnLocating;findOverworldSpawn(Lnet/minecraft/server/world/ServerWorld;IIZ)Lnet/minecraft/util/math/BlockPos;"
81+
)
82+
)
83+
private BlockPos captureIfHasGrassBlock(
84+
BlockPos blockPos,
85+
@Share("originalRandomResult") LocalRef<Integer> originalRandomResult,
86+
@Share("validIncludingObstructed") LocalBooleanRef validIncludingObstructed
87+
) {
88+
if (originalRandomResult.get() != null) {
89+
// whether or not the spawn is obstructed, it has a grass block above sea level and is valid as an obstructed spawn if all other spawns are obstructed or invalid
90+
validIncludingObstructed.set(blockPos != null);
91+
}
92+
return blockPos;
93+
}
94+
6695
@ModifyVariable(method = "moveToSpawn", at = @At(value = "LOAD", ordinal = 0), ordinal = 5)
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) {
96+
private int fallbackOnInvalidSpawn(
97+
int p,
98+
@Local(ordinal = 2) int k,
99+
@Local(ordinal = 3) int n,
100+
@Local(ordinal = 4) LocalIntRef o,
101+
@Share("seed") LocalRef<Seed> seed,
102+
@Share("originalRandomResult") LocalRef<Integer> originalRandomResult,
103+
@Share("newRandomValue") LocalRef<Integer> newRandomValue,
104+
@Share("validIncludingObstructed") LocalBooleanRef validIncludingObstructed
105+
) {
68106
// checks if the for loop is on its second iteration (p == 1), meaning the setspawn given spawn was invalid
69107
// and restores the original result of Random#nextInt
70108
if (p == 1 && originalRandomResult.get() != null) {
@@ -76,16 +114,23 @@ private int fallbackOnInvalidSpawn(int p, @Local(ordinal = 2) int k, @Local(ordi
76114
}
77115
// if we made it to the end of the loop after an obstructed spawn and didn't find another non-obstructed spawn
78116
// 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());
117+
if (p == k && originalRandomResult.get() == null && newRandomValue.get() != null && validIncludingObstructed.get()) {
118+
o.set(newRandomValue.get() - n * (p - 1));
81119
newRandomValue.set(null);
82120
p = k - 1;
83121
this.setSpawnError = null;
84122
}
85123
return p;
86124
}
87125

88-
@Inject(method = "moveToSpawn", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayerEntity;refreshPositionAndAngles(Lnet/minecraft/util/math/BlockPos;FF)V", ordinal = 1))
126+
@Inject(
127+
method = "moveToSpawn",
128+
at = @At(
129+
value = "INVOKE",
130+
target = "Lnet/minecraft/server/network/ServerPlayerEntity;refreshPositionAndAngles(Lnet/minecraft/util/math/BlockPos;FF)V",
131+
ordinal = 1
132+
)
133+
)
89134
private void failOnNonRandomSpawns(CallbackInfo ci, @Share("seed") LocalRef<Seed> seed) {
90135
if (seed.get() != null) {
91136
this.setSpawnError = "Failed to apply SetSpawn configuration because the spawn was not random. Not overriding player spawnpoint.";

0 commit comments

Comments
 (0)