Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified 1.12/src/main/resources/assets/setspawnmod/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions 1.12/src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
"tildejustin",
"contaria"
],
"contact": {
"homepage": "https://github.com/Minecraft-Java-Edition-Speedrunning/set-spawn",
"sources": "https://github.com/Minecraft-Java-Edition-Speedrunning/set-spawn",
"issues": "https://github.com/Minecraft-Java-Edition-Speedrunning/set-spawn/issues"
},
"license": "LGPL-3.0-only",
"icon": "assets/setspawnmod/icon.png",
"environment": "*",
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion 1.13.x/gradle.properties → 1.13.2/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
minecraft_version=1.13.2
yarn_build=565
yarn_build=571
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.set.spawn.mod.mixin;

import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.injector.wrapoperation.*;
import com.llamalad7.mixinextras.sugar.*;
import com.llamalad7.mixinextras.sugar.ref.*;
Expand All @@ -13,7 +14,7 @@
import net.set.spawn.mod.interfaces.MinecraftServerExtended;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import java.util.Random;

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

@WrapOperation(method = "method_21281", at = @At(value = "INVOKE", target = "Ljava/util/Random;nextInt(I)I"))
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) {
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
) {
int originalResult = original.call(random, bounds);

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

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

@ModifyExpressionValue(
method = "method_21281",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/dimension/Dimension;method_17190(IIZ)Lnet/minecraft/util/math/BlockPos;"
)
)
private BlockPos captureIfHasGrassBlock(
BlockPos blockPos,
@Share("originalRandomResult") LocalRef<Integer> originalRandomResult,
@Share("validIncludingObstructed") LocalBooleanRef validIncludingObstructed
) {
if (originalRandomResult.get() != null) {
// 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
validIncludingObstructed.set(blockPos != null);
}
return blockPos;
}

@ModifyVariable(method = "method_21281", at = @At(value = "LOAD", ordinal = 0), ordinal = 5)
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) {
private int fallbackOnInvalidSpawn(
int p,
@Local(ordinal = 2) int k,
@Local(ordinal = 3) int n,
@Local(ordinal = 4) LocalIntRef o,
@Share("seed") LocalRef<Seed> seed,
@Share("originalRandomResult") LocalRef<Integer> originalRandomResult,
@Share("newRandomValue") LocalRef<Integer> newRandomValue,
@Share("validIncludingObstructed") LocalBooleanRef validIncludingObstructed
) {
// checks if the for loop is on its second iteration (p == 1), meaning the setspawn given spawn was invalid
// and restores the original result of Random#nextInt
if (p == 1 && originalRandomResult.get() != null) {
Expand All @@ -77,16 +115,23 @@ private int fallbackOnInvalidSpawn(int p, @Local(ordinal = 2) int k, @Local(ordi
}
// if we made it to the end of the loop after an obstructed spawn and didn't find another non-obstructed spawn
// redo the last iteration of the loop with the choice obstructed spawn
if (p == k && originalRandomResult.get() == null && newRandomValue.get() != null) {
o.set(newRandomValue.get());
if (p == k && originalRandomResult.get() == null && newRandomValue.get() != null && validIncludingObstructed.get()) {
o.set(newRandomValue.get() - n * (p - 1));
newRandomValue.set(null);
p = k - 1;
this.setSpawnError = null;
}
return p;
}

@Inject(method = "method_21281", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/ServerPlayerEntity;refreshPositionAndAngles(Lnet/minecraft/util/math/BlockPos;FF)V", ordinal = 1))
@Inject(
method = "method_21281",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/entity/player/ServerPlayerEntity;refreshPositionAndAngles(Lnet/minecraft/util/math/BlockPos;FF)V",
ordinal = 1
)
)
private void failOnNonRandomSpawns(CallbackInfo ci, @Share("seed") LocalRef<Seed> seed) {
if (seed.get() != null) {
this.setSpawnError = "Failed to apply SetSpawn configuration because the spawn was not random. Not overriding player spawnpoint.";
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
"tildejustin",
"contaria"
],
"contact": {
"homepage": "https://github.com/Minecraft-Java-Edition-Speedrunning/set-spawn",
"sources": "https://github.com/Minecraft-Java-Edition-Speedrunning/set-spawn",
"issues": "https://github.com/Minecraft-Java-Edition-Speedrunning/set-spawn/issues"
},
"license": "LGPL-3.0-only",
"icon": "assets/setspawnmod/icon.png",
"environment": "*",
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package net.set.spawn.mod.mixin;

import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.injector.wrapoperation.*;
import com.llamalad7.mixinextras.sugar.*;
import com.llamalad7.mixinextras.sugar.ref.*;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.*;
import net.minecraft.util.Formatting;
import net.minecraft.util.math.*;
import net.set.spawn.mod.*;
import net.set.spawn.mod.interfaces.MinecraftServerExtended;
Expand All @@ -33,7 +33,16 @@ public abstract class ServerPlayerEntityMixin {
public abstract ServerWorld getServerWorld();

@WrapOperation(method = "moveToSpawn", at = @At(value = "INVOKE", target = "Ljava/util/Random;nextInt(I)I"))
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) {
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
) {
int originalResult = original.call(random, bounds);

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

if (xLocal >=0 && xLocal < spawnDiameter && result >= 0 && result < bounds) {
if (xLocal >= 0 && xLocal < spawnDiameter && result >= 0 && result < bounds) {
// we save the original result in case the set spawn is invalid, see fallbackOnInvalidSpawn
originalRandomResult.set(originalResult);
newRandomValue.set(result);
Expand All @@ -63,8 +72,52 @@ private int setSpawn(Random random, int bounds, Operation<Integer> original, @Lo
return originalResult;
}

@Dynamic
@ModifyExpressionValue(
method = "moveToSpawn",
at = {
@At(
value = "INVOKE",
target = "Lnet/minecraft/server/network/SpawnLocating;findOverworldSpawn(Lnet/minecraft/server/world/ServerWorld;IIZ)Lnet/minecraft/util/math/BlockPos;"
),
// 1.18+ findOverworldSpawn, no boolean
@At(
value = "INVOKE",
target = "Lnet/minecraft/class_5322;method_29194(Lnet/minecraft/class_3218;II)Lnet/minecraft/class_2338;"
),
@At(
value = "INVOKE",
// Dimension#getTopSpawningBlockPosition
target = "Lnet/minecraft/class_2869;method_12444(IIZ)Lnet/minecraft/class_2338;",
remap = false
)
},
require = 1,
allow = 1
)
private BlockPos captureIfHasGrassBlock(
BlockPos blockPos,
@Share("originalRandomResult") LocalRef<Integer> originalRandomResult,
@Share("validIncludingObstructed") LocalBooleanRef validIncludingObstructed
) {
if (originalRandomResult.get() != null) {
// 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
validIncludingObstructed.set(blockPos != null);
}
return blockPos;
}

@ModifyVariable(method = "moveToSpawn", at = @At(value = "LOAD", ordinal = 0), ordinal = 5)
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) {
private int fallbackOnInvalidSpawn(
int p,
@Local(ordinal = 2) int k,
@Local(ordinal = 3) int n,
@Local(ordinal = 4) LocalIntRef o,
@Share("seed") LocalRef<Seed> seed,
@Share("originalRandomResult") LocalRef<Integer> originalRandomResult,
@Share("newRandomValue") LocalRef<Integer> newRandomValue,
@Share("validIncludingObstructed") LocalBooleanRef validIncludingObstructed
) {
// checks if the for loop is on its second iteration (p == 1), meaning the setspawn given spawn was invalid
// and restores the original result of Random#nextInt
if (p == 1 && originalRandomResult.get() != null) {
Expand All @@ -76,16 +129,23 @@ private int fallbackOnInvalidSpawn(int p, @Local(ordinal = 2) int k, @Local(ordi
}
// if we made it to the end of the loop after an obstructed spawn and didn't find another non-obstructed spawn
// redo the last iteration of the loop with the choice obstructed spawn
if (p == k && originalRandomResult.get() == null && newRandomValue.get() != null) {
o.set(newRandomValue.get());
if (p == k && originalRandomResult.get() == null && newRandomValue.get() != null && validIncludingObstructed.get()) {
o.set(newRandomValue.get() - n * (p - 1));
newRandomValue.set(null);
p = k - 1;
this.setSpawnError = null;
}
return p;
}

@Inject(method = "moveToSpawn", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayerEntity;refreshPositionAndAngles(Lnet/minecraft/util/math/BlockPos;FF)V", ordinal = 1))
@Inject(
method = "moveToSpawn",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/server/network/ServerPlayerEntity;refreshPositionAndAngles(Lnet/minecraft/util/math/BlockPos;FF)V",
ordinal = 1
)
)
private void failOnNonRandomSpawns(CallbackInfo ci, @Share("seed") LocalRef<Seed> seed) {
if (seed.get() != null) {
this.setSpawnError = "Failed to apply SetSpawn configuration because the spawn was not random. Not overriding player spawnpoint.";
Expand All @@ -109,7 +169,8 @@ private void sendErrorMessage(CallbackInfo ci) {
@Inject(method = "method_14235(Lnet/minecraft/class_1703;)V", at = @At("TAIL"), require = 0, remap = false)
private void sendErrorMessage2(CallbackInfo ci) {
if (this.setSpawnError != null) {
this.sendMessage(new LiteralText(this.setSpawnError + " This run is not verifiable.").formatted(Formatting.RED), false);
// sorry the code is bad. it is the only way.
this.sendMessage(new LiteralText("§c" + this.setSpawnError + " This run is not verifiable."), false);
this.setSpawnError = null;
}
}
Expand Down
Binary file modified 1.14-1.18.2/src/main/resources/assets/setspawnmod/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions 1.14-1.18.2/src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
"tildejustin",
"contaria"
],
"contact": {
"homepage": "https://github.com/Minecraft-Java-Edition-Speedrunning/set-spawn",
"sources": "https://github.com/Minecraft-Java-Edition-Speedrunning/set-spawn",
"issues": "https://github.com/Minecraft-Java-Edition-Speedrunning/set-spawn/issues"
},
"license": "LGPL-3.0-only",
"icon": "assets/setspawnmod/icon.png",
"environment": "*",
Expand Down
Binary file not shown.
File renamed without changes.
File renamed without changes.
Loading