mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-25 18:09:17 +00:00
Configurable spawner block settings (#251)
* custom SpawnerSettings * [ci/skip] cleanup * [ci/skip] cleanup * Use vanilla min/max spawn delay as default values * Move config to gameplay
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Taiyou06 <kaandindar21@gmail.com>
|
||||
Date: Sun, 9 Mar 2025 00:36:26 +0100
|
||||
Subject: [PATCH] Spawner Configurations
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/BaseSpawner.java b/net/minecraft/world/level/BaseSpawner.java
|
||||
index 8c6f8cb08b247dcf497822ae991aa3afbcb784f1..9df9f4308c717db523d3c58e4d8dab7437984d02 100644
|
||||
--- a/net/minecraft/world/level/BaseSpawner.java
|
||||
+++ b/net/minecraft/world/level/BaseSpawner.java
|
||||
@@ -53,6 +53,12 @@ public abstract class BaseSpawner {
|
||||
|
||||
public boolean isNearPlayer(Level level, BlockPos pos) {
|
||||
if (level.purpurConfig.spawnerDeactivateByRedstone && level.hasNeighborSignal(pos)) return false; // Purpur - Redstone deactivates spawners
|
||||
+ // Leaf start - Spawner Configurations
|
||||
+ // Skip player proximity check if disabled in config
|
||||
+ if (org.dreeam.leaf.config.modules.gameplay.SpawnerSettings.enabled && !org.dreeam.leaf.config.modules.gameplay.SpawnerSettings.checkForNearbyPlayers) {
|
||||
+ return true; // Always act as if players are nearby
|
||||
+ }
|
||||
+ // Leaf end - Spawner Configurations
|
||||
return level.hasNearbyAlivePlayerThatAffectsSpawningForSpawner(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, this.requiredPlayerRange); // Paper - Affects Spawning API // Leaf - Optimize nearby alive players for spawning
|
||||
}
|
||||
|
||||
@@ -75,6 +81,20 @@ public abstract class BaseSpawner {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Leaf start - Spawner Configurations
|
||||
+ private int maxAllowedLight(EntityType<?> entityType) {
|
||||
+ if (entityType.getCategory().isFriendly()) {
|
||||
+ return 15; // No light restriction for passive mobs
|
||||
+ } else if (entityType == EntityType.SPIDER || entityType == EntityType.CAVE_SPIDER) {
|
||||
+ return 7; // Spiders can spawn in light level 7 or lower
|
||||
+ } else if (entityType == EntityType.ENDERMAN) {
|
||||
+ return 7; // Endermen can spawn in light level 7 or lower
|
||||
+ }
|
||||
+
|
||||
+ return 0; // Complete darkness for other hostile mobs
|
||||
+ }
|
||||
+ // Leaf end - Spawner Configurations
|
||||
+
|
||||
public void serverTick(ServerLevel serverLevel, BlockPos pos) {
|
||||
if (spawnCount <= 0 || maxNearbyEntities <= 0) return; // Paper - Ignore impossible spawn tick
|
||||
// Paper start - Configurable mob spawner tick rate
|
||||
@@ -82,6 +102,15 @@ public abstract class BaseSpawner {
|
||||
tickDelay = serverLevel.paperConfig().tickRates.mobSpawner;
|
||||
if (tickDelay == -1) { return; } // If disabled
|
||||
// Paper end - Configurable mob spawner tick rate
|
||||
+
|
||||
+ // Leaf start - Spawner Configurations
|
||||
+ // Apply custom min/max spawn delays if enabled
|
||||
+ if (org.dreeam.leaf.config.modules.gameplay.SpawnerSettings.enabled) {
|
||||
+ this.minSpawnDelay = org.dreeam.leaf.config.modules.gameplay.SpawnerSettings.minSpawnDelay;
|
||||
+ this.maxSpawnDelay = org.dreeam.leaf.config.modules.gameplay.SpawnerSettings.maxSpawnDelay;
|
||||
+ }
|
||||
+ // Leaf end - Spawner Configurations
|
||||
+
|
||||
if (this.isNearPlayer(serverLevel, pos)) {
|
||||
if (this.spawnDelay < -tickDelay) { // Paper - Configurable mob spawner tick rate
|
||||
this.delay(serverLevel, pos);
|
||||
@@ -107,18 +136,43 @@ public abstract class BaseSpawner {
|
||||
double d = size >= 1 ? list.getDouble(0) : pos.getX() + (random.nextDouble() - random.nextDouble()) * this.spawnRange + 0.5;
|
||||
double d1 = size >= 2 ? list.getDouble(1) : pos.getY() + random.nextInt(3) - 1;
|
||||
double d2 = size >= 3 ? list.getDouble(2) : pos.getZ() + (random.nextDouble() - random.nextDouble()) * this.spawnRange + 0.5;
|
||||
- if (serverLevel.noCollision(optional.get().getSpawnAABB(d, d1, d2))) {
|
||||
+
|
||||
+ // Leaf start - Spawner Configurations
|
||||
+ // Skip collision check if block checks are disabled
|
||||
+ boolean skipBlockChecks = org.dreeam.leaf.config.modules.gameplay.SpawnerSettings.enabled &&
|
||||
+ !org.dreeam.leaf.config.modules.gameplay.SpawnerSettings.spawnerBlockChecks;
|
||||
+ if (skipBlockChecks || serverLevel.noCollision(optional.get().getSpawnAABB(d, d1, d2))) {
|
||||
BlockPos blockPos = BlockPos.containing(d, d1, d2);
|
||||
+
|
||||
+ // Add light level check if enabled
|
||||
+ if (org.dreeam.leaf.config.modules.gameplay.SpawnerSettings.enabled &&
|
||||
+ org.dreeam.leaf.config.modules.gameplay.SpawnerSettings.lightLevelCheck) {
|
||||
+ int lightLevel = serverLevel.getMaxLocalRawBrightness(blockPos);
|
||||
+ if (lightLevel > maxAllowedLight(optional.get())) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Add water check if enabled
|
||||
+ if (org.dreeam.leaf.config.modules.gameplay.SpawnerSettings.enabled &&
|
||||
+ org.dreeam.leaf.config.modules.gameplay.SpawnerSettings.waterPreventSpawnCheck &&
|
||||
+ serverLevel.getBlockState(blockPos).getFluidState().is(net.minecraft.tags.FluidTags.WATER)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ // Handle spawn rules checks
|
||||
+ boolean skipSpawnRules = false;
|
||||
+ // Leaf end - Spawner Configurations
|
||||
if (nextSpawnData.getCustomSpawnRules().isPresent()) {
|
||||
if (!optional.get().getCategory().isFriendly() && serverLevel.getDifficulty() == Difficulty.PEACEFUL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SpawnData.CustomSpawnRules customSpawnRules = nextSpawnData.getCustomSpawnRules().get();
|
||||
- if (!customSpawnRules.isValidPosition(blockPos, serverLevel)) {
|
||||
+ if (!skipBlockChecks && !customSpawnRules.isValidPosition(blockPos, serverLevel)) { // Leaf - Spawner Configurations
|
||||
continue;
|
||||
}
|
||||
- } else if (!SpawnPlacements.checkSpawnRules(optional.get(), serverLevel, EntitySpawnReason.SPAWNER, blockPos, serverLevel.getRandom())) {
|
||||
+ } else if (!skipBlockChecks && !SpawnPlacements.checkSpawnRules(optional.get(), serverLevel, EntitySpawnReason.SPAWNER, blockPos, serverLevel.getRandom())) { // Leaf - Spawner Configurations
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -146,6 +200,7 @@ public abstract class BaseSpawner {
|
||||
return;
|
||||
}
|
||||
|
||||
+ if (!org.dreeam.leaf.config.modules.gameplay.SpawnerSettings.enabled || org.dreeam.leaf.config.modules.gameplay.SpawnerSettings.spawnerMaxNearbyCheck) { // Leaf - Spawner Configurations - Skip max nearby entity check if disabled
|
||||
int size1 = serverLevel.getEntities(
|
||||
EntityTypeTest.forExactClass(entity.getClass()),
|
||||
new AABB(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1).inflate(this.spawnRange),
|
||||
@@ -156,12 +211,16 @@ public abstract class BaseSpawner {
|
||||
this.delay(serverLevel, pos);
|
||||
return;
|
||||
}
|
||||
+ } // Leaf - Spawner Configurations
|
||||
|
||||
entity.preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported; preserve entity motion from tag
|
||||
entity.moveTo(entity.getX(), entity.getY(), entity.getZ(), random.nextFloat() * 360.0F, 0.0F);
|
||||
if (entity instanceof Mob mob) {
|
||||
- if (nextSpawnData.getCustomSpawnRules().isEmpty() && !mob.checkSpawnRules(serverLevel, EntitySpawnReason.SPAWNER)
|
||||
- || !mob.checkSpawnObstruction(serverLevel)) {
|
||||
+ // Leaf start - Spawner Configurations
|
||||
+ // Skip spawn rule and obstruction checks if block checks are disabled
|
||||
+ if (!skipBlockChecks && (nextSpawnData.getCustomSpawnRules().isEmpty() && !mob.checkSpawnRules(serverLevel, EntitySpawnReason.SPAWNER)
|
||||
+ || !mob.checkSpawnObstruction(serverLevel))) {
|
||||
+ // Leaf end - Spawner Configurations
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -249,6 +308,13 @@ public abstract class BaseSpawner {
|
||||
this.spawnPotentials = SimpleWeightedRandomList.single(this.nextSpawnData != null ? this.nextSpawnData : new SpawnData());
|
||||
}
|
||||
|
||||
+ // Leaf start - Spawner Configurations
|
||||
+ if (org.dreeam.leaf.config.modules.gameplay.SpawnerSettings.enabled) {
|
||||
+ this.minSpawnDelay = org.dreeam.leaf.config.modules.gameplay.SpawnerSettings.minSpawnDelay;
|
||||
+ this.maxSpawnDelay = org.dreeam.leaf.config.modules.gameplay.SpawnerSettings.maxSpawnDelay;
|
||||
+ this.spawnCount = tag.getShort("SpawnCount");
|
||||
+ } else
|
||||
+ // Leaf end - Spawner Configurations
|
||||
// Paper start - use ints if set
|
||||
if (tag.contains("Paper.MinSpawnDelay", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC)) {
|
||||
this.minSpawnDelay = tag.getInt("Paper.MinSpawnDelay");
|
||||
@@ -0,0 +1,87 @@
|
||||
package org.dreeam.leaf.config.modules.gameplay;
|
||||
|
||||
import org.dreeam.leaf.config.ConfigModules;
|
||||
import org.dreeam.leaf.config.EnumConfigCategory;
|
||||
|
||||
public class SpawnerSettings extends ConfigModules {
|
||||
|
||||
public String getBasePath() {
|
||||
return EnumConfigCategory.GAMEPLAY.getBaseKeyName() + ".spawner-settings";
|
||||
}
|
||||
|
||||
// Global toggle
|
||||
public static boolean enabled = false;
|
||||
|
||||
// Default values for spawner settings
|
||||
public static boolean lightLevelCheck = false;
|
||||
public static boolean spawnerMaxNearbyCheck = true;
|
||||
public static boolean checkForNearbyPlayers = true;
|
||||
public static boolean spawnerBlockChecks = false;
|
||||
public static boolean waterPreventSpawnCheck = false;
|
||||
|
||||
public static int minSpawnDelay = 200;
|
||||
public static int maxSpawnDelay = 800;
|
||||
|
||||
@Override
|
||||
public void onLoaded() {
|
||||
config.addCommentRegionBased(getBasePath(),
|
||||
"This section contains settings for mob spawner blocks.",
|
||||
"此部分包含刷怪笼生物生成的设置.");
|
||||
|
||||
// Global toggle
|
||||
enabled = config.getBoolean(getBasePath() + ".enabled", enabled,
|
||||
config.pickStringRegionBased(
|
||||
"Enable custom spawner settings. Set to true to enable all features below.",
|
||||
"启用自定义刷怪笼设置. 设为 true 以启用以下所有功能."
|
||||
));
|
||||
|
||||
// Checks section
|
||||
config.addCommentRegionBased(getBasePath() + ".checks",
|
||||
"Various checks that can be enabled or disabled for spawner blocks.",
|
||||
"可以为刷怪笼启用或禁用的各种检查.");
|
||||
|
||||
lightLevelCheck = config.getBoolean(getBasePath() + ".checks.light-level-check", lightLevelCheck,
|
||||
config.pickStringRegionBased(
|
||||
"Check if there is the required light level to spawn the mob",
|
||||
"检查是否有所需的光照等级来生成怪物"
|
||||
));
|
||||
|
||||
spawnerMaxNearbyCheck = config.getBoolean(getBasePath() + ".checks.spawner-max-nearby-check", spawnerMaxNearbyCheck,
|
||||
config.pickStringRegionBased(
|
||||
"Check if there are the max amount of nearby mobs to spawn the mob",
|
||||
"检查附近是否已达到最大怪物数量限制"
|
||||
));
|
||||
|
||||
checkForNearbyPlayers = config.getBoolean(getBasePath() + ".checks.check-for-nearby-players", checkForNearbyPlayers,
|
||||
config.pickStringRegionBased(
|
||||
"Check if any players are in a radius to spawn the mob",
|
||||
"检查是否有玩家在生成怪物的半径范围内"
|
||||
));
|
||||
|
||||
spawnerBlockChecks = config.getBoolean(getBasePath() + ".checks.spawner-block-checks", spawnerBlockChecks,
|
||||
config.pickStringRegionBased(
|
||||
"Check if there are blocks blocking the spawner to spawn the mob",
|
||||
"检查是否有方块阻挡刷怪笼生成怪物"
|
||||
));
|
||||
|
||||
waterPreventSpawnCheck = config.getBoolean(getBasePath() + ".checks.water-prevent-spawn-check", waterPreventSpawnCheck,
|
||||
config.pickStringRegionBased(
|
||||
"Checks if there is water around that prevents spawning",
|
||||
"检查周围是否有水阻止生成"
|
||||
));
|
||||
|
||||
// Delay settings
|
||||
|
||||
minSpawnDelay = config.getInt(getBasePath() + ".min-spawn-delay", minSpawnDelay,
|
||||
config.pickStringRegionBased(
|
||||
"Minimum delay (in ticks) between spawner spawns. Higher values slow down spawners.",
|
||||
"刷怪笼生成怪物之间的最小延迟 (以刻为单位). 较高的值会减缓刷怪笼的速度."
|
||||
));
|
||||
|
||||
maxSpawnDelay = config.getInt(getBasePath() + ".max-spawn-delay", maxSpawnDelay,
|
||||
config.pickStringRegionBased(
|
||||
"Maximum delay (in ticks) between spawner spawns. Higher values slow down spawners.",
|
||||
"刷怪笼生成怪物之间的最大延迟 (以刻为单位). 较高的值会减缓刷怪笼的速度."
|
||||
));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user