mirror of
https://github.com/PurpurMC/Purpur.git
synced 2026-02-17 16:37:43 +01:00
Upstream has released updates that appear to apply and compile correctly Paper Changes: 9a129fa99 Add #getEligibleHumans to SkeletonHorseTrapEvent b5e23c7a6 Fix merging spawning values a932e8ad7 Turn off spigot verbose world by default 8ced89f65 Fix Delegation to vanilla chunk gen
286 lines
16 KiB
Diff
286 lines
16 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
|
Date: Fri, 3 Jul 2020 00:03:52 -0500
|
|
Subject: [PATCH] Add phantom spawning options
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/DifficultyDamageScaler.java b/src/main/java/net/minecraft/server/DifficultyDamageScaler.java
|
|
index 75745af343..84c0ec1b50 100644
|
|
--- a/src/main/java/net/minecraft/server/DifficultyDamageScaler.java
|
|
+++ b/src/main/java/net/minecraft/server/DifficultyDamageScaler.java
|
|
@@ -13,6 +13,7 @@ public class DifficultyDamageScaler {
|
|
this.b = this.a(enumdifficulty, i, j, f);
|
|
}
|
|
|
|
+ public EnumDifficulty getGlobalDifficulty() { return a(); } // Purpur - OBFHELPER
|
|
public EnumDifficulty a() {
|
|
return this.a;
|
|
}
|
|
@@ -21,6 +22,7 @@ public class DifficultyDamageScaler {
|
|
return this.b;
|
|
}
|
|
|
|
+ public boolean isHarderThan(float f) { return a(f); } // Purpur - OBFHELPER
|
|
public boolean a(float f) {
|
|
return this.b > f;
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/EnumDifficulty.java b/src/main/java/net/minecraft/server/EnumDifficulty.java
|
|
index e0e72779c0..386eae71a1 100644
|
|
--- a/src/main/java/net/minecraft/server/EnumDifficulty.java
|
|
+++ b/src/main/java/net/minecraft/server/EnumDifficulty.java
|
|
@@ -19,6 +19,7 @@ public enum EnumDifficulty {
|
|
this.g = s;
|
|
}
|
|
|
|
+ public int getId() { return a(); } // Purpur - OBFHELPER
|
|
public int a() {
|
|
return this.f;
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/IBlockLightAccess.java b/src/main/java/net/minecraft/server/IBlockLightAccess.java
|
|
index 03a89301f2..fa5eb188da 100644
|
|
--- a/src/main/java/net/minecraft/server/IBlockLightAccess.java
|
|
+++ b/src/main/java/net/minecraft/server/IBlockLightAccess.java
|
|
@@ -12,6 +12,7 @@ public interface IBlockLightAccess extends IBlockAccess {
|
|
return this.e().b(blockposition, i);
|
|
}
|
|
|
|
+ default boolean isSkyVisible(BlockPosition blockposition) { return e(blockposition); } // Purpur - OBFHELPER
|
|
default boolean e(BlockPosition blockposition) {
|
|
return this.getBrightness(EnumSkyBlock.SKY, blockposition) >= this.K();
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/MobSpawnerPhantom.java b/src/main/java/net/minecraft/server/MobSpawnerPhantom.java
|
|
index 4e3f01bc79..ac1ea2f0c1 100644
|
|
--- a/src/main/java/net/minecraft/server/MobSpawnerPhantom.java
|
|
+++ b/src/main/java/net/minecraft/server/MobSpawnerPhantom.java
|
|
@@ -1,85 +1,99 @@
|
|
package net.minecraft.server;
|
|
|
|
-import java.util.Iterator;
|
|
-import java.util.Random;
|
|
+import com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent;
|
|
+import org.bukkit.event.entity.CreatureSpawnEvent;
|
|
|
|
public class MobSpawnerPhantom implements MobSpawner {
|
|
-
|
|
- private int a;
|
|
+ private int spawnDelay;
|
|
|
|
public MobSpawnerPhantom() {}
|
|
|
|
@Override
|
|
- public int a(WorldServer worldserver, boolean flag, boolean flag1) {
|
|
- if (!flag) {
|
|
+ public int a(WorldServer world, boolean allowMonsters, boolean allowAnimals) {
|
|
+ // Purpur start - rewrite entire thing
|
|
+ if (!allowMonsters) {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ if (!world.getGameRules().getBoolean(GameRules.DO_INSOMNIA)) {
|
|
return 0;
|
|
- } else if (!worldserver.getGameRules().getBoolean(GameRules.DO_INSOMNIA)) {
|
|
+ }
|
|
+
|
|
+ --this.spawnDelay;
|
|
+ if (this.spawnDelay > 0) {
|
|
return 0;
|
|
- } else {
|
|
- Random random = worldserver.random;
|
|
-
|
|
- --this.a;
|
|
- if (this.a > 0) {
|
|
- return 0;
|
|
- } else {
|
|
- this.a += (60 + random.nextInt(60)) * 20;
|
|
- if (worldserver.c() < 5 && worldserver.getDimensionManager().hasSkyLight()) {
|
|
- return 0;
|
|
- } else {
|
|
- int i = 0;
|
|
- Iterator iterator = worldserver.getPlayers().iterator();
|
|
-
|
|
- while (iterator.hasNext()) {
|
|
- EntityHuman entityhuman = (EntityHuman) iterator.next();
|
|
-
|
|
- if (!entityhuman.isSpectator() && (!worldserver.paperConfig.phantomIgnoreCreative || !entityhuman.isCreative())) { // Paper
|
|
- BlockPosition blockposition = entityhuman.getChunkCoordinates();
|
|
-
|
|
- if (!worldserver.getDimensionManager().hasSkyLight() || blockposition.getY() >= worldserver.getSeaLevel() && worldserver.e(blockposition)) {
|
|
- DifficultyDamageScaler difficultydamagescaler = worldserver.getDamageScaler(blockposition);
|
|
-
|
|
- if (difficultydamagescaler.a(random.nextFloat() * 3.0F)) {
|
|
- ServerStatisticManager serverstatisticmanager = ((EntityPlayer) entityhuman).getStatisticManager();
|
|
- int j = MathHelper.clamp(serverstatisticmanager.getStatisticValue(StatisticList.CUSTOM.b(StatisticList.TIME_SINCE_REST)), 1, Integer.MAX_VALUE);
|
|
- boolean flag2 = true;
|
|
-
|
|
- if (random.nextInt(j) >= 72000) {
|
|
- BlockPosition blockposition1 = blockposition.up(20 + random.nextInt(15)).east(-10 + random.nextInt(21)).south(-10 + random.nextInt(21));
|
|
- IBlockData iblockdata = worldserver.getType(blockposition1);
|
|
- Fluid fluid = worldserver.getFluid(blockposition1);
|
|
-
|
|
- if (SpawnerCreature.a((IBlockAccess) worldserver, blockposition1, iblockdata, fluid, EntityTypes.PHANTOM)) {
|
|
- GroupDataEntity groupdataentity = null;
|
|
- int k = 1 + random.nextInt(difficultydamagescaler.a().a() + 1);
|
|
-
|
|
- for (int l = 0; l < k; ++l) {
|
|
- // Paper start
|
|
- com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent event = new com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent(MCUtil.toLocation(worldserver, blockposition1), ((EntityPlayer) entityhuman).getBukkitEntity(), org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL);
|
|
- if (!event.callEvent()) {
|
|
- if (event.shouldAbortSpawn()) {
|
|
- break;
|
|
- }
|
|
- continue;
|
|
- }
|
|
- // Paper end
|
|
- EntityPhantom entityphantom = (EntityPhantom) EntityTypes.PHANTOM.a((World) worldserver);
|
|
- entityphantom.spawningEntity = entityhuman.uniqueID; // Paper
|
|
- entityphantom.setPositionRotation(blockposition1, 0.0F, 0.0F);
|
|
- groupdataentity = entityphantom.prepare(worldserver, difficultydamagescaler, EnumMobSpawn.NATURAL, groupdataentity, (NBTTagCompound) null);
|
|
- worldserver.addAllEntities(entityphantom, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBukkit
|
|
- }
|
|
-
|
|
- i += k;
|
|
- }
|
|
- }
|
|
- }
|
|
- }
|
|
- }
|
|
+ }
|
|
+ this.spawnDelay += world.purpurConfig.phantomSpawnDelayMin + world.random.nextInt(world.purpurConfig.phantomSpawnDelayMax - world.purpurConfig.phantomSpawnDelayMin);
|
|
+
|
|
+ if (!world.getDimensionManager().hasSkyLight() || world.getSkyDarkness() < world.purpurConfig.phantomSpawnMinSkyDarkness) {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ int numberSpawnsAttempted = 0;
|
|
+ for (EntityPlayer player : world.getPlayers()) {
|
|
+ if (player.isSpectator() || (player.isCreative() && world.paperConfig.phantomIgnoreCreative)) { // Paper
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ BlockPosition playerPos = player.getChunkCoordinates();
|
|
+ if (playerPos.getY() < world.getSeaLevel() && world.purpurConfig.phantomSpawnOnlyAboveSeaLevel) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ if (!world.isSkyVisible(playerPos) && world.purpurConfig.phantomSpawnOnlyWithVisibleSky) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ DifficultyDamageScaler dmgScaler = world.getDamageScaler(playerPos);
|
|
+ if (!dmgScaler.isHarderThan(world.random.nextFloat() * (float) world.purpurConfig.phantomSpawnLocalDifficultyChance)) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ ServerStatisticManager stats = player.getStatisticManager();
|
|
+ int timeSinceRest = MathHelper.clamp(stats.getStatisticValue(StatisticList.CUSTOM.get(StatisticList.TIME_SINCE_REST)), 1, Integer.MAX_VALUE);
|
|
+ if (world.random.nextInt(timeSinceRest) < world.purpurConfig.phantomSpawnMinTimeSinceSlept) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ BlockPosition spawnPos = playerPos
|
|
+ .up(world.purpurConfig.phantomSpawnMinOverhead + world.random.nextInt(world.purpurConfig.phantomSpawnMaxOverhead - world.purpurConfig.phantomSpawnMinOverhead))
|
|
+ .east(-world.purpurConfig.phantomSpawnOverheadRadius + world.random.nextInt(world.purpurConfig.phantomSpawnOverheadRadius + 1))
|
|
+ .south(-world.purpurConfig.phantomSpawnOverheadRadius + world.random.nextInt(world.purpurConfig.phantomSpawnOverheadRadius + 1));
|
|
+
|
|
+ if (!SpawnerCreature.canSpawn(world, spawnPos, world.getType(spawnPos), world.getFluid(spawnPos), EntityTypes.PHANTOM)) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ int difficulty = dmgScaler.getGlobalDifficulty().getId();
|
|
+ int spawnAttempts = world.purpurConfig.phantomSpawnMinPerAttempt + world.random.nextInt((world.purpurConfig.phantomSpawnMaxPerAttempt < 0 ? difficulty : world.purpurConfig.phantomSpawnMaxPerAttempt) + world.purpurConfig.phantomSpawnMinPerAttempt);
|
|
+
|
|
+ GroupDataEntity groupData = null;
|
|
+ for (int count = 0; count < spawnAttempts; ++count) {
|
|
+ // Paper start
|
|
+ PhantomPreSpawnEvent event = new PhantomPreSpawnEvent(MCUtil.toLocation(world, spawnPos), player.getBukkitEntity(), CreatureSpawnEvent.SpawnReason.NATURAL);
|
|
+ if (!event.callEvent()) {
|
|
+ if (event.shouldAbortSpawn()) {
|
|
+ break;
|
|
}
|
|
+ continue;
|
|
+ }
|
|
+ // Paper end
|
|
|
|
- return i;
|
|
+ EntityPhantom phantom = EntityTypes.PHANTOM.create(world);
|
|
+ if (phantom == null) {
|
|
+ continue;
|
|
}
|
|
+
|
|
+ phantom.spawningEntity = player.uniqueID; // Paper
|
|
+ phantom.setPositionRotation(spawnPos, 0.0F, 0.0F);
|
|
+ groupData = phantom.prepare(world, dmgScaler, EnumMobSpawn.NATURAL, groupData, null);
|
|
+ world.addEntity(phantom, CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBukkit
|
|
}
|
|
+
|
|
+ numberSpawnsAttempted += spawnAttempts;
|
|
}
|
|
+
|
|
+ return numberSpawnsAttempted;
|
|
+ // Purpur end - rewrite entire thing
|
|
}
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
index 661ad8f8e6..ee91c33a7a 100644
|
|
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
@@ -385,6 +385,7 @@ public final class SpawnerCreature {
|
|
return new BlockPosition(i, l, j);
|
|
}
|
|
|
|
+ public static boolean canSpawn(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, Fluid fluid, EntityTypes entitytypes) { return a(iblockaccess, blockposition, iblockdata, fluid, entitytypes); } // Purpur - OBFHELPER
|
|
public static boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, Fluid fluid, EntityTypes<?> entitytypes) {
|
|
return iblockdata.r(iblockaccess, blockposition) ? false : (iblockdata.isPowerSource() ? false : (!fluid.isEmpty() ? false : (iblockdata.a((Tag) TagsBlock.PREVENT_MOB_SPAWNING_INSIDE) ? false : !entitytypes.a(iblockdata))));
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
|
index ca4d260e8f..a8571dae8d 100644
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
|
@@ -1564,6 +1564,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
|
|
return new DifficultyDamageScaler(this.getDifficulty(), this.getDayTime(), i, f);
|
|
}
|
|
|
|
+ public int getSkyDarkness() { return c(); } // Purpur - OBFHELPER
|
|
@Override
|
|
public int c() {
|
|
return this.d;
|
|
diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
|
|
index f4362093f3..b4e19576ae 100644
|
|
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
|
|
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
|
|
@@ -335,10 +335,34 @@ public class PurpurWorldConfig {
|
|
public double phantomAttackedByCrystalRadius = 0.0D;
|
|
public float phantomAttackedByCrystalDamage = 1.0F;
|
|
public double phantomOrbitCrystalRadius = 0.0D;
|
|
+ public int phantomSpawnDelayMin = 1200;
|
|
+ public int phantomSpawnDelayMax = 2400;
|
|
+ public int phantomSpawnMinSkyDarkness = 5;
|
|
+ public boolean phantomSpawnOnlyAboveSeaLevel = true;
|
|
+ public boolean phantomSpawnOnlyWithVisibleSky = true;
|
|
+ public double phantomSpawnLocalDifficultyChance = 3.0D;
|
|
+ public int phantomSpawnMinTimeSinceSlept = 72000;
|
|
+ public int phantomSpawnMinOverhead = 20;
|
|
+ public int phantomSpawnMaxOverhead = 35;
|
|
+ public int phantomSpawnOverheadRadius = 10;
|
|
+ public int phantomSpawnMinPerAttempt = 1;
|
|
+ public int phantomSpawnMaxPerAttempt = -1;
|
|
private void phantomSettings() {
|
|
phantomAttackedByCrystalRadius = getDouble("mobs.phantom.attacked-by-crystal-range", phantomAttackedByCrystalRadius);
|
|
phantomAttackedByCrystalDamage = (float) getDouble("mobs.phantom.attacked-by-crystal-damage", phantomAttackedByCrystalDamage);
|
|
phantomOrbitCrystalRadius = getDouble("mobs.phantom.orbit-crystal-radius", phantomOrbitCrystalRadius);
|
|
+ phantomSpawnDelayMin = getInt("mobs.phantom.spawn.delay.min", phantomSpawnDelayMin);
|
|
+ phantomSpawnDelayMax = getInt("mobs.phantom.spawn.delay.max", phantomSpawnDelayMax);
|
|
+ phantomSpawnMinSkyDarkness = getInt("mobs.phantom.spawn.min-sky-darkness", phantomSpawnMinSkyDarkness);
|
|
+ phantomSpawnOnlyAboveSeaLevel = getBoolean("mobs.phantom.spawn.only-above-sea-level", phantomSpawnOnlyAboveSeaLevel);
|
|
+ phantomSpawnOnlyWithVisibleSky = getBoolean("mobs.phantom.spawn.only-with-visible-sky", phantomSpawnOnlyWithVisibleSky);
|
|
+ phantomSpawnLocalDifficultyChance = getDouble("mobs.phantom.spawn.local-difficulty-chance", phantomSpawnLocalDifficultyChance);
|
|
+ phantomSpawnMinTimeSinceSlept = getInt("mobs.phantom.spawn.min-time-since-slept", phantomSpawnMinTimeSinceSlept);
|
|
+ phantomSpawnMinOverhead = getInt("mobs.phantom.spawn.overhead.min", phantomSpawnMinOverhead);
|
|
+ phantomSpawnMaxOverhead = getInt("mobs.phantom.spawn.overhead.max", phantomSpawnMaxOverhead);
|
|
+ phantomSpawnOverheadRadius = getInt("mobs.phantom.spawn.overhead.radius", phantomSpawnOverheadRadius);
|
|
+ phantomSpawnMinPerAttempt = getInt("mobs.phantom.spawn.per-attempt.min", phantomSpawnMinPerAttempt);
|
|
+ phantomSpawnMaxPerAttempt = getInt("mobs.phantom.spawn.per-attempt.max", phantomSpawnMaxPerAttempt);
|
|
}
|
|
|
|
public boolean pigGiveSaddleBack = false;
|