100 lines
2.9 KiB
Java
100 lines
2.9 KiB
Java
package net.Chipperfluff.chipi.entity;
|
|
|
|
import net.fabricmc.fabric.api.biome.v1.BiomeModifications;
|
|
import net.fabricmc.fabric.api.biome.v1.BiomeSelectors;
|
|
|
|
import net.minecraft.block.BlockState;
|
|
import net.minecraft.block.Blocks;
|
|
import net.minecraft.entity.EntityType;
|
|
import net.minecraft.entity.SpawnGroup;
|
|
import net.minecraft.entity.SpawnReason;
|
|
import net.minecraft.entity.SpawnRestriction;
|
|
import net.minecraft.entity.mob.MobEntity;
|
|
import net.minecraft.registry.RegistryKey;
|
|
import net.minecraft.registry.RegistryKeys;
|
|
import net.minecraft.util.Identifier;
|
|
import net.minecraft.util.math.BlockPos;
|
|
import net.minecraft.util.math.random.Random;
|
|
import net.minecraft.world.Heightmap;
|
|
import net.minecraft.world.ServerWorldAccess;
|
|
import net.minecraft.world.biome.Biome;
|
|
import net.minecraft.entity.player.PlayerEntity;
|
|
import net.minecraft.util.math.Box;
|
|
|
|
|
|
public final class SpawnLogic {
|
|
|
|
private static final int MAX_MEPS = 60;
|
|
private static final int SPAWN_RADIUS = 150;
|
|
|
|
private static final RegistryKey<Biome> VOID_BIOME =
|
|
RegistryKey.of(RegistryKeys.BIOME, new Identifier("chipi", "void"));
|
|
|
|
private SpawnLogic() {
|
|
}
|
|
|
|
public static void register() {
|
|
|
|
BiomeModifications.addSpawn(
|
|
BiomeSelectors.includeByKey(VOID_BIOME),
|
|
SpawnGroup.MONSTER,
|
|
ModEntities.MEP,
|
|
1,
|
|
1,
|
|
4
|
|
);
|
|
|
|
SpawnRestriction.register(
|
|
ModEntities.MEP,
|
|
SpawnRestriction.Location.ON_GROUND,
|
|
Heightmap.Type.MOTION_BLOCKING_NO_LEAVES,
|
|
SpawnLogic::canSpawn
|
|
);
|
|
}
|
|
|
|
private static boolean canSpawn(
|
|
EntityType<? extends MobEntity> type,
|
|
ServerWorldAccess world,
|
|
SpawnReason reason,
|
|
BlockPos pos,
|
|
Random random
|
|
) {
|
|
// --- HEIGHT & Z RULES ---
|
|
int y = pos.getY();
|
|
if (y < 87 || y > 90) return false;
|
|
if (pos.getZ() < 18) return false;
|
|
|
|
// --- BLOCK CHECK ---
|
|
BlockState below = world.getBlockState(pos.down());
|
|
if (!below.isOf(Blocks.POLISHED_BLACKSTONE_BRICKS)) return false;
|
|
|
|
// --- GLOBAL CAP (DENY SPAWN, DO NOT DESPAWN) ---
|
|
int mepCount = world.getEntitiesByClass(
|
|
MepEntity.class,
|
|
new Box(
|
|
pos.getX() - 512, pos.getY() - 512, pos.getZ() - 512,
|
|
pos.getX() + 512, pos.getY() + 512, pos.getZ() + 512
|
|
),
|
|
e -> true
|
|
).size();
|
|
|
|
if (mepCount >= MAX_MEPS) return false;
|
|
|
|
// --- PLAYER PROXIMITY ---
|
|
double maxSq = SPAWN_RADIUS * SPAWN_RADIUS;
|
|
|
|
for (PlayerEntity player : world.getPlayers()) {
|
|
if (player.squaredDistanceTo(
|
|
pos.getX() + 0.5,
|
|
pos.getY(),
|
|
pos.getZ() + 0.5
|
|
) <= maxSq) {
|
|
return true; // ✔ valid spawn
|
|
}
|
|
}
|
|
|
|
// No nearby player → no spawn
|
|
return false;
|
|
}
|
|
}
|