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: 8c74d3126 Updated Upstream (Bukkit) (#5359) fd3c66a91 bug #5362 - correctly pass "render type" when registering a new scoreboard objective 39c487b37 Add per-command perms for paper command cdbf2578c Add Item Rarity API (#5352) d80e43647 [CI-SKIP] Removal from the MIT list (#5345) Tuinity Changes: aea6b8347 Merge dev/playerchunkloading 722c7ca8a Use hash table for maintaing changed block set 98ae59d85 Custom table implementation for blockstate state lookups 8b8704fb6 Oprimise map impl for tracked players ea71d6ba4 Optimise snow & ice in chunk ticking 9871d4ce5 Remove chunk lookup & lambda allocation from counting mobs 5a4a35f3e Add patreon 7d93d9618 Refactor data management for region manager c3035219f Change license from MIT to LGPLv3 Airplane Changes: 580f380b6 Updated Upstream (Tuinity) 82253fd36 Early return optimization for target finding 9572643bb Cache entityhuman display name 5df98254f Remove iterators from inventory contains 18d2be193 Merge pull request #14 from violetwtf/patch-1 f716d4c33 Merge pull request #13 from violetwtf/master 128cbe519 Reduce entity chunk ticking checks from 3 to 1 03ac0933b Skip copying unloading tile entities 97dd027b5 Smaller pool size for tracking 9e9f57be4 Only set up Flare if token is available
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 c7573e1271288bd2b9dfe9801ea8f8804089f6ce..b5b0f295d63eb245a6221f88110f1bb1694c641c 100644
|
|
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
|
@@ -397,6 +397,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 068d303853572519efc16bb9cd3b799e458e39e7..ad7360cd5ae79e4d031ae866bf911fb87a2c0cdf 100644
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
|
@@ -1687,6 +1687,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 88cac6394f67ec113a781a552261f760fc95eb16..fedc39bdbbd328296c5c08d220d6695fe08fdf91 100644
|
|
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
|
|
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
|
|
@@ -352,10 +352,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;
|