From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sat, 22 Aug 2020 20:47:11 -0700 Subject: [PATCH] Allow toggling special MobSpawners per world In vanilla, these are all hardcoded on for world type 0 (overworld) and hardcoded off for every other world type. Default config behaviour matches this. diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java index 0ef7b405ad9174045128fb5445f0bc0e22a3f2e2..d10ebe9b094a0e8b62e6607a4fefaf0bcd412413 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -83,6 +83,7 @@ import net.minecraft.world.entity.MobCategory; import net.minecraft.world.entity.ReputationEventHandler; import net.minecraft.world.entity.ai.navigation.PathNavigation; import net.minecraft.world.entity.ai.village.ReputationEventType; +import net.minecraft.world.entity.ai.village.VillageSiege; import net.minecraft.world.entity.ai.village.poi.PoiManager; import net.minecraft.world.entity.ai.village.poi.PoiType; import net.minecraft.world.entity.animal.Animal; @@ -91,7 +92,9 @@ import net.minecraft.world.entity.animal.horse.AbstractHorse; import net.minecraft.world.entity.animal.horse.SkeletonHorse; import net.minecraft.world.entity.boss.EnderDragonPart; import net.minecraft.world.entity.boss.enderdragon.EnderDragon; +import net.minecraft.world.entity.npc.CatSpawner; import net.minecraft.world.entity.npc.Npc; +import net.minecraft.world.entity.npc.WanderingTraderSpawner; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.raid.Raid; import net.minecraft.world.entity.raid.Raids; @@ -132,6 +135,8 @@ import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.level.gameevent.GameEventListenerRegistrar; import net.minecraft.world.level.gameevent.vibrations.VibrationPath; import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.PatrolSpawner; +import net.minecraft.world.level.levelgen.PhantomSpawner; import net.minecraft.world.level.levelgen.feature.StructureFeature; import net.minecraft.world.level.levelgen.structure.BoundingBox; import net.minecraft.world.level.levelgen.structure.StructureStart; @@ -341,7 +346,24 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl this.dragonParts = new Int2ObjectOpenHashMap(); this.tickTime = flag1; this.server = minecraftserver; - this.customSpawners = list; + // Purpur start - enable/disable MobSpawners per world + this.customSpawners = Lists.newArrayList(); + if (purpurConfig.phantomSpawning) { + customSpawners.add(new PhantomSpawner()); + } + if (purpurConfig.patrolSpawning) { + customSpawners.add(new PatrolSpawner()); + } + if (purpurConfig.catSpawning) { + customSpawners.add(new CatSpawner()); + } + if (purpurConfig.villageSiegeSpawning) { + customSpawners.add(new VillageSiege()); + } + if (purpurConfig.villagerTraderSpawning) { + customSpawners.add(new WanderingTraderSpawner(iworlddataserver)); + } + // Purpur end // CraftBukkit start this.serverLevelData = (PrimaryLevelData) iworlddataserver; serverLevelData.world = this; diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java index f8ede3588bfda9a7d4d5807311a3e9c2651fd0a3..56967cef0f184def046935e20148574f24524f44 100644 --- a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java +++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java @@ -5,6 +5,7 @@ import java.util.Optional; import java.util.Random; import javax.annotation.Nullable; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; @@ -160,7 +161,17 @@ public class WanderingTraderSpawner implements CustomSpawner { int k = pos.getX() + this.random.nextInt(range * 2) - range; int l = pos.getZ() + this.random.nextInt(range * 2) - range; int i1 = world.getHeight(Heightmap.Types.WORLD_SURFACE, k, l); - BlockPos blockposition2 = new BlockPos(k, i1, l); + // Purpur start - allow traders to spawn below nether roof + BlockPos.MutableBlockPos blockposition2 = new BlockPos.MutableBlockPos(k, i1, l); + if (world.dimensionType().hasCeiling()) { + do { + blockposition2.relative(Direction.DOWN); + } while (!world.getBlockState(blockposition2).isAir()); + do { + blockposition2.relative(Direction.DOWN); + } while (world.getBlockState(blockposition2).isAir() && blockposition2.getY() > 0); + } + // Purpur end if (NaturalSpawner.isSpawnPositionOk(SpawnPlacements.Type.ON_GROUND, world, blockposition2, EntityType.WANDERING_TRADER)) { blockposition1 = blockposition2; diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java index 1f9129180badb6df786b080edf926d04ef95125c..917a671894e16e024db941cea1845e39eaf93ef8 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -200,7 +200,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, final DimensionType dimensionmanager, Supplier supplier, boolean flag, boolean flag1, long i, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env, java.util.concurrent.Executor executor) { // Paper this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName(), this.spigotConfig); // Paper - this.purpurConfig = new net.pl3x.purpur.PurpurWorldConfig((((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName())); // Purpur + this.purpurConfig = new net.pl3x.purpur.PurpurWorldConfig((((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()), env); // Purpur this.generator = gen; this.world = new CraftWorld((ServerLevel) this, gen, env); this.ticksPerAnimalSpawns = this.getCraftServer().getTicksPerAnimalSpawns(); // CraftBukkit diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java index 9825fe8dd51f5dda74f6645f0ea78ee22746366e..ea1e7d9c917762457ecb8b22bcf790cdbe674da7 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java @@ -8,6 +8,8 @@ import net.minecraft.world.level.Explosion; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; +import org.apache.commons.lang.BooleanUtils; +import org.bukkit.World; import org.bukkit.configuration.ConfigurationSection; import java.util.ArrayList; @@ -16,6 +18,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.Predicate; import java.util.logging.Level; import static net.pl3x.purpur.PurpurConfig.log; @@ -23,9 +26,11 @@ import static net.pl3x.purpur.PurpurConfig.log; public class PurpurWorldConfig { private final String worldName; + private final World.Environment environment; - public PurpurWorldConfig(String worldName) { + public PurpurWorldConfig(String worldName, World.Environment environment) { this.worldName = worldName; + this.environment = environment; init(); } @@ -53,6 +58,12 @@ public class PurpurWorldConfig { return PurpurConfig.config.getBoolean("world-settings." + worldName + "." + path, PurpurConfig.config.getBoolean("world-settings.default." + path)); } + private boolean getBoolean(String path, Predicate predicate) { + String val = getString(path, "default").toLowerCase(); + Boolean bool = BooleanUtils.toBooleanObject(val, "true", "false", "default"); + return predicate.test(bool); + } + private double getDouble(String path, double def) { PurpurConfig.config.addDefault("world-settings.default." + path, def); return PurpurConfig.config.getDouble("world-settings." + worldName + "." + path, PurpurConfig.config.getDouble("world-settings.default." + path)); @@ -201,6 +212,21 @@ public class PurpurWorldConfig { } } + public boolean catSpawning; + public boolean patrolSpawning; + public boolean phantomSpawning; + public boolean villagerTraderSpawning; + public boolean villageSiegeSpawning; + private void mobSpawnerSettings() { + // values of "default" or null will default to true only if the world environment is normal (aka overworld) + Predicate predicate = (bool) -> (bool != null && bool) || (bool == null && environment == World.Environment.NORMAL); + catSpawning = getBoolean("gameplay-mechanics.mob-spawning.village-cats", predicate); + patrolSpawning = getBoolean("gameplay-mechanics.mob-spawning.raid-patrols", predicate); + phantomSpawning = getBoolean("gameplay-mechanics.mob-spawning.phantoms", predicate); + villagerTraderSpawning = getBoolean("gameplay-mechanics.mob-spawning.wandering-traders", predicate); + villageSiegeSpawning = getBoolean("gameplay-mechanics.mob-spawning.village-sieges", predicate); + } + public boolean idleTimeoutKick = true; public boolean idleTimeoutTickNearbyEntities = true; public boolean idleTimeoutCountAsSleeping = false;