mirror of
https://github.com/PurpurMC/Purpur.git
synced 2026-02-18 00:47:42 +01:00
Upstream has released updates that appear to apply and compile correctly Paper Changes: 05af2837c [CI-SKIP] Improved the annotation test output 586966949 abstract custom set tags, add entity tags c7667378e Added PlayerLoomPatternSelectEvent 00972e80d Reimplement GS4QueryEvent 544c5c278 Re-add coral block tags (#4987) 7d56c8deb Added PlayerLecternPageChangeEvent c7cdf255b Add BlockFailedDispenseEvent c8a8d6fbe Added world settings for mobs picking up loot 91eda5bd3 Added ServerResourcesReloadedEvent be81b4f5c Add a Enchantable MaterialTag 975d18703 Add doors to material tags d075e748e colorful itemdump f3ba3dee0 Added WorldGameRuleChangeEvent 086d20118 Guardian beam workaround b63c890ec Support spawning item stacks d7d74c552 added height config for bamboo 7878e3bc2 Use setAmount for Recipe Amount 50e70697b Add EntityLoadCrossbowEvent f344e092c Add Anti-Xray bypass permission 9fd31e675 fix for nerfed slime mobs splitting 4a7962cd1 Zombie API - breaking doors 5650a41f5 Fix interact event not being called in adventure 2c9ed4335 Add PlayerFlowerPotManipulateEvent 1f32290b6 [Auto] Updated Upstream (CraftBukkit) d87694a20 Redact Velocity forwarding secret properly (#4980) 24a0b0206 [Auto] Updated Upstream (CraftBukkit) 7681042ef [Auto] Updated Upstream (Bukkit/CraftBukkit) 7dea3dba6 [Auto] Updated Upstream (CraftBukkit) 4b3792920 JavaDoc fixes f13b4727e Allow disabling mob spawner spawn egg transformation 525b50737 Cache burn durations 2c37d1077 Optimized tick ready check b4000b01a Add API to get the Material of Boats and Minecarts f1317386d Fix sign lazy initialisation 9f61759d9 Updated Upstream (CraftBukkit/Spigot) (#4972) aaff430b6 [CI-SKIP] Use GitHub Actions for build status 9f4055d99 Fix harming potion dupe 7bfb781ff Additional Block Material API's 0eaffd008 Micro Optimize DataBits Tuinity Changes: 9e5cabb6e Port starlight changes
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 75745af3435434bddd420536ca3bbea3a9f181d6..84c0ec1b50758b433980765d087e15d8a8eaaaf7 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 e0e72779c0f4e4856ed5682122fedf0321db11cb..386eae71a146e06ca60f8bf11429fe2131232a21 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 03a89301f2b3d29e39c6c9d05ee072527f652efc..fa5eb188da64cc1409cc614515e8c70b0a341dd0 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 4e3f01bc79b6ed2a322155f29f1d0dcf298c8b82..ac1ea2f0c15bccf94f203194a5a7b10ec125ffb8 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 661ad8f8e67046211e001ea40d97660d7c88f8e5..ee91c33a7a2edca02caf5c71fd6429f97eac7e2d 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 68dec17bbf64a60c774ab26abc326b953889aa8c..f91d9a19b3d9870c99a03c86eb835b8ec68cc133 100644
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
|
@@ -1566,6 +1566,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 74aee0687cb8aa7e4b7efbf34d6374a516d873c0..f60bc17cf25211bf0c9007307c54821aecc7bb96 100644
|
|
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
|
|
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
|
|
@@ -336,10 +336,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;
|