-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Fixed my random Xoroshift implementation being very off causing tremendous lag (due to like 5000 entities spawning :P) - Fixed mobs not being very responsive - Fixed a Random crash when locating structures - Added an optimization to slime spawning that reduces Random operations by caching slime chunks in WorldChunk
- Loading branch information
Showing
12 changed files
with
205 additions
and
134 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
78 changes: 52 additions & 26 deletions
78
...java/com/github/tatercertified/potatoptimize/mixin/random/math/RandomMathHelperMixin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,54 +1,80 @@ | ||
package com.github.tatercertified.potatoptimize.mixin.random.math; | ||
|
||
import com.github.tatercertified.potatoptimize.utils.random.ThreadLocalRandomImpl; | ||
import com.github.tatercertified.potatoptimize.utils.random.PotatoptimizedRandom; | ||
import com.llamalad7.mixinextras.injector.ModifyReturnValue; | ||
import com.llamalad7.mixinextras.sugar.Local; | ||
import com.moulberry.mixinconstraints.annotations.IfModAbsent; | ||
import net.minecraft.util.math.MathHelper; | ||
import net.minecraft.util.math.random.Random; | ||
import org.spongepowered.asm.mixin.*; | ||
import org.spongepowered.asm.mixin.injection.At; | ||
import org.spongepowered.asm.mixin.injection.Inject; | ||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; | ||
|
||
import java.util.UUID; | ||
|
||
@IfModAbsent(value = "faster-random") | ||
@Mixin(MathHelper.class) | ||
public class RandomMathHelperMixin { | ||
public abstract class RandomMathHelperMixin { | ||
|
||
@Shadow @Final private static Random RANDOM; | ||
@Shadow | ||
public static float nextBetween(Random random, float min, float max) { | ||
return 0; | ||
} | ||
|
||
@ModifyReturnValue(method = "nextGaussian", at = @At("RETURN")) | ||
private static float optimizedGaussian(float original, @Local(ordinal = 0, argsOnly = true) float mean, @Local(ordinal = 0, argsOnly = true) float deviation, @Local(ordinal = 0, argsOnly = true) Random random) { | ||
return (float) (mean + quickGaussian(random) * deviation); | ||
} | ||
|
||
@Inject(method = "nextGaussian", at = @At("HEAD"), cancellable = true) | ||
private static void optimizedGaussian(Random random, float mean, float deviation, CallbackInfoReturnable<Float> cir) { | ||
cir.setReturnValue(((ThreadLocalRandomImpl)RANDOM).nextGaussian(mean, deviation)); | ||
// Gaussian Code | ||
private static double quickGaussian(Random random) { | ||
long randomBits = random.nextLong(); | ||
long evenChunks = randomBits & EVEN_CHUNKS; | ||
long oddChunks = (randomBits & ODD_CHUNKS) >>> 5; | ||
long sum = chunkSum(evenChunks + oddChunks) - 186; | ||
return sum / 31.0; | ||
} | ||
|
||
@Inject(method = "nextBetween(Lnet/minecraft/util/math/random/Random;II)I", at = @At("HEAD"), cancellable = true) | ||
private static void optimizedNextBetween(Random random, int min, int max, CallbackInfoReturnable<Integer> cir) { | ||
cir.setReturnValue(RANDOM.nextBetween(min, max)); | ||
private static long chunkSum(long bits) { | ||
long sum = bits + (bits >>> 40); | ||
sum += sum >>> 20; | ||
sum += sum >>> 10; | ||
sum &= (1<<10)-1; | ||
return sum; | ||
} | ||
|
||
@Inject(method = "nextBetween(Lnet/minecraft/util/math/random/Random;FF)F", at = @At("HEAD"), cancellable = true) | ||
private static void optimizedNextBetween(Random random, float min, float max, CallbackInfoReturnable<Float> cir) { | ||
cir.setReturnValue(((ThreadLocalRandomImpl)RANDOM).nextFloat(min, max)); | ||
private static final long EVEN_CHUNKS = 0x7c1f07c1f07c1fL; | ||
private static final long ODD_CHUNKS = EVEN_CHUNKS << 5; | ||
|
||
@ModifyReturnValue(method = "nextFloat", at = @At("RETURN")) | ||
private static float optimizedNextBetween(float original, @Local(ordinal = 0, argsOnly = true) Random random, @Local(ordinal = 0, argsOnly = true) float min, @Local(ordinal = 0, argsOnly = true) float max) { | ||
if (random instanceof PotatoptimizedRandom potatoptimizedRandom) { | ||
return potatoptimizedRandom.nextFloat(min, max); | ||
} else { | ||
return original; | ||
} | ||
} | ||
|
||
@Inject(method = "randomUuid(Lnet/minecraft/util/math/random/Random;)Ljava/util/UUID;", at = @At("HEAD"), cancellable = true) | ||
private static void optimizedRandomUUID(Random random, CallbackInfoReturnable<UUID> cir) { | ||
cir.setReturnValue(((ThreadLocalRandomImpl)RANDOM).nextUUID()); | ||
@ModifyReturnValue(method = "randomUuid(Lnet/minecraft/util/math/random/Random;)Ljava/util/UUID;", at = @At("RETURN")) | ||
private static UUID optimizedRandomUUID(UUID original, @Local(ordinal = 0, argsOnly = true) Random random) { | ||
return new UUID(random.nextLong() & 0xFFFFFFFFFFFF0FFFL | 0x4000L, random.nextLong() & 0x3FFFFFFFFFFFFFFFL | Long.MIN_VALUE); | ||
} | ||
|
||
@Inject(method = "nextInt", at = @At("HEAD"), cancellable = true) | ||
private static void optimizedNextInt(Random random, int min, int max, CallbackInfoReturnable<Integer> cir) { | ||
cir.setReturnValue(RANDOM.nextBetween(min, max)); | ||
@ModifyReturnValue(method = "nextInt", at = @At("RETURN")) | ||
private static int optimizedNextInt(int original, @Local(ordinal = 0, argsOnly = true) Random random, @Local(ordinal = 0, argsOnly = true) int min, @Local(ordinal = 0, argsOnly = true) int max) { | ||
return random.nextBetween(min, max); | ||
} | ||
|
||
@Inject(method = "nextFloat", at = @At("HEAD"), cancellable = true) | ||
private static void optimizedNextFloat(Random random, float min, float max, CallbackInfoReturnable<Float> cir) { | ||
cir.setReturnValue(((ThreadLocalRandomImpl)RANDOM).nextFloat(min, max)); | ||
@ModifyReturnValue(method = "nextFloat", at = @At("RETURN")) | ||
private static float optimizedNextFloat(float original, @Local(ordinal = 0, argsOnly = true) Random random, @Local(ordinal = 0, argsOnly = true) float min, @Local(ordinal = 0, argsOnly = true) float max) { | ||
return nextBetween(random, min, max); | ||
} | ||
|
||
@Inject(method = "nextDouble", at = @At("HEAD"), cancellable = true) | ||
private static void optimizedNextDouble(Random random, double min, double max, CallbackInfoReturnable<Double> cir) { | ||
cir.setReturnValue(((ThreadLocalRandomImpl)RANDOM).nextDouble(min, max)); | ||
@ModifyReturnValue(method = "nextDouble", at = @At("RETURN")) | ||
private static double optimizedNextDouble(double original, @Local(ordinal = 0, argsOnly = true) Random random, @Local(ordinal = 0, argsOnly = true) double min, @Local(ordinal = 0, argsOnly = true) double max) { | ||
if (random instanceof PotatoptimizedRandom potatoptimizedRandom) { | ||
return potatoptimizedRandom.nextDouble(min, max); | ||
} else { | ||
return original; | ||
} | ||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
...va/com/github/tatercertified/potatoptimize/mixin/random/slime/RandomSlimeEntityMixin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package com.github.tatercertified.potatoptimize.mixin.random.slime; | ||
|
||
import com.github.tatercertified.potatoptimize.utils.interfaces.SlimeChunkInterface; | ||
import net.minecraft.entity.EntityType; | ||
import net.minecraft.entity.SpawnReason; | ||
import net.minecraft.entity.mob.MobEntity; | ||
import net.minecraft.entity.mob.Monster; | ||
import net.minecraft.entity.mob.SlimeEntity; | ||
import net.minecraft.util.math.BlockPos; | ||
import net.minecraft.util.math.random.Random; | ||
import net.minecraft.world.StructureWorldAccess; | ||
import net.minecraft.world.World; | ||
import net.minecraft.world.WorldAccess; | ||
import net.minecraft.world.chunk.WorldChunk; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.Overwrite; | ||
|
||
@Mixin(SlimeEntity.class) | ||
public abstract class RandomSlimeEntityMixin extends MobEntity implements Monster { | ||
protected RandomSlimeEntityMixin(EntityType<? extends MobEntity> entityType, World world) { | ||
super(entityType, world); | ||
} | ||
|
||
/** | ||
* @author QPCrummer | ||
* @reason This is just plain awful | ||
*/ | ||
@Overwrite | ||
public static boolean canSpawn(EntityType<SlimeEntity> type, WorldAccess world, SpawnReason spawnReason, BlockPos pos, Random random) { | ||
if (!(world instanceof StructureWorldAccess)) { | ||
return false; | ||
} | ||
|
||
if (SpawnReason.isAnySpawner(spawnReason)) { | ||
return canMobSpawn(type, world, spawnReason, pos, random); | ||
} else if (pos.getY() < 70 && pos.getY() > 50 ) { | ||
float randomFloat = random.nextFloat(); // This will slightly change parity | ||
if (randomFloat > 0.5f && randomFloat > world.getMoonSize() && world.getLightLevel(pos) <= random.nextInt(8)) { | ||
return canMobSpawn(type, world, spawnReason, pos, random); | ||
} | ||
} | ||
|
||
if (pos.getY() < 40 && random.nextInt(10) == 0) { | ||
WorldChunk chunk = (WorldChunk) world.getChunk(pos); | ||
if (((SlimeChunkInterface)chunk).isSlimeChunk()) { | ||
return canMobSpawn(type, world, spawnReason, pos, random); | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
...main/java/com/github/tatercertified/potatoptimize/mixin/random/slime/SlimeChunkMixin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package com.github.tatercertified.potatoptimize.mixin.random.slime; | ||
|
||
import com.github.tatercertified.potatoptimize.utils.interfaces.SlimeChunkInterface; | ||
import net.minecraft.server.world.ServerWorld; | ||
import net.minecraft.util.math.ChunkPos; | ||
import net.minecraft.util.math.random.ChunkRandom; | ||
import net.minecraft.util.math.random.Random; | ||
import net.minecraft.world.StructureWorldAccess; | ||
import net.minecraft.world.World; | ||
import net.minecraft.world.chunk.ChunkSection; | ||
import net.minecraft.world.chunk.ProtoChunk; | ||
import net.minecraft.world.chunk.UpgradeData; | ||
import net.minecraft.world.chunk.WorldChunk; | ||
import net.minecraft.world.gen.chunk.BlendingData; | ||
import net.minecraft.world.tick.ChunkTickScheduler; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.injection.At; | ||
import org.spongepowered.asm.mixin.injection.Inject; | ||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; | ||
|
||
@Mixin(WorldChunk.class) | ||
public class SlimeChunkMixin implements SlimeChunkInterface { | ||
|
||
private boolean slimeChunk; | ||
|
||
@Inject(method = "<init>(Lnet/minecraft/world/World;Lnet/minecraft/util/math/ChunkPos;)V", at = @At("TAIL")) | ||
private void assignSlimeChunk1(World world, ChunkPos pos, CallbackInfo ci) { | ||
setSlimeChunk(world, pos); | ||
} | ||
|
||
@Inject(method = "<init>(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/world/chunk/ProtoChunk;Lnet/minecraft/world/chunk/WorldChunk$EntityLoader;)V", at = @At("TAIL")) | ||
private void assignSlimeChunk2(ServerWorld world, ProtoChunk protoChunk, WorldChunk.EntityLoader entityLoader, CallbackInfo ci) { | ||
setSlimeChunk(world, protoChunk.getPos()); | ||
} | ||
|
||
@Inject(method = "<init>(Lnet/minecraft/world/World;Lnet/minecraft/util/math/ChunkPos;Lnet/minecraft/world/chunk/UpgradeData;Lnet/minecraft/world/tick/ChunkTickScheduler;Lnet/minecraft/world/tick/ChunkTickScheduler;J[Lnet/minecraft/world/chunk/ChunkSection;Lnet/minecraft/world/chunk/WorldChunk$EntityLoader;Lnet/minecraft/world/gen/chunk/BlendingData;)V", at = @At("TAIL")) | ||
private void assignSlimeChunk3(World world, ChunkPos pos, UpgradeData upgradeData, ChunkTickScheduler blockTickScheduler, ChunkTickScheduler fluidTickScheduler, long inhabitedTime, ChunkSection[] sectionArrayInitializer, WorldChunk.EntityLoader entityLoader, BlendingData blendingData, CallbackInfo ci) { | ||
setSlimeChunk(world, pos); | ||
} | ||
|
||
@Override | ||
public boolean isSlimeChunk() { | ||
return slimeChunk; | ||
} | ||
|
||
private void setSlimeChunk(World world, ChunkPos pos) { | ||
if (world instanceof StructureWorldAccess) { | ||
Random random = ChunkRandom.getSlimeRandom(pos.x, pos.z, ((StructureWorldAccess)world).getSeed(), 987234911L); | ||
slimeChunk = random.nextInt(10) == 0; | ||
} else { | ||
slimeChunk = false; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.