Skip to content

Commit

Permalink
Update MixinPatchSpawnerAnimals
Browse files Browse the repository at this point in the history
  • Loading branch information
quentin452 committed Jan 20, 2024
1 parent aefbe0b commit f67b834
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.util.MathHelper;
import net.minecraft.world.ChunkPosition;
Expand All @@ -18,8 +19,10 @@
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Unique;

import static fr.iamacat.optimizationsandtweaks.utilsformods.vanilla.CreatureCountTask.optimizationsAndTweaks$canCreatureSpawnOnLand;
import static fr.iamacat.optimizationsandtweaks.utilsformods.vanilla.CreatureCountTask.optimizationsAndTweaks$eligibleChunksForSpawning;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

import static fr.iamacat.optimizationsandtweaks.utilsformods.vanilla.CreatureCountTask.*;

@Mixin(value = SpawnerAnimals.class, priority = 999)
public class MixinPatchSpawnerAnimals {
Expand Down Expand Up @@ -59,6 +62,31 @@ public static boolean canCreatureTypeSpawnAtLocation(EnumCreatureType creatureTy
return optimizationsAndTweaks$canCreatureSpawnOnLand(creatureType, world, x, y, z, block, world.getBlock(x, y + 1, z));
}

@Unique
private static boolean optimizationsAndTweaks$isNormalCube(Block block) {
return block.isNormalCube();
}
@Unique
private static boolean optimizationsAndTweaks$doesBlockHaveSolidTopSurface(World world, int x, int y, int z) {
return World.doesBlockHaveSolidTopSurface(world, x, y, z);
}

@Unique
private static boolean optimizationsAndTweaks$canCreatureSpawnOnLand(EnumCreatureType creatureType, World world, int x, int y, int z, Block block, Block blockAbove) {
if (!optimizationsAndTweaks$doesBlockHaveSolidTopSurface(world, x, y - 1, z)) {
return false;
}
boolean isPeacefulCreature = creatureType.getPeacefulCreature();
boolean isAnimal = creatureType.getAnimal();
if ((!isPeacefulCreature || isAnimal) && optimizationsAndTweaks$shouldSpawnCreature(creatureType, world, optimizationsAndTweaks$eligibleChunksForSpawning)) {
for (int spawnAttempt = 0; spawnAttempt < creatureType.getMaxNumberOfCreature(); spawnAttempt++) {
if (block != Blocks.bedrock && !optimizationsAndTweaks$isNormalCube(blockAbove) && !blockAbove.getMaterial().isLiquid()) {
return true;
}
}
}
return false;
}
@Unique
private static boolean optimizationsAndTweaks$canCreatureSpawnInWater(Block block, Block blockBelow, Block blockAbove) {
Material blockMaterial = block.getMaterial();
Expand All @@ -72,7 +100,7 @@ public static boolean canCreatureTypeSpawnAtLocation(EnumCreatureType creatureTy
* @reason optimize findChunksForSpawning
*/
@Overwrite
public int findChunksForSpawning(WorldServer world, boolean peaceful, boolean hostile, boolean animals) {
public int findChunksForSpawning(WorldServer world, boolean peaceful, boolean hostile, boolean animals) throws ExecutionException, InterruptedException {
if (!peaceful && !hostile) {
return 0;
}
Expand All @@ -81,14 +109,14 @@ public int findChunksForSpawning(WorldServer world, boolean peaceful, boolean ho
optimizationsAndTweaks$populateEligibleChunks(world);

int spawnedEntities = 0;
ChunkCoordinates spawnPoint = world.getSpawnPoint();
CompletableFuture<ChunkCoordinates> spawnPoint = optimizationsAndTweaks$getSpawnPoint(world);

for (EnumCreatureType creatureType : EnumCreatureType.values()) {
if (optimizationsAndTweaks$shouldSpawnCreatureType(creatureType, world, peaceful, hostile, animals)) {
for (Object chunkCoord : optimizationsAndTweaks$eligibleChunksForSpawning.keySet()) {
Boolean isChunkEligible = (Boolean) optimizationsAndTweaks$eligibleChunksForSpawning.get(chunkCoord);
if (isChunkEligible != null && !isChunkEligible) {
spawnedEntities += optimizationsAndTweaks$spawnEntitiesInChunk(world, creatureType, (ChunkCoordinates) chunkCoord, spawnPoint);
spawnedEntities = optimizationsAndTweaks$spawnEntitiesInChunk(world, creatureType, (ChunkCoordinates) chunkCoord, spawnPoint.get());
}
}
}
Expand Down Expand Up @@ -139,8 +167,7 @@ public int findChunksForSpawning(WorldServer world, boolean peaceful, boolean ho
// todo fix Entity is already tracked! errors while refactoring the method into smaller methods
// why i want to refactor this method into smallers : because for maintanibility, detecting performances bottlenecks
@Unique
private int optimizationsAndTweaks$spawnEntitiesInChunk(WorldServer world, EnumCreatureType creatureType, ChunkCoordinates chunkCoord,
ChunkCoordinates spawnPoint) {
private int optimizationsAndTweaks$spawnEntitiesInChunk(WorldServer world, EnumCreatureType creatureType, ChunkCoordinates chunkCoord, ChunkCoordinates spawnPoint) {
ChunkPosition chunkPosition = func_151350_a(world, chunkCoord.posX, chunkCoord.posZ);

int spawnedEntities = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@
import net.minecraft.entity.Entity;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.init.Blocks;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.util.MathHelper;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import org.spongepowered.asm.mixin.Unique;

import java.util.Iterator;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;

public class CreatureCountTask implements Runnable {
Expand Down Expand Up @@ -40,7 +44,10 @@ public CreatureCountTask(EnumCreatureType creatureType, World world, Object2Obje
@Override
public void run() {
int totalCreatureCount = 0;
assert creatureType != null;
assert eligibleChunks != null;
int maxCreatureCount = optimizationsAndTweaks$getMaxCreatureCount(creatureType, eligibleChunks);
assert world != null;
Iterator<?> entityIterator = world.loadedEntityList.iterator();
Class<?> creatureClass = Objects.requireNonNull(creatureType.getCreatureClass());

Expand Down Expand Up @@ -78,30 +85,12 @@ public int getTotalCreatureCount() {
threadStarted = true;
}

try {
countThread.join(500);
} catch (InterruptedException e) {
e.printStackTrace();
}

int totalCreatureCount = new CreatureCountTask(creatureType, world, eligibleChunks, new AtomicInteger()).getTotalCreatureCount();
int maxCreatureCount = optimizationsAndTweaks$getMaxCreatureCount(creatureType, eligibleChunks);
return totalCreatureCount <= maxCreatureCount;
}

public static boolean optimizationsAndTweaks$canCreatureSpawnOnLand(EnumCreatureType creatureType, World world, int x, int y, int z, Block block, Block blockAbove) {
if (!World.doesBlockHaveSolidTopSurface(world, x, y - 1, z)) {
return false;
}
boolean isPeacefulCreature = creatureType.getPeacefulCreature();
boolean isAnimal = creatureType.getAnimal();
if ((!isPeacefulCreature || isAnimal) && optimizationsAndTweaks$shouldSpawnCreature(creatureType, world, optimizationsAndTweaks$eligibleChunksForSpawning)) {
for (int spawnAttempt = 0; spawnAttempt < creatureType.getMaxNumberOfCreature(); spawnAttempt++) {
if (block != Blocks.bedrock && !blockAbove.isNormalCube() && !blockAbove.getMaterial().isLiquid()) {
return true;
}
}
}
return false;
@Unique
public static CompletableFuture<ChunkCoordinates> optimizationsAndTweaks$getSpawnPoint(WorldServer world) {
return CompletableFuture.supplyAsync(world::getSpawnPoint);
}
}

0 comments on commit f67b834

Please sign in to comment.