100 patches done

This commit is contained in:
granny
2024-12-03 20:57:07 -08:00
parent ceacfddaf9
commit 087bfb64f5
50 changed files with 117 additions and 117 deletions

View File

@@ -1,96 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sat, 23 Nov 2019 17:55:42 -0600
Subject: [PATCH] Implement infinite liquids
diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
index f4fbcbb8ff6d2677af1a02a0801a323c06dce9b1..6f024a29e8824a604ff0c74f88522d23423beb5c 100644
--- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
+++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
@@ -266,7 +266,7 @@ public abstract class FlowingFluid extends Fluid {
}
}
- if (j >= 2 && this.canConvertToSource(world)) {
+ if (j >= getRequiredSources(world) && this.canConvertToSource(world)) { // Purpur
BlockState iblockdata2 = world.getBlockState(blockposition_mutableblockposition.setWithOffset(pos, Direction.DOWN));
FluidState fluid1 = iblockdata2.getFluidState();
@@ -356,6 +356,12 @@ public abstract class FlowingFluid extends Fluid {
protected abstract boolean canConvertToSource(ServerLevel world);
+ // Purpur start
+ protected int getRequiredSources(Level level) {
+ return 2;
+ }
+ // Purpur end
+
protected void spreadTo(LevelAccessor world, BlockPos pos, BlockState state, Direction direction, FluidState fluidState) {
Block block = state.getBlock();
diff --git a/src/main/java/net/minecraft/world/level/material/LavaFluid.java b/src/main/java/net/minecraft/world/level/material/LavaFluid.java
index 884db3e64cb22ed765beec8f11ea309fcf810207..e9687c3580e5fff33ce902eb7b86eb815ca1072d 100644
--- a/src/main/java/net/minecraft/world/level/material/LavaFluid.java
+++ b/src/main/java/net/minecraft/world/level/material/LavaFluid.java
@@ -199,6 +199,13 @@ public abstract class LavaFluid extends FlowingFluid {
world.levelEvent(1501, pos, 0);
}
+ // Purpur start
+ @Override
+ protected int getRequiredSources(Level level) {
+ return level.purpurConfig.lavaInfiniteRequiredSources;
+ }
+ // Purpur end
+
@Override
protected boolean canConvertToSource(ServerLevel world) {
return world.getGameRules().getBoolean(GameRules.RULE_LAVA_SOURCE_CONVERSION);
diff --git a/src/main/java/net/minecraft/world/level/material/WaterFluid.java b/src/main/java/net/minecraft/world/level/material/WaterFluid.java
index 552925ba47c7475e2e1ec2ded0966f28ed3e50a5..1e741f36b79585f33abe413beafe00cf5205d54f 100644
--- a/src/main/java/net/minecraft/world/level/material/WaterFluid.java
+++ b/src/main/java/net/minecraft/world/level/material/WaterFluid.java
@@ -81,6 +81,13 @@ public abstract class WaterFluid extends FlowingFluid {
return world.getGameRules().getBoolean(GameRules.RULE_WATER_SOURCE_CONVERSION);
}
+ // Purpur start
+ @Override
+ protected int getRequiredSources(Level level) {
+ return level.purpurConfig.waterInfiniteRequiredSources;
+ }
+ // Purpur end
+
// Paper start - Add BlockBreakBlockEvent
@Override
protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state, BlockPos source) {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 1b96a84a1c81c075aa5f7308b89d396a4578be33..8221f383726a4d6aec895529f9330c64de286a35 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -222,6 +222,11 @@ public class PurpurWorldConfig {
farmlandGetsMoistFromBelow = getBoolean("blocks.farmland.gets-moist-from-below", farmlandGetsMoistFromBelow);
}
+ public int lavaInfiniteRequiredSources = 2;
+ private void lavaSettings() {
+ lavaInfiniteRequiredSources = getInt("blocks.lava.infinite-required-sources", lavaInfiniteRequiredSources);
+ }
+
public boolean turtleEggsBreakFromExpOrbs = false;
public boolean turtleEggsBreakFromItems = false;
public boolean turtleEggsBreakFromMinecarts = false;
@@ -231,6 +236,11 @@ public class PurpurWorldConfig {
turtleEggsBreakFromMinecarts = getBoolean("blocks.turtle_egg.break-from-minecarts", turtleEggsBreakFromMinecarts);
}
+ public int waterInfiniteRequiredSources = 2;
+ private void waterSources() {
+ waterInfiniteRequiredSources = getInt("blocks.water.infinite-required-sources", waterInfiniteRequiredSources);
+ }
+
public boolean babiesAreRidable = true;
public boolean untamedTamablesAreRidable = true;
public boolean useNightVisionWhenRiding = false;

View File

@@ -1,36 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 2 Jan 2020 11:31:36 -0600
Subject: [PATCH] Make lava flow speed configurable
diff --git a/src/main/java/net/minecraft/world/level/material/LavaFluid.java b/src/main/java/net/minecraft/world/level/material/LavaFluid.java
index e9687c3580e5fff33ce902eb7b86eb815ca1072d..6e643c1a7f7e71cfd20603facaf224985ee81716 100644
--- a/src/main/java/net/minecraft/world/level/material/LavaFluid.java
+++ b/src/main/java/net/minecraft/world/level/material/LavaFluid.java
@@ -181,7 +181,7 @@ public abstract class LavaFluid extends FlowingFluid {
@Override
public int getTickDelay(LevelReader world) {
- return world.dimensionType().ultraWarm() ? 10 : 30;
+ return world.dimensionType().ultraWarm() ? world.getWorldBorder().world.purpurConfig.lavaSpeedNether : world.getWorldBorder().world.purpurConfig.lavaSpeedNotNether; // Purpur
}
@Override
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 8221f383726a4d6aec895529f9330c64de286a35..8b2d9b592ef0f90df0c623595fb425e4f37d0c04 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -223,8 +223,12 @@ public class PurpurWorldConfig {
}
public int lavaInfiniteRequiredSources = 2;
+ public int lavaSpeedNether = 10;
+ public int lavaSpeedNotNether = 30;
private void lavaSettings() {
lavaInfiniteRequiredSources = getInt("blocks.lava.infinite-required-sources", lavaInfiniteRequiredSources);
+ lavaSpeedNether = getInt("blocks.lava.speed.nether", lavaSpeedNether);
+ lavaSpeedNotNether = getInt("blocks.lava.speed.not-nether", lavaSpeedNotNether);
}
public boolean turtleEggsBreakFromExpOrbs = false;

View File

@@ -1,57 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 26 Dec 2019 22:08:37 -0600
Subject: [PATCH] Add player death exp control options
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
index d1b6e7cf8d110d9106ea99431cf9719ea3b102d5..f4823112f2daf2aa75e1f4520fb91077c9c94e09 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -1921,7 +1921,23 @@ public abstract class Player extends LivingEntity {
@Override
protected int getBaseExperienceReward(ServerLevel world) {
- return !world.getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) && !this.isSpectator() ? Math.min(this.experienceLevel * 7, 100) : 0;
+ // Purpur start
+ if (!world.getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) && !this.isSpectator()) {
+ int toDrop;
+ try {
+ toDrop = Math.round(((Number) scriptEngine.eval("let expLevel = " + experienceLevel + "; " +
+ "let expTotal = " + totalExperience + "; " +
+ "let exp = " + experienceProgress + "; " +
+ level().purpurConfig.playerDeathExpDropEquation)).floatValue());
+ } catch (javax.script.ScriptException e) {
+ e.printStackTrace();
+ toDrop = experienceLevel * 7;
+ }
+ return Math.min(toDrop, level().purpurConfig.playerDeathExpDropMax);
+ } else {
+ return 0;
+ }
+ // Purpur end
}
@Override
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 8b2d9b592ef0f90df0c623595fb425e4f37d0c04..f62000475acb9e48f3c86c6ed267ed3b2038529a 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -172,6 +172,8 @@ public class PurpurWorldConfig {
public boolean idleTimeoutCountAsSleeping = false;
public boolean idleTimeoutUpdateTabList = false;
public boolean idleTimeoutTargetPlayer = true;
+ public String playerDeathExpDropEquation = "expLevel * 7";
+ public int playerDeathExpDropMax = 100;
private void playerSettings() {
if (PurpurConfig.version < 19) {
boolean oldVal = getBoolean("gameplay-mechanics.player.idle-timeout.mods-target", idleTimeoutTargetPlayer);
@@ -183,6 +185,8 @@ public class PurpurWorldConfig {
idleTimeoutCountAsSleeping = getBoolean("gameplay-mechanics.player.idle-timeout.count-as-sleeping", idleTimeoutCountAsSleeping);
idleTimeoutUpdateTabList = getBoolean("gameplay-mechanics.player.idle-timeout.update-tab-list", idleTimeoutUpdateTabList);
idleTimeoutTargetPlayer = getBoolean("gameplay-mechanics.player.idle-timeout.mobs-target", idleTimeoutTargetPlayer);
+ playerDeathExpDropEquation = getString("gameplay-mechanics.player.exp-dropped-on-death.equation", playerDeathExpDropEquation);
+ playerDeathExpDropMax = getInt("gameplay-mechanics.player.exp-dropped-on-death.maximum", playerDeathExpDropMax);
}
public boolean silkTouchEnabled = false;

View File

@@ -1,172 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 27 Feb 2020 21:42:19 -0600
Subject: [PATCH] Configurable void damage height and damage
temporarily migrate to paper's config
drop patch on the next minecraft release
diff --git a/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java b/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java
index c5644d8d64f12073e39bc6ed79c8714f4560ff89..47a2cba0db36b11548d06ec21f7c7d7c9a962d6e 100644
--- a/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java
+++ b/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java
@@ -263,6 +263,7 @@ public class PaperConfigurations extends Configurations<GlobalConfiguration, Wor
for (final NodePath path : RemovedConfigurations.REMOVED_WORLD_PATHS) {
builder.addAction(path, TransformAction.remove());
}
+ org.purpurmc.purpur.configuration.transformation.VoidDamageHeightMigration.apply(builder, contextMap); // Purpur
builder.build().apply(node);
final ConfigurationTransformation.VersionedBuilder versionedBuilder = Transformations.versionedBuilder();
diff --git a/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java
index b1c917d65076a3805e5b78cb946753f0c101e214..82210667376fd466d5d4cdcb56b62f6165bd5cde 100644
--- a/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java
+++ b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java
@@ -409,6 +409,7 @@ public class WorldConfiguration extends ConfigurationPart {
public boolean useVanillaWorldScoreboardNameColoring = false;
}
+ @Setting(org.purpurmc.purpur.configuration.transformation.VoidDamageHeightMigration.ENVIRONMENT_KEY) // Purpur
public Environment environment;
public class Environment extends ConfigurationPart {
@@ -418,7 +419,9 @@ public class WorldConfiguration extends ConfigurationPart {
public boolean disableExplosionKnockback = false;
public boolean generateFlatBedrock = false;
public FrostedIce frostedIce;
+ @Setting(org.purpurmc.purpur.configuration.transformation.VoidDamageHeightMigration.VOID_DAMAGE_KEY) // Purpur
public DoubleOr.Disabled voidDamageAmount = new DoubleOr.Disabled(OptionalDouble.of(4));
+ @Setting(org.purpurmc.purpur.configuration.transformation.VoidDamageHeightMigration.VOID_DAMAGE_MIN_HEIGHT_OFFSET_KEY) // Purpur
public double voidDamageMinBuildHeightOffset = -64.0;
public class FrostedIce extends ConfigurationPart {
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index f6ad220e3e228e978c8b635064e8d5bf65ac5a89..67db7d9f57fd4407412b9cfbc8b0ab06f15fff12 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1270,7 +1270,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
LOGGER.info("*************************************************************************************");
}
// Paper end - Add onboarding message for initial server start
-
+ // Purpur start
+ if (org.purpurmc.purpur.configuration.transformation.VoidDamageHeightMigration.HAS_BEEN_REGISTERED) {
+ try {
+ org.purpurmc.purpur.PurpurConfig.config.save((File) this.options.valueOf("purpur-settings"));
+ } catch (IOException ex) {
+ Bukkit.getLogger().log(java.util.logging.Level.SEVERE, "Could not save " + this.options.valueOf("purpur-settings"), ex);
+ }
+ }
+ // Purpur end
while (this.running) {
long i;
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index 2a7fd4420467cce0c4ddca749955ba45e034e555..c142f25e520e69d343702fcd83dfbbb117370d69 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -219,6 +219,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
org.spigotmc.SpigotConfig.registerCommands();
// Spigot end
io.papermc.paper.util.ObfHelper.INSTANCE.getClass(); // Paper - load mappings for stacktrace deobf and etc.
+ // Purpur start
+ try {
+ org.purpurmc.purpur.PurpurConfig.init((java.io.File) options.valueOf("purpur-settings"));
+ } catch (Exception e) {
+ DedicatedServer.LOGGER.error("Unable to load server configuration", e);
+ return false;
+ }
+ org.purpurmc.purpur.PurpurConfig.registerCommands();
+ // Purpur end
// Paper start - initialize global and world-defaults configuration
this.paperConfigurations.initializeGlobalConfiguration(this.registryAccess());
this.paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess());
@@ -235,15 +244,6 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command
this.server.spark.registerCommandBeforePlugins(this.server); // Paper - spark
com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics
- // Purpur start
- try {
- org.purpurmc.purpur.PurpurConfig.init((java.io.File) options.valueOf("purpur-settings"));
- } catch (Exception e) {
- DedicatedServer.LOGGER.error("Unable to load server configuration", e);
- return false;
- }
- org.purpurmc.purpur.PurpurConfig.registerCommands();
- // Purpur end
com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now
gg.pufferfish.pufferfish.PufferfishConfig.load(); // Pufferfish
gg.pufferfish.pufferfish.PufferfishCommand.init(); // Pufferfish
diff --git a/src/main/java/org/purpurmc/purpur/configuration/transformation/VoidDamageHeightMigration.java b/src/main/java/org/purpurmc/purpur/configuration/transformation/VoidDamageHeightMigration.java
new file mode 100644
index 0000000000000000000000000000000000000000..a04d23bd98075cd65a24d4de8d18281d1668480f
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/configuration/transformation/VoidDamageHeightMigration.java
@@ -0,0 +1,67 @@
+package org.purpurmc.purpur.configuration.transformation;
+
+import io.papermc.paper.configuration.Configurations;
+import io.papermc.paper.configuration.PaperConfigurations;
+import io.papermc.paper.configuration.type.number.DoubleOr;
+import java.util.OptionalDouble;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.purpurmc.purpur.PurpurConfig;
+import org.spongepowered.configurate.ConfigurateException;
+import org.spongepowered.configurate.ConfigurationNode;
+import org.spongepowered.configurate.NodePath;
+import org.spongepowered.configurate.transformation.ConfigurationTransformation;
+import org.spongepowered.configurate.transformation.TransformAction;
+
+import static org.spongepowered.configurate.NodePath.path;
+
+public class VoidDamageHeightMigration implements TransformAction {
+
+ public static boolean HAS_BEEN_REGISTERED = false;
+
+ public static final String ENVIRONMENT_KEY = "environment";
+ public static final String VOID_DAMAGE_KEY = "void-damage-amount";
+ public static final String VOID_DAMAGE_MIN_HEIGHT_OFFSET_KEY = "void-damage-min-build-height-offset";
+ public static final double DEFAULT_VOID_DAMAGE_HEIGHT = -64.0D;
+ public static final double DEFAULT_VOID_DAMAGE = 4.0D;
+
+ private final String worldName;
+
+ private VoidDamageHeightMigration(String worldName) {
+ this.worldName = PaperConfigurations.WORLD_DEFAULTS.equals(worldName) ? "default" : worldName;
+ }
+
+ @Override
+ public Object @Nullable [] visitPath(final NodePath path, final ConfigurationNode value) throws ConfigurateException {
+ String purpurVoidDamageHeightPath = "world-settings." + this.worldName + ".gameplay-mechanics.void-damage-height";
+ ConfigurationNode voidDamageMinHeightOffsetNode = value.node(ENVIRONMENT_KEY, VOID_DAMAGE_MIN_HEIGHT_OFFSET_KEY);
+ if (PurpurConfig.config.contains(purpurVoidDamageHeightPath)) {
+ double purpurVoidDamageHeight = PurpurConfig.config.getDouble(purpurVoidDamageHeightPath);
+ if (purpurVoidDamageHeight != DEFAULT_VOID_DAMAGE_HEIGHT && (voidDamageMinHeightOffsetNode.empty() || voidDamageMinHeightOffsetNode.getDouble() == DEFAULT_VOID_DAMAGE_HEIGHT)) {
+ voidDamageMinHeightOffsetNode.raw(null);
+ voidDamageMinHeightOffsetNode.set(purpurVoidDamageHeight);
+ }
+ PurpurConfig.config.set(purpurVoidDamageHeightPath, null);
+ }
+
+ String purpurVoidDamagePath = "world-settings." + this.worldName + ".gameplay-mechanics.void-damage-dealt";
+ ConfigurationNode voidDamageNode = value.node(ENVIRONMENT_KEY, VOID_DAMAGE_KEY);
+ if (PurpurConfig.config.contains(purpurVoidDamagePath)) {
+ double purpurVoidDamage = PurpurConfig.config.getDouble(purpurVoidDamagePath);
+ if (purpurVoidDamage != DEFAULT_VOID_DAMAGE && (voidDamageNode.empty() || voidDamageNode.getDouble() == DEFAULT_VOID_DAMAGE)) {
+ voidDamageNode.raw(null);
+ voidDamageNode.set(new DoubleOr.Disabled(OptionalDouble.of(purpurVoidDamage)));
+ }
+ PurpurConfig.config.set(purpurVoidDamagePath, null);
+ }
+
+ return null;
+ }
+
+ public static void apply(final ConfigurationTransformation.Builder builder, final Configurations.ContextMap contextMap) {
+ if (PurpurConfig.version < 36) {
+ HAS_BEEN_REGISTERED = true;
+ builder.addAction(path(), new VoidDamageHeightMigration(contextMap.require(Configurations.WORLD_NAME)));
+ }
+ }
+
+}

View File

@@ -1,86 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Tue, 18 Feb 2020 20:07:08 -0600
Subject: [PATCH] Add canSaveToDisk to Entity
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 35c6cc4d0d76becba693d056534a9437bd3364e4..56225797f1cf0294c1e6aa824d8c146dca530e9f 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -572,6 +572,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
}
// Paper end - optimise entity tracker
+ // Purpur start
+ public boolean canSaveToDisk() {
+ return true;
+ }
+ // Purpur end
public Entity(EntityType<?> type, Level world) {
this.id = Entity.ENTITY_COUNTER.incrementAndGet();
diff --git a/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java b/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java
index a1f25efb38eff32aaabe892ddbc9a60426923686..e0f25b057b7b908a10038d9e9695a500aa883c75 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java
@@ -121,6 +121,11 @@ public class WitherSkull extends AbstractHurtingProjectile {
// do not hit rider
return target != this.getRider() && super.canHitEntity(target);
}
+
+ @Override
+ public boolean canSaveToDisk() {
+ return false;
+ }
// Purpur end
@Override
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java
index 356d010506fd21f3c752e4aa86c46c1106fdde3b..86e16dd6b905af31795fda8002f2e1f857ddcb9f 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java
@@ -106,6 +106,7 @@ public class EntityStorage implements EntityPersistentStorage<Entity> {
}
// Paper end - Entity load/save limit per chunk
CompoundTag compoundTagx = new CompoundTag();
+ if (!entity.canSaveToDisk()) return; // Purpur
if (entity.save(compoundTagx)) {
listTag.add(compoundTagx);
}
diff --git a/src/main/java/org/purpurmc/purpur/entity/DolphinSpit.java b/src/main/java/org/purpurmc/purpur/entity/DolphinSpit.java
index 89c476c740b4efb4f44c1dcd384b908626d96780..f25abee6dbf99c8d08f8e09db02b41df86115faa 100644
--- a/src/main/java/org/purpurmc/purpur/entity/DolphinSpit.java
+++ b/src/main/java/org/purpurmc/purpur/entity/DolphinSpit.java
@@ -36,6 +36,13 @@ public class DolphinSpit extends LlamaSpit {
dolphin.getZ() + (double) (dolphin.getBbWidth() + 1.0F) * 0.5D * (double) Mth.cos(dolphin.yBodyRot * 0.017453292F));
}
+ // Purpur start
+ @Override
+ public boolean canSaveToDisk() {
+ return false;
+ }
+ // Purpur end
+
public void tick() {
super_tick();
diff --git a/src/main/java/org/purpurmc/purpur/entity/PhantomFlames.java b/src/main/java/org/purpurmc/purpur/entity/PhantomFlames.java
index d7f5686fe897f3c2424b146c8e7d2862223d1eaf..58957b0bd3cd2c37fd4a6766a02e2506d9f51010 100644
--- a/src/main/java/org/purpurmc/purpur/entity/PhantomFlames.java
+++ b/src/main/java/org/purpurmc/purpur/entity/PhantomFlames.java
@@ -38,6 +38,13 @@ public class PhantomFlames extends LlamaSpit {
phantom.getZ() + (double) (phantom.getBbWidth() + 1.0F) * 0.5D * (double) Mth.cos(phantom.yBodyRot * 0.017453292F));
}
+ // Purpur start
+ @Override
+ public boolean canSaveToDisk() {
+ return false;
+ }
+ // Purpur end
+
public void tick() {
super_tick();

View File

@@ -1,61 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sun, 25 Aug 2019 00:09:52 -0500
Subject: [PATCH] Dispenser curse of binding protection
diff --git a/src/main/java/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java
index bf8c511739265c6a9cd277752e844481598f8966..ffe2399ab6b1f311536475d8216238b5b01c5dab 100644
--- a/src/main/java/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java
+++ b/src/main/java/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java
@@ -41,7 +41,7 @@ public class EquipmentDispenseItemBehavior extends DefaultDispenseItemBehavior {
return false;
} else {
LivingEntity entityliving = (LivingEntity) list.getFirst();
- EquipmentSlot enumitemslot = entityliving.getEquipmentSlotForItem(stack);
+ EquipmentSlot enumitemslot = pointer.level().purpurConfig.dispenserApplyCursedArmor ? entityliving.getEquipmentSlotForItem(stack) : entityliving.getEquipmentSlotForDispenserItem(stack); if (enumitemslot == null) return false; // Purpur - Dispenser curse of binding protection
ItemStack itemstack1 = stack.copyWithCount(1); // Paper - shrink below and single item in event
// CraftBukkit start
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index af017da528924bae0542dd0e59d23c3bf59aa7b3..d8e37b250be00445fa6a97c99789198a74795e7d 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -4719,7 +4719,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
if (equippable != null && equippable.dispensable()) {
EquipmentSlot enumitemslot = equippable.slot();
- return this.canUseSlot(enumitemslot) && equippable.canBeEquippedBy(this.getType()) ? this.getItemBySlot(enumitemslot).isEmpty() && this.canDispenserEquipIntoSlot(enumitemslot) : false;
+ return this.canUseSlot(enumitemslot) && equippable.canBeEquippedBy(this.getType()) && this.getItemBySlot(enumitemslot).isEmpty() && this.canDispenserEquipIntoSlot(enumitemslot);
} else {
return false;
}
@@ -4744,6 +4744,12 @@ public abstract class LivingEntity extends Entity implements Attackable {
return equippable == null ? slot == EquipmentSlot.MAINHAND && this.canUseSlot(EquipmentSlot.MAINHAND) : slot == equippable.slot() && this.canUseSlot(equippable.slot()) && equippable.canBeEquippedBy(this.getType());
}
+ // Purpur start - Dispenser curse of binding protection
+ public @Nullable EquipmentSlot getEquipmentSlotForDispenserItem(ItemStack itemstack) {
+ return EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.BINDING_CURSE, itemstack) > 0 ? null : this.getEquipmentSlotForItem(itemstack);
+ }
+ // Purpur end - Dispenser curse of binding protection
+
private static SlotAccess createEquipmentSlotAccess(LivingEntity entity, EquipmentSlot slot) {
return slot != EquipmentSlot.HEAD && slot != EquipmentSlot.MAINHAND && slot != EquipmentSlot.OFFHAND ? SlotAccess.forEquipmentSlot(entity, slot, (itemstack) -> {
return itemstack.isEmpty() || entity.getEquipmentSlotForItem(itemstack) == slot;
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index f62000475acb9e48f3c86c6ed267ed3b2038529a..04b3b0661143d4d600dd34cd91498acbc929b10d 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -221,6 +221,11 @@ public class PurpurWorldConfig {
});
}
+ public boolean dispenserApplyCursedArmor = true;
+ private void dispenserSettings() {
+ dispenserApplyCursedArmor = getBoolean("blocks.dispenser.apply-cursed-to-armor-slots", dispenserApplyCursedArmor);
+ }
+
public boolean farmlandGetsMoistFromBelow = false;
private void farmlandSettings() {
farmlandGetsMoistFromBelow = getBoolean("blocks.farmland.gets-moist-from-below", farmlandGetsMoistFromBelow);

View File

@@ -1,35 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sat, 7 Sep 2019 22:47:59 -0500
Subject: [PATCH] Add option for boats to eject players on land
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java
index 1fdbef16cd29c8fc74578ac3328f985eca61088d..e523f651e8776a89ffba015921d708f569fad8f3 100644
--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java
+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java
@@ -499,6 +499,7 @@ public abstract class AbstractBoat extends VehicleEntity implements Leashable {
if (f > 0.0F) {
this.landFriction = f;
+ if (level().purpurConfig.boatEjectPlayersOnLand) ejectPassengers(); // Purpur
return AbstractBoat.Status.ON_LAND;
} else {
return AbstractBoat.Status.IN_AIR;
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 04b3b0661143d4d600dd34cd91498acbc929b10d..3e78e57f29e98db2dde7d650b65ee23f99238ff7 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -96,10 +96,12 @@ public class PurpurWorldConfig {
armorstandStepHeight = (float) getDouble("gameplay-mechanics.armorstand.step-height", armorstandStepHeight);
}
+ public boolean boatEjectPlayersOnLand = false;
public boolean disableDropsOnCrammingDeath = false;
public boolean milkCuresBadOmen = true;
public double tridentLoyaltyVoidReturnHeight = 0.0D;
private void miscGameplayMechanicsSettings() {
+ boatEjectPlayersOnLand = getBoolean("gameplay-mechanics.boat.eject-players-on-land", boatEjectPlayersOnLand);
disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath);
milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen);
tridentLoyaltyVoidReturnHeight = getDouble("gameplay-mechanics.trident-loyalty-void-return-height", tridentLoyaltyVoidReturnHeight);

View File

@@ -1,129 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sun, 14 Jul 2019 19:52:47 -0500
Subject: [PATCH] Mending mends most damages equipment first
diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
index bf0838f574fa3fb9654e087d602b8d380bd7fb28..6db9a3ea4c0dc1f0629bc8bf6466aeab00c498f6 100644
--- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
+++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
@@ -351,7 +351,7 @@ public class ExperienceOrb extends Entity {
}
private int repairPlayerItems(ServerPlayer player, int amount) {
- Optional<EnchantedItemInUse> optional = EnchantmentHelper.getRandomItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, player, ItemStack::isDamaged);
+ Optional<EnchantedItemInUse> optional = level().purpurConfig.useBetterMending ? EnchantmentHelper.getMostDamagedItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, player) : EnchantmentHelper.getRandomItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, player, ItemStack::isDamaged); // Purpur - Add option to mend the most damaged equipment first
if (optional.isPresent()) {
ItemStack itemstack = ((EnchantedItemInUse) optional.get()).itemStack();
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
index 33e7d2884195677c4d6340d8b84c1dd85c636ec1..239bd6e3d756dc4ecab6ca639fa84ccbf89418a7 100644
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
@@ -681,6 +681,26 @@ public final class ItemStack implements DataComponentHolder {
return this.isDamageableItem() && this.getDamageValue() > 0;
}
+ // Purpur start - Add option to mend the most damaged equipment first
+ public float getDamagePercent() {
+ if (this.has(DataComponents.UNBREAKABLE)) {
+ return 0.0F;
+ }
+
+ final int maxDamage = this.getOrDefault(DataComponents.MAX_DAMAGE, 0);
+ if (maxDamage == 0) {
+ return 0.0F;
+ }
+
+ final int damage = this.getOrDefault(DataComponents.DAMAGE, 0);
+ if (damage == 0) {
+ return 0.0F;
+ }
+
+ return (float) damage / maxDamage;
+ }
+ // Purpur end - Add option to mend the most damaged equipment first
+
public int getDamageValue() {
return Mth.clamp((Integer) this.getOrDefault(DataComponents.DAMAGE, 0), 0, this.getMaxDamage());
}
diff --git a/src/main/java/net/minecraft/world/item/enchantment/EnchantmentHelper.java b/src/main/java/net/minecraft/world/item/enchantment/EnchantmentHelper.java
index d8fc10f9cd0ab2c26e64613006569a86ce201550..73241113e50dc8be89ef8850d49d95ec31fb194f 100644
--- a/src/main/java/net/minecraft/world/item/enchantment/EnchantmentHelper.java
+++ b/src/main/java/net/minecraft/world/item/enchantment/EnchantmentHelper.java
@@ -6,6 +6,7 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap.Entry;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
@@ -588,4 +589,48 @@ public class EnchantmentHelper {
return getItemEnchantmentLevel(getEnchantmentHolder(enchantment), stack);
}
// Purpur end - Enchantment convenience methods
+
+ // Purpur start - Add option to mend the most damaged equipment first
+ public static Optional<EnchantedItemInUse> getMostDamagedItemWith(DataComponentType<?> componentType, LivingEntity entity) {
+ ItemStack maxStack = null;
+ EquipmentSlot maxSlot = null;
+ float maxPercent = 0.0F;
+
+ equipmentSlotLoop:
+ for (EquipmentSlot equipmentSlot : EquipmentSlot.values()) {
+ ItemStack stack = entity.getItemBySlot(equipmentSlot);
+
+ // do not even check enchantments for item with lower or equal damage percent
+ float percent = stack.getDamagePercent();
+ if (percent <= maxPercent) {
+ continue;
+ }
+
+ ItemEnchantments itemEnchantments = stack.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY);
+
+ for (Entry<Holder<Enchantment>> entry : itemEnchantments.entrySet()) {
+ Enchantment enchantment = entry.getKey().value();
+
+ net.minecraft.core.component.DataComponentMap effects = enchantment.effects();
+ if (!effects.has(componentType)) {
+ // try with another enchantment
+ continue;
+ }
+
+ if (enchantment.matchingSlot(equipmentSlot)) {
+ maxStack = stack;
+ maxSlot = equipmentSlot;
+ maxPercent = percent;
+
+ // check another slot now
+ continue equipmentSlotLoop;
+ }
+ }
+ }
+
+ return maxStack != null
+ ? Optional.of(new EnchantedItemInUse(maxStack, maxSlot, entity))
+ : Optional.empty();
+ }
+ // Purpur end - Add option to mend the most damaged equipment first
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 3e78e57f29e98db2dde7d650b65ee23f99238ff7..6b7a6a7889353f9557c6e3bfa8ff8caf66416c1b 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -96,11 +96,13 @@ public class PurpurWorldConfig {
armorstandStepHeight = (float) getDouble("gameplay-mechanics.armorstand.step-height", armorstandStepHeight);
}
+ public boolean useBetterMending = false;
public boolean boatEjectPlayersOnLand = false;
public boolean disableDropsOnCrammingDeath = false;
public boolean milkCuresBadOmen = true;
public double tridentLoyaltyVoidReturnHeight = 0.0D;
private void miscGameplayMechanicsSettings() {
+ useBetterMending = getBoolean("gameplay-mechanics.use-better-mending", useBetterMending);
boatEjectPlayersOnLand = getBoolean("gameplay-mechanics.boat.eject-players-on-land", boatEjectPlayersOnLand);
disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath);
milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen);

View File

@@ -1,108 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sun, 28 Jul 2019 01:27:37 -0500
Subject: [PATCH] Add 5 second tps average in /tps
diff --git a/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java b/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java
index 12b327eea95e0de9e9c39b7d039badee8ec46508..849ecc5af70901f1e40cb6c419f33f1cf6f3b6be 100644
--- a/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java
+++ b/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java
@@ -61,6 +61,7 @@ public class RAMDetails extends JList<String> {
// Follows CraftServer#getTPS
double[] tps = new double[] {
+ server.tps5s.getAverage(), // Purpur
server.tps1.getAverage(),
server.tps5.getAverage(),
server.tps15.getAverage()
@@ -73,7 +74,7 @@ public class RAMDetails extends JList<String> {
vector.add("Memory use: " + (data.getUsedMem() / 1024L / 1024L) + " mb (" + (data.getFree() * 100L / data.getMax()) + "% free)");
vector.add("Heap: " + (data.getTotal() / 1024L / 1024L) + " / " + (data.getMax() / 1024L / 1024L) + " mb");
vector.add("Avg tick: " + DECIMAL_FORMAT.format((double)this.server.getAverageTickTimeNanos() / (double) TimeUtil.NANOSECONDS_PER_MILLISECOND) + " ms");
- vector.add("TPS from last 1m, 5m, 15m: " + String.join(", ", tpsAvg));
+ vector.add("TPS from last 5s, 1m, 5m, 15m: " + String.join(", ", tpsAvg)); // Purpur
setListData(vector);
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 67db7d9f57fd4407412b9cfbc8b0ab06f15fff12..e1858bc2b043f0edf5d3f1393340f40aa7bcb36a 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -324,7 +324,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public static final int TICK_TIME = 1000000000 / MinecraftServer.TPS;
private static final int SAMPLE_INTERVAL = 20; // Paper - improve server tick loop
@Deprecated(forRemoval = true) // Paper
- public final double[] recentTps = new double[ 3 ];
+ public final double[] recentTps = new double[ 4 ]; // Purpur
// Spigot end
public final io.papermc.paper.configuration.PaperConfigurations paperConfigurations; // Paper - add paper configuration files
public boolean isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked
@@ -1184,6 +1184,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
private static final long MAX_CATCHUP_BUFFER = TICK_TIME * TPS * 60L;
private long lastTick = 0;
private long catchupTime = 0;
+ public final RollingAverage tps5s = new RollingAverage(5); // Purpur
public final RollingAverage tps1 = new RollingAverage(60);
public final RollingAverage tps5 = new RollingAverage(60 * 5);
public final RollingAverage tps15 = new RollingAverage(60 * 15);
@@ -1305,14 +1306,18 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
if (++MinecraftServer.currentTick % MinecraftServer.SAMPLE_INTERVAL == 0) {
final long diff = currentTime - tickSection;
final java.math.BigDecimal currentTps = TPS_BASE.divide(new java.math.BigDecimal(diff), 30, java.math.RoundingMode.HALF_UP);
+ tps5s.add(currentTps, diff); // Purpur
tps1.add(currentTps, diff);
tps5.add(currentTps, diff);
tps15.add(currentTps, diff);
// Backwards compat with bad plugins
- this.recentTps[0] = tps1.getAverage();
- this.recentTps[1] = tps5.getAverage();
- this.recentTps[2] = tps15.getAverage();
+ // Purpur start
+ this.recentTps[0] = tps5s.getAverage();
+ this.recentTps[1] = tps1.getAverage();
+ this.recentTps[2] = tps5.getAverage();
+ this.recentTps[3] = tps15.getAverage();
+ // Purpur end
lagging = recentTps[0] < org.purpurmc.purpur.PurpurConfig.laggingThreshold; // Purpur
tickSection = currentTime;
}
diff --git a/src/main/java/net/minecraft/server/gui/StatsComponent.java b/src/main/java/net/minecraft/server/gui/StatsComponent.java
index 096c89bd01cec2abd151bf6fffc4847d1bcd548f..cd0a8a6a1be75cab8bbb8ee3ac17bb732b9e7108 100644
--- a/src/main/java/net/minecraft/server/gui/StatsComponent.java
+++ b/src/main/java/net/minecraft/server/gui/StatsComponent.java
@@ -45,7 +45,7 @@ public class StatsComponent extends JComponent {
this.msgs[1] = "Avg tick: "
+ DECIMAL_FORMAT.format((double)this.server.getAverageTickTimeNanos() / (double)TimeUtil.NANOSECONDS_PER_MILLISECOND)
+ " ms";
- this.msgs[2] = "TPS from last 1m, 5m, 15m: " + String.join(", ", tpsAvg);
+ this.msgs[2] = "TPS from last 5s, 1m, 5m, 15m: " + String.join(", ", tpsAvg); // Purpur
// Paper end - Improve ServerGUI
this.values[this.vp++ & 0xFF] = (int)(l * 100L / Runtime.getRuntime().maxMemory());
this.repaint();
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 5fa7d429b19d135c5b3f719c35042818499b4563..1db859d7016dc96f00b985fc0bed67f18fdb88e3 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -3075,6 +3075,7 @@ public final class CraftServer implements Server {
@Override
public double[] getTPS() {
return new double[] {
+ net.minecraft.server.MinecraftServer.getServer().tps5s.getAverage(), // Purpur
net.minecraft.server.MinecraftServer.getServer().tps1.getAverage(),
net.minecraft.server.MinecraftServer.getServer().tps5.getAverage(),
net.minecraft.server.MinecraftServer.getServer().tps15.getAverage()
diff --git a/src/main/java/org/spigotmc/TicksPerSecondCommand.java b/src/main/java/org/spigotmc/TicksPerSecondCommand.java
index 9eb2823cc8f83bad2626fc77578b0162d9ed5782..f144a08e88f8268b84eb188a36bf470457f59958 100644
--- a/src/main/java/org/spigotmc/TicksPerSecondCommand.java
+++ b/src/main/java/org/spigotmc/TicksPerSecondCommand.java
@@ -39,7 +39,7 @@ public class TicksPerSecondCommand extends Command
}
net.kyori.adventure.text.TextComponent.Builder builder = net.kyori.adventure.text.Component.text();
- builder.append(net.kyori.adventure.text.Component.text("TPS from last 1m, 5m, 15m: ", net.kyori.adventure.text.format.NamedTextColor.GOLD));
+ builder.append(net.kyori.adventure.text.Component.text("TPS from last 5s, 1m, 5m, 15m: ", net.kyori.adventure.text.format.NamedTextColor.GOLD)); // Purpur
builder.append(net.kyori.adventure.text.Component.join(net.kyori.adventure.text.JoinConfiguration.commas(true), tpsAvg));
sender.sendMessage(builder.asComponent());
if (args.length > 0 && args[0].equals("mem") && sender.hasPermission("bukkit.command.tpsmemory")) {

View File

@@ -1,136 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 25 Jul 2019 18:07:37 -0500
Subject: [PATCH] Implement elytra settings
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index d8e37b250be00445fa6a97c99789198a74795e7d..c1a3103aa692bb5dfb4e162159c77a03d9c9a0e8 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -3788,7 +3788,17 @@ public abstract class LivingEntity extends Entity implements Attackable {
}).toList();
EquipmentSlot enumitemslot = (EquipmentSlot) Util.getRandom(list, this.random);
- this.getItemBySlot(enumitemslot).hurtAndBreak(1, this, enumitemslot);
+ // Purpur start
+ int damage = level().purpurConfig.elytraDamagePerSecond;
+ if (level().purpurConfig.elytraDamageMultiplyBySpeed > 0) {
+ double speed = getDeltaMovement().lengthSqr();
+ if (speed > level().purpurConfig.elytraDamageMultiplyBySpeed) {
+ damage *= (int) speed;
+ }
+ }
+
+ this.getItemBySlot(enumitemslot).hurtAndBreak(damage, this, enumitemslot);
+ // Purpur end
}
this.gameEvent(GameEvent.ELYTRA_GLIDE);
@@ -3797,7 +3807,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
- protected boolean canGlide() {
+ public boolean canGlide() { // Purpur
if (!this.onGround() && !this.isPassenger() && !this.hasEffect(MobEffects.LEVITATION)) {
Iterator iterator = EquipmentSlot.VALUES.iterator();
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
index f4823112f2daf2aa75e1f4520fb91077c9c94e09..773be9c116a664e4d0349c58c00df34f203f8ebf 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -1661,7 +1661,7 @@ public abstract class Player extends LivingEntity {
}
@Override
- protected boolean canGlide() {
+ public boolean canGlide() { // Purpur
return !this.abilities.flying && super.canGlide();
}
diff --git a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
index 29a048a9b09166838616ac7ba1d31625d56b0bca..184e6d9bf393188fc1f1c7acd545b4ac6d31f6a4 100644
--- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
+++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
@@ -66,6 +66,18 @@ public class FireworkRocketItem extends Item implements ProjectileItem {
com.destroystokyo.paper.event.player.PlayerElytraBoostEvent event = new com.destroystokyo.paper.event.player.PlayerElytraBoostEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Firework) delayed.projectile().getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand));
if (event.callEvent() && delayed.attemptSpawn()) {
user.awardStat(Stats.ITEM_USED.get(this)); // Moved up from below
+
+ // Purpur start
+ if (world.purpurConfig.elytraDamagePerFireworkBoost > 0) {
+ List<net.minecraft.world.entity.EquipmentSlot> list = net.minecraft.world.entity.EquipmentSlot.VALUES.stream().filter((enumitemslot) -> net.minecraft.world.entity.LivingEntity.canGlideUsing(user.getItemBySlot(enumitemslot), enumitemslot)).toList();
+ net.minecraft.world.entity.EquipmentSlot enumitemslot = net.minecraft.Util.getRandom(list, user.random);
+
+ ItemStack glideItem = user.getItemBySlot(enumitemslot);
+ if (user.canGlide()) {
+ glideItem.hurtAndBreak(world.purpurConfig.elytraDamagePerFireworkBoost, user, enumitemslot);
+ }
+ }
+ // Purpur end
if (event.shouldConsume() && !user.hasInfiniteMaterials()) {
itemStack.shrink(1); // Moved up from below
} else ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
index 239bd6e3d756dc4ecab6ca639fa84ccbf89418a7..dcb656be3d37f29bdbe7d25ace05c6dd1889e252 100644
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
@@ -781,6 +781,12 @@ public final class ItemStack implements DataComponentHolder {
org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent(serverPlayer, this); // Paper - Add EntityDamageItemEvent
}
// CraftBukkit end
+ // Purpur start
+ if (this.has(DataComponents.GLIDER)) {
+ setDamageValue(this.getMaxDamage() - 1);
+ return;
+ }
+ // Purpur end
this.shrink(1);
breakCallback.accept(item);
diff --git a/src/main/java/net/minecraft/world/item/TridentItem.java b/src/main/java/net/minecraft/world/item/TridentItem.java
index 8b9a93ef71164cce8a616735b71d96d37e83b1a8..5133443911f932e8f6b5d3ca8baccecfd6f81c00 100644
--- a/src/main/java/net/minecraft/world/item/TridentItem.java
+++ b/src/main/java/net/minecraft/world/item/TridentItem.java
@@ -132,6 +132,18 @@ public class TridentItem extends Item implements ProjectileItem {
f4 *= f / f6;
f5 *= f / f6;
org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerRiptideEvent(entityhuman, stack, f3, f4, f5); // CraftBukkit
+
+ // Purpur start
+ List<EquipmentSlot> list = EquipmentSlot.VALUES.stream().filter((enumitemslot) -> LivingEntity.canGlideUsing(entityhuman.getItemBySlot(enumitemslot), enumitemslot)).toList();
+ if (!list.isEmpty()) {
+ EquipmentSlot enumitemslot = net.minecraft.Util.getRandom(list, entityhuman.random);
+ ItemStack glideItem = entityhuman.getItemBySlot(enumitemslot);
+ if (glideItem.has(net.minecraft.core.component.DataComponents.GLIDER) && world.purpurConfig.elytraDamagePerTridentBoost > 0) {
+ glideItem.hurtAndBreak(world.purpurConfig.elytraDamagePerTridentBoost, entityhuman, enumitemslot);
+ }
+ }
+ // Purpur end
+
entityhuman.push((double) f3, (double) f4, (double) f5);
entityhuman.startAutoSpinAttack(20, 8.0F, stack);
if (entityhuman.onGround()) {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 6b7a6a7889353f9557c6e3bfa8ff8caf66416c1b..bc355a6b03877ca5e74688df13a089b487cde86c 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -109,6 +109,17 @@ public class PurpurWorldConfig {
tridentLoyaltyVoidReturnHeight = getDouble("gameplay-mechanics.trident-loyalty-void-return-height", tridentLoyaltyVoidReturnHeight);
}
+ public int elytraDamagePerSecond = 1;
+ public double elytraDamageMultiplyBySpeed = 0;
+ public int elytraDamagePerFireworkBoost = 0;
+ public int elytraDamagePerTridentBoost = 0;
+ private void elytraSettings() {
+ elytraDamagePerSecond = getInt("gameplay-mechanics.elytra.damage-per-second", elytraDamagePerSecond);
+ elytraDamageMultiplyBySpeed = getDouble("gameplay-mechanics.elytra.damage-multiplied-by-speed", elytraDamageMultiplyBySpeed);
+ elytraDamagePerFireworkBoost = getInt("gameplay-mechanics.elytra.damage-per-boost.firework", elytraDamagePerFireworkBoost);
+ elytraDamagePerTridentBoost = getInt("gameplay-mechanics.elytra.damage-per-boost.trident", elytraDamagePerTridentBoost);
+ }
+
public double minecartMaxSpeed = 0.4D;
public boolean minecartPlaceAnywhere = false;
public boolean minecartControllable = false;

View File

@@ -1,172 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sat, 22 Feb 2020 15:54:08 -0600
Subject: [PATCH] Item entity immunities
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
index 3ea4920323606150548d6e9fc1ce67724f19dc60..c14ce846afb7364e541bfe01b73a06a94e48f55b 100644
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
@@ -81,7 +81,7 @@ public class ServerEntity {
@Nullable
private List<SynchedEntityData.DataValue<?>> trackedDataValues;
// CraftBukkit start
- private final Set<ServerPlayerConnection> trackedPlayers;
+ public final Set<ServerPlayerConnection> trackedPlayers; // Purpur - private -> public
public ServerEntity(ServerLevel worldserver, Entity entity, int i, boolean flag, Consumer<Packet<?>> consumer, Set<ServerPlayerConnection> trackedPlayers) {
this.trackedPlayers = trackedPlayers;
diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
index 0f086af57a5ff08c264dcbf89a8c3931ec73a609..c63cf322e0d00b5ec9929db8c22d4a392049160f 100644
--- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
+++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
@@ -64,6 +64,12 @@ public class ItemEntity extends Entity implements TraceableEntity {
public boolean canMobPickup = true; // Paper - Item#canEntityPickup
private int despawnRate = -1; // Paper - Alternative item-despawn-rate
public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API
+ // Purpur start
+ public boolean immuneToCactus = false;
+ public boolean immuneToExplosion = false;
+ public boolean immuneToFire = false;
+ public boolean immuneToLightning = false;
+ // Purpur end
public ItemEntity(EntityType<? extends ItemEntity> type, Level world) {
super(type, world);
@@ -384,7 +390,16 @@ public class ItemEntity extends Entity implements TraceableEntity {
@Override
public final boolean hurtServer(ServerLevel world, DamageSource source, float amount) {
- if (this.isInvulnerableToBase(source)) {
+ // Purpur start
+ if (
+ (immuneToCactus && source.is(net.minecraft.world.damagesource.DamageTypes.CACTUS)) ||
+ (immuneToFire && (source.is(net.minecraft.tags.DamageTypeTags.IS_FIRE) || source.is(net.minecraft.world.damagesource.DamageTypes.ON_FIRE) || source.is(net.minecraft.world.damagesource.DamageTypes.IN_FIRE))) ||
+ (immuneToLightning && source.is(net.minecraft.world.damagesource.DamageTypes.LIGHTNING_BOLT)) ||
+ (immuneToExplosion && source.is(net.minecraft.tags.DamageTypeTags.IS_EXPLOSION))
+ ) {
+ return false;
+ } else if (this.isInvulnerableToBase(source)) {
+ // Purpur end
return false;
} else if (!world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && source.getEntity() instanceof Mob) {
return false;
@@ -595,6 +610,12 @@ public class ItemEntity extends Entity implements TraceableEntity {
public void setItem(ItemStack stack) {
this.getEntityData().set(ItemEntity.DATA_ITEM, stack);
this.despawnRate = this.level().paperConfig().entities.spawning.altItemDespawnRate.enabled ? this.level().paperConfig().entities.spawning.altItemDespawnRate.items.getOrDefault(stack.getItem(), this.level().spigotConfig.itemDespawnRate) : this.level().spigotConfig.itemDespawnRate; // Paper - Alternative item-despawn-rate
+ // Purpur start
+ if (level().purpurConfig.itemImmuneToCactus.contains(stack.getItem())) immuneToCactus = true;
+ if (level().purpurConfig.itemImmuneToExplosion.contains(stack.getItem())) immuneToExplosion = true;
+ if (level().purpurConfig.itemImmuneToFire.contains(stack.getItem())) immuneToFire = true;
+ if (level().purpurConfig.itemImmuneToLightning.contains(stack.getItem())) immuneToLightning = true;
+ // level end
}
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
index 30d62ee4d5cd2ddacb8783b5bbbf475d592b3e02..01e4395f1669d21c30465aa1366bd2f1ae17678f 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
@@ -151,4 +151,46 @@ public class CraftItem extends CraftEntity implements Item {
public String toString() {
return "CraftItem";
}
+
+ // Purpur start
+ @Override
+ public void setImmuneToCactus(boolean immuneToCactus) {
+ this.getHandle().immuneToCactus = immuneToCactus;
+ }
+
+ @Override
+ public boolean isImmuneToCactus() {
+ return this.getHandle().immuneToCactus;
+ }
+
+ @Override
+ public void setImmuneToExplosion(boolean immuneToExplosion) {
+ this.getHandle().immuneToExplosion = immuneToExplosion;
+ }
+
+ @Override
+ public boolean isImmuneToExplosion() {
+ return this.getHandle().immuneToExplosion;
+ }
+
+ @Override
+ public void setImmuneToFire(boolean immuneToFire) {
+ item.immuneToFire = immuneToFire;
+ }
+
+ @Override
+ public boolean isImmuneToFire() {
+ return this.getHandle().immuneToFire;
+ }
+
+ @Override
+ public void setImmuneToLightning(boolean immuneToLightning) {
+ this.getHandle().immuneToLightning = immuneToLightning;
+ }
+
+ @Override
+ public boolean isImmuneToLightning() {
+ return this.getHandle().immuneToLightning;
+ }
+ // Purpur end
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index bc355a6b03877ca5e74688df13a089b487cde86c..a750c73519b43f28b0fea69e6056e2752d2eed35 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -120,6 +120,49 @@ public class PurpurWorldConfig {
elytraDamagePerTridentBoost = getInt("gameplay-mechanics.elytra.damage-per-boost.trident", elytraDamagePerTridentBoost);
}
+ public List<Item> itemImmuneToCactus = new ArrayList<>();
+ public List<Item> itemImmuneToExplosion = new ArrayList<>();
+ public List<Item> itemImmuneToFire = new ArrayList<>();
+ public List<Item> itemImmuneToLightning = new ArrayList<>();
+ private void itemSettings() {
+ itemImmuneToCactus.clear();
+ getList("gameplay-mechanics.item.immune.cactus", new ArrayList<>()).forEach(key -> {
+ if (key.toString().equals("*")) {
+ BuiltInRegistries.ITEM.stream().filter(item -> item != Items.AIR).forEach((item) -> itemImmuneToCactus.add(item));
+ return;
+ }
+ Item item = BuiltInRegistries.ITEM.getValue(ResourceLocation.parse(key.toString()));
+ if (item != Items.AIR) itemImmuneToCactus.add(item);
+ });
+ itemImmuneToExplosion.clear();
+ getList("gameplay-mechanics.item.immune.explosion", new ArrayList<>()).forEach(key -> {
+ if (key.toString().equals("*")) {
+ BuiltInRegistries.ITEM.stream().filter(item -> item != Items.AIR).forEach((item) -> itemImmuneToExplosion.add(item));
+ return;
+ }
+ Item item = BuiltInRegistries.ITEM.getValue(ResourceLocation.parse(key.toString()));
+ if (item != Items.AIR) itemImmuneToExplosion.add(item);
+ });
+ itemImmuneToFire.clear();
+ getList("gameplay-mechanics.item.immune.fire", new ArrayList<>()).forEach(key -> {
+ if (key.toString().equals("*")) {
+ BuiltInRegistries.ITEM.stream().filter(item -> item != Items.AIR).forEach((item) -> itemImmuneToFire.add(item));
+ return;
+ }
+ Item item = BuiltInRegistries.ITEM.getValue(ResourceLocation.parse(key.toString()));
+ if (item != Items.AIR) itemImmuneToFire.add(item);
+ });
+ itemImmuneToLightning.clear();
+ getList("gameplay-mechanics.item.immune.lightning", new ArrayList<>()).forEach(key -> {
+ if (key.toString().equals("*")) {
+ BuiltInRegistries.ITEM.stream().filter(item -> item != Items.AIR).forEach((item) -> itemImmuneToLightning.add(item));
+ return;
+ }
+ Item item = BuiltInRegistries.ITEM.getValue(ResourceLocation.parse(key.toString()));
+ if (item != Items.AIR) itemImmuneToLightning.add(item);
+ });
+ }
+
public double minecartMaxSpeed = 0.4D;
public boolean minecartPlaceAnywhere = false;
public boolean minecartControllable = false;

View File

@@ -1,77 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Fri, 13 Mar 2020 22:29:10 -0500
Subject: [PATCH] Add ping command
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
index 1210305bcfc8a1158dbdc3c21647502a01b138a3..e721dbe479b667dee605153754e50b3fc140bb42 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
@@ -255,6 +255,7 @@ public class Commands {
StopCommand.register(this.dispatcher);
TransferCommand.register(this.dispatcher);
WhitelistCommand.register(this.dispatcher);
+ org.purpurmc.purpur.command.PingCommand.register(this.dispatcher); // Purpur
}
if (environment.includeIntegrated) {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index c8e7e6333d20ca976ed74d839ccfaebdc02e5167..0cad1ea803e4882601fcd05cfa575d03ffd77b04 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -182,6 +182,7 @@ public class PurpurConfig {
public static boolean afkBroadcastUseDisplayName = false;
public static String afkTabListPrefix = "[AFK] ";
public static String afkTabListSuffix = "";
+ public static String pingCommandOutput = "<green>%s's ping is %sms";
private static void messages() {
cannotRideMob = getString("settings.messages.cannot-ride-mob", cannotRideMob);
afkBroadcastAway = getString("settings.messages.afk-broadcast-away", afkBroadcastAway);
@@ -189,6 +190,7 @@ public class PurpurConfig {
afkBroadcastUseDisplayName = getBoolean("settings.messages.afk-broadcast-use-display-name", afkBroadcastUseDisplayName);
afkTabListPrefix = MiniMessage.miniMessage().serialize(MiniMessage.miniMessage().deserialize(getString("settings.messages.afk-tab-list-prefix", afkTabListPrefix)));
afkTabListSuffix = MiniMessage.miniMessage().serialize(MiniMessage.miniMessage().deserialize(getString("settings.messages.afk-tab-list-suffix", afkTabListSuffix)));
+ pingCommandOutput = getString("settings.messages.ping-command-output", pingCommandOutput);
}
public static String serverModName = io.papermc.paper.ServerBuildInfo.buildInfo().brandName();
diff --git a/src/main/java/org/purpurmc/purpur/command/PingCommand.java b/src/main/java/org/purpurmc/purpur/command/PingCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..f202b98a194604e39798fdb8e417c6d2835f71c8
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/command/PingCommand.java
@@ -0,0 +1,33 @@
+package org.purpurmc.purpur.command;
+
+import com.mojang.brigadier.CommandDispatcher;
+import net.minecraft.commands.CommandSourceStack;
+import net.minecraft.commands.Commands;
+import net.minecraft.commands.arguments.EntityArgument;
+import net.minecraft.server.level.ServerPlayer;
+import org.purpurmc.purpur.PurpurConfig;
+import org.bukkit.craftbukkit.util.CraftChatMessage;
+
+import java.util.Collection;
+import java.util.Collections;
+
+public class PingCommand {
+ public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
+ dispatcher.register(Commands.literal("ping")
+ .requires((listener) -> listener.hasPermission(2, "bukkit.command.ping"))
+ .executes((context) -> execute(context.getSource(), Collections.singleton(context.getSource().getPlayerOrException())))
+ .then(Commands.argument("targets", EntityArgument.players())
+ .requires(listener -> listener.hasPermission(2, "bukkit.command.ping.other"))
+ .executes((context) -> execute(context.getSource(), EntityArgument.getPlayers(context, "targets")))
+ )
+ );
+ }
+
+ private static int execute(CommandSourceStack sender, Collection<ServerPlayer> targets) {
+ for (ServerPlayer player : targets) {
+ String output = String.format(PurpurConfig.pingCommandOutput, player.getGameProfile().getName(), player.connection.latency());
+ sender.sendSuccess(output, false);
+ }
+ return targets.size();
+ }
+}

View File

@@ -1,79 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Mon, 30 Nov 2020 03:12:04 -0600
Subject: [PATCH] Add demo command
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
index e721dbe479b667dee605153754e50b3fc140bb42..839cc754fea89067fc3e4473e3e808f4df53f123 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
@@ -255,6 +255,7 @@ public class Commands {
StopCommand.register(this.dispatcher);
TransferCommand.register(this.dispatcher);
WhitelistCommand.register(this.dispatcher);
+ org.purpurmc.purpur.command.DemoCommand.register(this.dispatcher); // Purpur
org.purpurmc.purpur.command.PingCommand.register(this.dispatcher); // Purpur
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index 0cad1ea803e4882601fcd05cfa575d03ffd77b04..438a60ae155f05c667ae887a2ae44b05df7977e2 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -182,6 +182,7 @@ public class PurpurConfig {
public static boolean afkBroadcastUseDisplayName = false;
public static String afkTabListPrefix = "[AFK] ";
public static String afkTabListSuffix = "";
+ public static String demoCommandOutput = "<green>%s has been shown the demo screen";
public static String pingCommandOutput = "<green>%s's ping is %sms";
private static void messages() {
cannotRideMob = getString("settings.messages.cannot-ride-mob", cannotRideMob);
@@ -190,6 +191,7 @@ public class PurpurConfig {
afkBroadcastUseDisplayName = getBoolean("settings.messages.afk-broadcast-use-display-name", afkBroadcastUseDisplayName);
afkTabListPrefix = MiniMessage.miniMessage().serialize(MiniMessage.miniMessage().deserialize(getString("settings.messages.afk-tab-list-prefix", afkTabListPrefix)));
afkTabListSuffix = MiniMessage.miniMessage().serialize(MiniMessage.miniMessage().deserialize(getString("settings.messages.afk-tab-list-suffix", afkTabListSuffix)));
+ demoCommandOutput = getString("settings.messages.demo-command-output", demoCommandOutput);
pingCommandOutput = getString("settings.messages.ping-command-output", pingCommandOutput);
}
diff --git a/src/main/java/org/purpurmc/purpur/command/DemoCommand.java b/src/main/java/org/purpurmc/purpur/command/DemoCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..235f3cd89f675b70a6152a00534608c0902f19fd
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/command/DemoCommand.java
@@ -0,0 +1,35 @@
+package org.purpurmc.purpur.command;
+
+import com.mojang.brigadier.CommandDispatcher;
+import net.minecraft.commands.CommandSourceStack;
+import net.minecraft.commands.Commands;
+import net.minecraft.commands.arguments.EntityArgument;
+import net.minecraft.network.protocol.game.ClientboundGameEventPacket;
+import net.minecraft.server.level.ServerPlayer;
+import org.purpurmc.purpur.PurpurConfig;
+
+import java.util.Collection;
+import java.util.Collections;
+
+public class DemoCommand {
+ public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
+ dispatcher.register(Commands.literal("demo")
+ .requires((listener) -> listener.hasPermission(2, "bukkit.command.demo"))
+ .executes((context) -> execute(context.getSource(), Collections.singleton(context.getSource().getPlayerOrException())))
+ .then(Commands.argument("targets", EntityArgument.players())
+ .requires(listener -> listener.hasPermission(2, "bukkit.command.demo.other"))
+ .executes((context) -> execute(context.getSource(), EntityArgument.getPlayers(context, "targets")))
+ )
+ );
+ }
+
+ private static int execute(CommandSourceStack sender, Collection<ServerPlayer> targets) {
+ for (ServerPlayer player : targets) {
+ ClientboundGameEventPacket packet = new ClientboundGameEventPacket(ClientboundGameEventPacket.DEMO_EVENT, 0);
+ player.connection.send(packet);
+ String output = String.format(PurpurConfig.demoCommandOutput, player.getGameProfile().getName());
+ sender.sendSuccess(output, false);
+ }
+ return targets.size();
+ }
+}

View File

@@ -1,79 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Fri, 30 Apr 2021 14:03:06 -0400
Subject: [PATCH] Add credits command
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
index 839cc754fea89067fc3e4473e3e808f4df53f123..02c7b57eef9a4462af413415ff268b9daeea0b93 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
@@ -255,6 +255,7 @@ public class Commands {
StopCommand.register(this.dispatcher);
TransferCommand.register(this.dispatcher);
WhitelistCommand.register(this.dispatcher);
+ org.purpurmc.purpur.command.CreditsCommand.register(this.dispatcher); // Purpur
org.purpurmc.purpur.command.DemoCommand.register(this.dispatcher); // Purpur
org.purpurmc.purpur.command.PingCommand.register(this.dispatcher); // Purpur
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index 438a60ae155f05c667ae887a2ae44b05df7977e2..6228d23bd84e59a9e1f01414cc9f00c33cc64cd0 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -182,6 +182,7 @@ public class PurpurConfig {
public static boolean afkBroadcastUseDisplayName = false;
public static String afkTabListPrefix = "[AFK] ";
public static String afkTabListSuffix = "";
+ public static String creditsCommandOutput = "<green>%s has been shown the end credits";
public static String demoCommandOutput = "<green>%s has been shown the demo screen";
public static String pingCommandOutput = "<green>%s's ping is %sms";
private static void messages() {
@@ -191,6 +192,7 @@ public class PurpurConfig {
afkBroadcastUseDisplayName = getBoolean("settings.messages.afk-broadcast-use-display-name", afkBroadcastUseDisplayName);
afkTabListPrefix = MiniMessage.miniMessage().serialize(MiniMessage.miniMessage().deserialize(getString("settings.messages.afk-tab-list-prefix", afkTabListPrefix)));
afkTabListSuffix = MiniMessage.miniMessage().serialize(MiniMessage.miniMessage().deserialize(getString("settings.messages.afk-tab-list-suffix", afkTabListSuffix)));
+ creditsCommandOutput = getString("settings.messages.credits-command-output", creditsCommandOutput);
demoCommandOutput = getString("settings.messages.demo-command-output", demoCommandOutput);
pingCommandOutput = getString("settings.messages.ping-command-output", pingCommandOutput);
}
diff --git a/src/main/java/org/purpurmc/purpur/command/CreditsCommand.java b/src/main/java/org/purpurmc/purpur/command/CreditsCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..40d2fab4a9728ac90c36e30c130f3116b7025d11
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/command/CreditsCommand.java
@@ -0,0 +1,35 @@
+package org.purpurmc.purpur.command;
+
+import com.mojang.brigadier.CommandDispatcher;
+import net.minecraft.commands.CommandSourceStack;
+import net.minecraft.commands.Commands;
+import net.minecraft.commands.arguments.EntityArgument;
+import net.minecraft.network.protocol.game.ClientboundGameEventPacket;
+import net.minecraft.server.level.ServerPlayer;
+import org.purpurmc.purpur.PurpurConfig;
+
+import java.util.Collection;
+import java.util.Collections;
+
+public class CreditsCommand {
+ public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
+ dispatcher.register(Commands.literal("credits")
+ .requires((listener) -> listener.hasPermission(2, "bukkit.command.credits"))
+ .executes((context) -> execute(context.getSource(), Collections.singleton(context.getSource().getPlayerOrException())))
+ .then(Commands.argument("targets", EntityArgument.players())
+ .requires(listener -> listener.hasPermission(2, "bukkit.command.credits.other"))
+ .executes((context) -> execute(context.getSource(), EntityArgument.getPlayers(context, "targets")))
+ )
+ );
+ }
+
+ private static int execute(CommandSourceStack sender, Collection<ServerPlayer> targets) {
+ for (ServerPlayer player : targets) {
+ ClientboundGameEventPacket packet = new ClientboundGameEventPacket(ClientboundGameEventPacket.WIN_GAME, 1F);
+ player.connection.send(packet);
+ String output = String.format(PurpurConfig.creditsCommandOutput, player.getGameProfile().getName());
+ sender.sendSuccess(output, false);
+ }
+ return targets.size();
+ }
+}

View File

@@ -1,271 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 26 Mar 2020 21:39:32 -0500
Subject: [PATCH] Configurable jockey options
diff --git a/src/main/java/net/minecraft/world/entity/monster/Drowned.java b/src/main/java/net/minecraft/world/entity/monster/Drowned.java
index 0b572267d929ef362b6e65c55846ef12412951ba..7dc7f8734ffb3c5e50c763cb4e750d20c6e22281 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Drowned.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Drowned.java
@@ -100,6 +100,21 @@ public class Drowned extends Zombie implements RangedAttackMob {
this.getAttribute(Attributes.SPAWN_REINFORCEMENTS_CHANCE).setBaseValue(this.random.nextDouble() * this.level().purpurConfig.drownedSpawnReinforcements);
}
+ @Override
+ public boolean jockeyOnlyBaby() {
+ return level().purpurConfig.drownedJockeyOnlyBaby;
+ }
+
+ @Override
+ public double jockeyChance() {
+ return level().purpurConfig.drownedJockeyChance;
+ }
+
+ @Override
+ public boolean jockeyTryExistingChickens() {
+ return level().purpurConfig.drownedJockeyTryExistingChickens;
+ }
+
@Override
protected void addBehaviourGoals() {
this.goalSelector.addGoal(1, new Drowned.DrownedGoToWaterGoal(this, 1.0));
diff --git a/src/main/java/net/minecraft/world/entity/monster/Husk.java b/src/main/java/net/minecraft/world/entity/monster/Husk.java
index d9dbcd15522301344770963a6e3592afe393861a..ed4b1e2df6d7c7dfa45d96b9c08f2aa429ad32c5 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Husk.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Husk.java
@@ -50,6 +50,21 @@ public class Husk extends Zombie {
this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.SPAWN_REINFORCEMENTS_CHANCE).setBaseValue(this.random.nextDouble() * this.level().purpurConfig.huskSpawnReinforcements);
}
+ @Override
+ public boolean jockeyOnlyBaby() {
+ return level().purpurConfig.huskJockeyOnlyBaby;
+ }
+
+ @Override
+ public double jockeyChance() {
+ return level().purpurConfig.huskJockeyChance;
+ }
+
+ @Override
+ public boolean jockeyTryExistingChickens() {
+ return level().purpurConfig.huskJockeyTryExistingChickens;
+ }
+
public static boolean checkHuskSpawnRules(EntityType<Husk> type, ServerLevelAccessor world, EntitySpawnReason spawnReason, BlockPos pos, RandomSource random) {
return checkMonsterSpawnRules(type, world, spawnReason, pos, random) && (EntitySpawnReason.isSpawner(spawnReason) || world.canSeeSky(pos));
}
diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
index 978f610d31312f36093c0111ce623d1157fa943d..cb5cf34781de4e87074a70a447fd463280147bdc 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
@@ -133,6 +133,18 @@ public class Zombie extends Monster {
this.getAttribute(Attributes.SCALE).setBaseValue(this.level().purpurConfig.zombieScale);
}
+ public boolean jockeyOnlyBaby() {
+ return level().purpurConfig.zombieJockeyOnlyBaby;
+ }
+
+ public double jockeyChance() {
+ return level().purpurConfig.zombieJockeyChance;
+ }
+
+ public boolean jockeyTryExistingChickens() {
+ return level().purpurConfig.zombieJockeyTryExistingChickens;
+ }
+
@Override
protected void registerGoals() {
this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur
@@ -553,19 +565,20 @@ public class Zombie extends Monster {
}
if (object instanceof Zombie.ZombieGroupData entityzombie_groupdatazombie) {
- if (entityzombie_groupdatazombie.isBaby) {
- this.setBaby(true);
+ // Purpur start
+ if (!jockeyOnlyBaby() || entityzombie_groupdatazombie.isBaby) {
+ this.setBaby(entityzombie_groupdatazombie.isBaby);
if (entityzombie_groupdatazombie.canSpawnJockey) {
- if ((double) randomsource.nextFloat() < 0.05D) {
- List<Chicken> list = world.getEntitiesOfClass(Chicken.class, this.getBoundingBox().inflate(5.0D, 3.0D, 5.0D), EntitySelector.ENTITY_NOT_BEING_RIDDEN);
+ if ((double) randomsource.nextFloat() < jockeyChance()) {
+ List<Chicken> list = jockeyTryExistingChickens() ? world.getEntitiesOfClass(Chicken.class, this.getBoundingBox().inflate(5.0D, 3.0D, 5.0D), EntitySelector.ENTITY_NOT_BEING_RIDDEN) : java.util.Collections.emptyList();
+ // Purpur end
if (!list.isEmpty()) {
Chicken entitychicken = (Chicken) list.get(0);
entitychicken.setChickenJockey(true);
this.startRiding(entitychicken);
- }
- } else if ((double) randomsource.nextFloat() < 0.05D) {
+ } else { // Purpur
Chicken entitychicken1 = (Chicken) EntityType.CHICKEN.create(this.level(), EntitySpawnReason.JOCKEY);
if (entitychicken1 != null) {
@@ -575,6 +588,7 @@ public class Zombie extends Monster {
this.startRiding(entitychicken1);
world.addFreshEntity(entitychicken1, CreatureSpawnEvent.SpawnReason.MOUNT); // CraftBukkit
}
+ } // Purpur
}
}
}
diff --git a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java
index a2447844a6a6e08d41bb5152d01da91c852665cf..eb6daba7d44542739f1c537cbeef8f87c6db61bf 100644
--- a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java
+++ b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java
@@ -112,6 +112,21 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder {
this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.SPAWN_REINFORCEMENTS_CHANCE).setBaseValue(this.random.nextDouble() * this.level().purpurConfig.zombieVillagerSpawnReinforcements);
}
+ @Override
+ public boolean jockeyOnlyBaby() {
+ return level().purpurConfig.zombieVillagerJockeyOnlyBaby;
+ }
+
+ @Override
+ public double jockeyChance() {
+ return level().purpurConfig.zombieVillagerJockeyChance;
+ }
+
+ @Override
+ public boolean jockeyTryExistingChickens() {
+ return level().purpurConfig.zombieVillagerJockeyTryExistingChickens;
+ }
+
@Override
protected void defineSynchedData(SynchedEntityData.Builder builder) {
super.defineSynchedData(builder);
diff --git a/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java b/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java
index ba1ce7e0ed888bd47312e9d7da5426f5c1015d07..650f9e1ca3a5ddec5123133c9604f33140e948a8 100644
--- a/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java
+++ b/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java
@@ -86,6 +86,21 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob {
this.getAttribute(Attributes.SCALE).setBaseValue(this.level().purpurConfig.zombifiedPiglinScale);
}
+ @Override
+ public boolean jockeyOnlyBaby() {
+ return level().purpurConfig.zombifiedPiglinJockeyOnlyBaby;
+ }
+
+ @Override
+ public double jockeyChance() {
+ return level().purpurConfig.zombifiedPiglinJockeyChance;
+ }
+
+ @Override
+ public boolean jockeyTryExistingChickens() {
+ return level().purpurConfig.zombifiedPiglinJockeyTryExistingChickens;
+ }
+
@Override
public void setPersistentAngerTarget(@Nullable UUID angryAt) {
this.persistentAngerTarget = angryAt;
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index a750c73519b43f28b0fea69e6056e2752d2eed35..bb8aa3d4e33e2d8ed4bf3fd668577ea901410783 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -649,6 +649,9 @@ public class PurpurWorldConfig {
public double drownedMaxHealth = 20.0D;
public double drownedScale = 1.0D;
public double drownedSpawnReinforcements = 0.1D;
+ public boolean drownedJockeyOnlyBaby = true;
+ public double drownedJockeyChance = 0.05D;
+ public boolean drownedJockeyTryExistingChickens = true;
private void drownedSettings() {
drownedRidable = getBoolean("mobs.drowned.ridable", drownedRidable);
drownedRidableInWater = getBoolean("mobs.drowned.ridable-in-water", drownedRidableInWater);
@@ -661,6 +664,9 @@ public class PurpurWorldConfig {
drownedMaxHealth = getDouble("mobs.drowned.attributes.max_health", drownedMaxHealth);
drownedScale = Mth.clamp(getDouble("mobs.drowned.attributes.scale", drownedScale), 0.0625D, 16.0D);
drownedSpawnReinforcements = getDouble("mobs.drowned.attributes.spawn_reinforcements", drownedSpawnReinforcements);
+ drownedJockeyOnlyBaby = getBoolean("mobs.drowned.jockey.only-babies", drownedJockeyOnlyBaby);
+ drownedJockeyChance = getDouble("mobs.drowned.jockey.chance", drownedJockeyChance);
+ drownedJockeyTryExistingChickens = getBoolean("mobs.drowned.jockey.try-existing-chickens", drownedJockeyTryExistingChickens);
}
public boolean elderGuardianRidable = false;
@@ -932,6 +938,9 @@ public class PurpurWorldConfig {
public double huskMaxHealth = 20.0D;
public double huskScale = 1.0D;
public double huskSpawnReinforcements = 0.1D;
+ public boolean huskJockeyOnlyBaby = true;
+ public double huskJockeyChance = 0.05D;
+ public boolean huskJockeyTryExistingChickens = true;
private void huskSettings() {
huskRidable = getBoolean("mobs.husk.ridable", huskRidable);
huskRidableInWater = getBoolean("mobs.husk.ridable-in-water", huskRidableInWater);
@@ -944,6 +953,9 @@ public class PurpurWorldConfig {
huskMaxHealth = getDouble("mobs.husk.attributes.max_health", huskMaxHealth);
huskScale = Mth.clamp(getDouble("mobs.husk.attributes.scale", huskScale), 0.0625D, 16.0D);
huskSpawnReinforcements = getDouble("mobs.husk.attributes.spawn_reinforcements", huskSpawnReinforcements);
+ huskJockeyOnlyBaby = getBoolean("mobs.husk.jockey.only-babies", huskJockeyOnlyBaby);
+ huskJockeyChance = getDouble("mobs.husk.jockey.chance", huskJockeyChance);
+ huskJockeyTryExistingChickens = getBoolean("mobs.husk.jockey.try-existing-chickens", huskJockeyTryExistingChickens);
}
public boolean illusionerRidable = false;
@@ -1841,6 +1853,9 @@ public class PurpurWorldConfig {
public double zombieMaxHealth = 20.0D;
public double zombieScale = 1.0D;
public double zombieSpawnReinforcements = 0.1D;
+ public boolean zombieJockeyOnlyBaby = true;
+ public double zombieJockeyChance = 0.05D;
+ public boolean zombieJockeyTryExistingChickens = true;
private void zombieSettings() {
zombieRidable = getBoolean("mobs.zombie.ridable", zombieRidable);
zombieRidableInWater = getBoolean("mobs.zombie.ridable-in-water", zombieRidableInWater);
@@ -1853,6 +1868,9 @@ public class PurpurWorldConfig {
zombieMaxHealth = getDouble("mobs.zombie.attributes.max_health", zombieMaxHealth);
zombieScale = Mth.clamp(getDouble("mobs.zombie.attributes.scale", zombieScale), 0.0625D, 16.0D);
zombieSpawnReinforcements = getDouble("mobs.zombie.attributes.spawn_reinforcements", zombieSpawnReinforcements);
+ zombieJockeyOnlyBaby = getBoolean("mobs.zombie.jockey.only-babies", zombieJockeyOnlyBaby);
+ zombieJockeyChance = getDouble("mobs.zombie.jockey.chance", zombieJockeyChance);
+ zombieJockeyTryExistingChickens = getBoolean("mobs.zombie.jockey.try-existing-chickens", zombieJockeyTryExistingChickens);
}
public boolean zombieHorseRidable = false;
@@ -1890,6 +1908,9 @@ public class PurpurWorldConfig {
public double zombieVillagerMaxHealth = 20.0D;
public double zombieVillagerScale = 1.0D;
public double zombieVillagerSpawnReinforcements = 0.1D;
+ public boolean zombieVillagerJockeyOnlyBaby = true;
+ public double zombieVillagerJockeyChance = 0.05D;
+ public boolean zombieVillagerJockeyTryExistingChickens = true;
private void zombieVillagerSettings() {
zombieVillagerRidable = getBoolean("mobs.zombie_villager.ridable", zombieVillagerRidable);
zombieVillagerRidableInWater = getBoolean("mobs.zombie_villager.ridable-in-water", zombieVillagerRidableInWater);
@@ -1902,6 +1923,9 @@ public class PurpurWorldConfig {
zombieVillagerMaxHealth = getDouble("mobs.zombie_villager.attributes.max_health", zombieVillagerMaxHealth);
zombieVillagerScale = Mth.clamp(getDouble("mobs.zombie_villager.attributes.scale", zombieVillagerScale), 0.0625D, 16.0D);
zombieVillagerSpawnReinforcements = getDouble("mobs.zombie_villager.attributes.spawn_reinforcements", zombieVillagerSpawnReinforcements);
+ zombieVillagerJockeyOnlyBaby = getBoolean("mobs.zombie_villager.jockey.only-babies", zombieVillagerJockeyOnlyBaby);
+ zombieVillagerJockeyChance = getDouble("mobs.zombie_villager.jockey.chance", zombieVillagerJockeyChance);
+ zombieVillagerJockeyTryExistingChickens = getBoolean("mobs.zombie_villager.jockey.try-existing-chickens", zombieVillagerJockeyTryExistingChickens);
}
public boolean zombifiedPiglinRidable = false;
@@ -1910,6 +1934,9 @@ public class PurpurWorldConfig {
public double zombifiedPiglinMaxHealth = 20.0D;
public double zombifiedPiglinScale = 1.0D;
public double zombifiedPiglinSpawnReinforcements = 0.0D;
+ public boolean zombifiedPiglinJockeyOnlyBaby = true;
+ public double zombifiedPiglinJockeyChance = 0.05D;
+ public boolean zombifiedPiglinJockeyTryExistingChickens = true;
private void zombifiedPiglinSettings() {
zombifiedPiglinRidable = getBoolean("mobs.zombified_piglin.ridable", zombifiedPiglinRidable);
zombifiedPiglinRidableInWater = getBoolean("mobs.zombified_piglin.ridable-in-water", zombifiedPiglinRidableInWater);
@@ -1922,5 +1949,8 @@ public class PurpurWorldConfig {
zombifiedPiglinMaxHealth = getDouble("mobs.zombified_piglin.attributes.max_health", zombifiedPiglinMaxHealth);
zombifiedPiglinScale = Mth.clamp(getDouble("mobs.zombified_piglin.attributes.scale", zombifiedPiglinScale), 0.0625D, 16.0D);
zombifiedPiglinSpawnReinforcements = getDouble("mobs.zombified_piglin.attributes.spawn_reinforcements", zombifiedPiglinSpawnReinforcements);
+ zombifiedPiglinJockeyOnlyBaby = getBoolean("mobs.zombified_piglin.jockey.only-babies", zombifiedPiglinJockeyOnlyBaby);
+ zombifiedPiglinJockeyChance = getDouble("mobs.zombified_piglin.jockey.chance", zombifiedPiglinJockeyChance);
+ zombifiedPiglinJockeyTryExistingChickens = getBoolean("mobs.zombified_piglin.jockey.try-existing-chickens", zombifiedPiglinJockeyTryExistingChickens);
}
}

View File

@@ -1,281 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 9 May 2019 18:26:06 -0500
Subject: [PATCH] Phantoms attracted to crystals and crystals shoot phantoms
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
index 7cb3d69a69e0e3ef4b7f9f9c8b1eb67edb5d116d..4c9709e680b585316978b6a410600a8a3b4b6e3e 100644
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
@@ -31,6 +31,12 @@ public class EndCrystal extends Entity {
private static final EntityDataAccessor<Boolean> DATA_SHOW_BOTTOM = SynchedEntityData.defineId(EndCrystal.class, EntityDataSerializers.BOOLEAN);
public int time;
public boolean generatedByDragonFight = false; // Paper - Fix invulnerable end crystals
+ // Purpur start
+ private net.minecraft.world.entity.monster.Phantom targetPhantom;
+ private int phantomBeamTicks = 0;
+ private int phantomDamageCooldown = 0;
+ private int idleCooldown = 0;
+ // Purpur end
public EndCrystal(EntityType<? extends EndCrystal> type, Level world) {
super(type, world);
@@ -82,6 +88,49 @@ public class EndCrystal extends Entity {
// Paper end - Fix invulnerable end crystals
}
+ // Purpur start
+ if (level().purpurConfig.phantomAttackedByCrystalRadius <= 0 || --idleCooldown > 0) {
+ return; // on cooldown
+ }
+
+ if (targetPhantom == null) {
+ for (net.minecraft.world.entity.monster.Phantom phantom : level().getEntitiesOfClass(net.minecraft.world.entity.monster.Phantom.class, getBoundingBox().inflate(level().purpurConfig.phantomAttackedByCrystalRadius))) {
+ if (phantom.hasLineOfSight(this)) {
+ attackPhantom(phantom);
+ break;
+ }
+ }
+ } else {
+ setBeamTarget(new BlockPos(targetPhantom).offset(0, -2, 0));
+ if (--phantomBeamTicks > 0 && targetPhantom.isAlive()) {
+ phantomDamageCooldown--;
+ if (targetPhantom.hasLineOfSight(this)) {
+ if (phantomDamageCooldown <= 0) {
+ phantomDamageCooldown = 20;
+ targetPhantom.hurt(targetPhantom.damageSources().indirectMagic(this, this), level().purpurConfig.phantomAttackedByCrystalDamage);
+ }
+ } else {
+ forgetPhantom(); // no longer in sight
+ }
+ } else {
+ forgetPhantom(); // attacked long enough
+ }
+ }
+ }
+
+ private void attackPhantom(net.minecraft.world.entity.monster.Phantom phantom) {
+ phantomDamageCooldown = 0;
+ phantomBeamTicks = 60;
+ targetPhantom = phantom;
+ }
+
+ private void forgetPhantom() {
+ targetPhantom = null;
+ setBeamTarget(null);
+ phantomBeamTicks = 0;
+ phantomDamageCooldown = 0;
+ idleCooldown = 60;
+ // Purpur end
}
@Override
diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
index e44d6d02ceaf1f133705efcd58b94e36014389ec..bd1c23d849269df504c94da9d0ca0a6846b22c41 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
@@ -49,6 +49,7 @@ public class Phantom extends FlyingMob implements Enemy {
Vec3 moveTargetPoint;
public BlockPos anchorPoint;
Phantom.AttackPhase attackPhase;
+ Vec3 crystalPosition; // Purpur
public Phantom(EntityType<? extends Phantom> type, Level world) {
super(type, world);
@@ -116,6 +117,23 @@ public class Phantom extends FlyingMob implements Enemy {
level().addFreshEntity(flames);
return true;
}
+
+ @Override
+ protected void dropFromLootTable(ServerLevel world, DamageSource damageSource, boolean causedByPlayer) {
+ boolean dropped = false;
+ if (lastHurtByPlayer == null && damageSource.getEntity() instanceof net.minecraft.world.entity.boss.enderdragon.EndCrystal) {
+ if (random.nextInt(5) < 1) {
+ dropped = spawnAtLocation(world, new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.PHANTOM_MEMBRANE)) != null;
+ }
+ }
+ if (!dropped) {
+ super.dropFromLootTable(world, damageSource, causedByPlayer);
+ }
+ }
+
+ public boolean isCirclingCrystal() {
+ return crystalPosition != null;
+ }
// Purpur end
@Override
@@ -130,11 +148,17 @@ public class Phantom extends FlyingMob implements Enemy {
@Override
protected void registerGoals() {
- this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur
- this.goalSelector.addGoal(1, new Phantom.PhantomAttackStrategyGoal());
- this.goalSelector.addGoal(2, new Phantom.PhantomSweepAttackGoal());
- this.goalSelector.addGoal(3, new Phantom.PhantomCircleAroundAnchorGoal());
- this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur
+ // Purpur start
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this));
+ if (level().purpurConfig.phantomOrbitCrystalRadius > 0) {
+ this.goalSelector.addGoal(1, new FindCrystalGoal(this));
+ this.goalSelector.addGoal(2, new OrbitCrystalGoal(this));
+ }
+ this.goalSelector.addGoal(3, new Phantom.PhantomAttackStrategyGoal());
+ this.goalSelector.addGoal(4, new Phantom.PhantomSweepAttackGoal());
+ this.goalSelector.addGoal(5, new Phantom.PhantomCircleAroundAnchorGoal());
+ this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this));
+ // Purpur end
this.targetSelector.addGoal(1, new Phantom.PhantomAttackPlayerTargetGoal());
}
@@ -333,6 +357,124 @@ public class Phantom extends FlyingMob implements Enemy {
private AttackPhase() {}
}
+ // Purpur start
+ class FindCrystalGoal extends Goal {
+ private final Phantom phantom;
+ private net.minecraft.world.entity.boss.enderdragon.EndCrystal crystal;
+ private Comparator<net.minecraft.world.entity.boss.enderdragon.EndCrystal> comparator;
+
+ FindCrystalGoal(Phantom phantom) {
+ this.phantom = phantom;
+ this.comparator = Comparator.comparingDouble(phantom::distanceToSqr);
+ this.setFlags(EnumSet.of(Flag.LOOK));
+ }
+
+ @Override
+ public boolean canUse() {
+ double range = maxTargetRange();
+ List<net.minecraft.world.entity.boss.enderdragon.EndCrystal> crystals = level().getEntitiesOfClass(net.minecraft.world.entity.boss.enderdragon.EndCrystal.class, phantom.getBoundingBox().inflate(range));
+ if (crystals.isEmpty()) {
+ return false;
+ }
+ crystals.sort(comparator);
+ crystal = crystals.get(0);
+ if (phantom.distanceToSqr(crystal) > range * range) {
+ crystal = null;
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean canContinueToUse() {
+ if (crystal == null || !crystal.isAlive()) {
+ return false;
+ }
+ double range = maxTargetRange();
+ return phantom.distanceToSqr(crystal) <= (range * range) * 2;
+ }
+
+ @Override
+ public void start() {
+ phantom.crystalPosition = new Vec3(crystal.getX(), crystal.getY() + (phantom.random.nextInt(10) + 10), crystal.getZ());
+ }
+
+ @Override
+ public void stop() {
+ crystal = null;
+ phantom.crystalPosition = null;
+ super.stop();
+ }
+
+ private double maxTargetRange() {
+ return phantom.level().purpurConfig.phantomOrbitCrystalRadius;
+ }
+ }
+
+ class OrbitCrystalGoal extends Goal {
+ private final Phantom phantom;
+ private float offset;
+ private float radius;
+ private float verticalChange;
+ private float direction;
+
+ OrbitCrystalGoal(Phantom phantom) {
+ this.phantom = phantom;
+ this.setFlags(EnumSet.of(Flag.MOVE));
+ }
+
+ @Override
+ public boolean canUse() {
+ return phantom.isCirclingCrystal();
+ }
+
+ @Override
+ public void start() {
+ this.radius = 5.0F + phantom.random.nextFloat() * 10.0F;
+ this.verticalChange = -4.0F + phantom.random.nextFloat() * 9.0F;
+ this.direction = phantom.random.nextBoolean() ? 1.0F : -1.0F;
+ updateOffset();
+ }
+
+ @Override
+ public void tick() {
+ if (phantom.random.nextInt(350) == 0) {
+ this.verticalChange = -4.0F + phantom.random.nextFloat() * 9.0F;
+ }
+ if (phantom.random.nextInt(250) == 0) {
+ ++this.radius;
+ if (this.radius > 15.0F) {
+ this.radius = 5.0F;
+ this.direction = -this.direction;
+ }
+ }
+ if (phantom.random.nextInt(450) == 0) {
+ this.offset = phantom.random.nextFloat() * 2.0F * 3.1415927F;
+ updateOffset();
+ }
+ if (phantom.moveTargetPoint.distanceToSqr(phantom.getX(), phantom.getY(), phantom.getZ()) < 4.0D) {
+ updateOffset();
+ }
+ if (phantom.moveTargetPoint.y < phantom.getY() && !phantom.level().isEmptyBlock(new BlockPos(phantom).below(1))) {
+ this.verticalChange = Math.max(1.0F, this.verticalChange);
+ updateOffset();
+ }
+ if (phantom.moveTargetPoint.y > phantom.getY() && !phantom.level().isEmptyBlock(new BlockPos(phantom).above(1))) {
+ this.verticalChange = Math.min(-1.0F, this.verticalChange);
+ updateOffset();
+ }
+ }
+
+ private void updateOffset() {
+ this.offset += this.direction * 15.0F * 0.017453292F;
+ phantom.moveTargetPoint = phantom.crystalPosition.add(
+ this.radius * Mth.cos(this.offset),
+ -4.0F + this.verticalChange,
+ this.radius * Mth.sin(this.offset));
+ }
+ }
+ // Purpur end
+
private class PhantomMoveControl extends org.purpurmc.purpur.controller.FlyingMoveControllerWASD { // Purpur
private float speed = 0.1F;
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index bb8aa3d4e33e2d8ed4bf3fd668577ea901410783..429c0bd678cb726b761e32d4b22b33c630f28097 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1163,6 +1163,9 @@ public class PurpurWorldConfig {
public String phantomAttackDamage = "6 + size";
public Map<Integer, Double> phantomMaxHealthCache = new HashMap<>();
public Map<Integer, Double> phantomAttackDamageCache = new HashMap<>();
+ public double phantomAttackedByCrystalRadius = 0.0D;
+ public float phantomAttackedByCrystalDamage = 1.0F;
+ public double phantomOrbitCrystalRadius = 0.0D;
private void phantomSettings() {
phantomRidable = getBoolean("mobs.phantom.ridable", phantomRidable);
phantomRidableInWater = getBoolean("mobs.phantom.ridable-in-water", phantomRidableInWater);
@@ -1184,6 +1187,9 @@ public class PurpurWorldConfig {
phantomAttackDamage = getString("mobs.phantom.attributes.attack_damage", phantomAttackDamage);
phantomMaxHealthCache.clear();
phantomAttackDamageCache.clear();
+ 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);
}
public boolean pigRidable = false;

View File

@@ -1,71 +0,0 @@
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/world/level/levelgen/PhantomSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
index 021221da5d0315f6e371380a705ac6b3f6ac18d3..27eb9a365006884c85603dc6d9dd8eee009c98b3 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
@@ -48,7 +48,7 @@ public class PhantomSpawner implements CustomSpawner {
int spawnAttemptMaxSeconds = world.paperConfig().entities.behavior.phantomsSpawnAttemptMaxSeconds;
this.nextTick += (spawnAttemptMinSeconds + randomsource.nextInt(spawnAttemptMaxSeconds - spawnAttemptMinSeconds + 1)) * 20;
// Paper end - Ability to control player's insomnia and phantoms
- if (world.getSkyDarken() < 5 && world.dimensionType().hasSkyLight()) {
+ if (world.getSkyDarken() < world.purpurConfig.phantomSpawnMinSkyDarkness && world.dimensionType().hasSkyLight()) { // Purpur
return 0;
} else {
int i = 0;
@@ -60,10 +60,10 @@ public class PhantomSpawner implements CustomSpawner {
if (!entityplayer.isSpectator() && (!world.paperConfig().entities.behavior.phantomsDoNotSpawnOnCreativePlayers || !entityplayer.isCreative())) { // Paper - Add phantom creative and insomniac controls
BlockPos blockposition = entityplayer.blockPosition();
- if (!world.dimensionType().hasSkyLight() || blockposition.getY() >= world.getSeaLevel() && world.canSeeSky(blockposition)) {
+ if (!world.dimensionType().hasSkyLight() || (!world.purpurConfig.phantomSpawnOnlyAboveSeaLevel || blockposition.getY() >= world.getSeaLevel()) && (!world.purpurConfig.phantomSpawnOnlyWithVisibleSky || world.canSeeSky(blockposition))) { // Purpur
DifficultyInstance difficultydamagescaler = world.getCurrentDifficultyAt(blockposition);
- if (difficultydamagescaler.isHarderThan(randomsource.nextFloat() * 3.0F)) {
+ if (difficultydamagescaler.isHarderThan(randomsource.nextFloat() * (float) world.purpurConfig.phantomSpawnLocalDifficultyChance)) { // Purpur
ServerStatsCounter serverstatisticmanager = entityplayer.getStats();
int j = Mth.clamp(serverstatisticmanager.getValue(Stats.CUSTOM.get(Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE);
boolean flag2 = true;
@@ -75,7 +75,7 @@ public class PhantomSpawner implements CustomSpawner {
if (NaturalSpawner.isValidEmptySpawnBlock(world, blockposition1, iblockdata, fluid, EntityType.PHANTOM)) {
SpawnGroupData groupdataentity = null;
- int k = 1 + randomsource.nextInt(difficultydamagescaler.getDifficulty().getId() + 1);
+ int k = world.purpurConfig.phantomSpawnMinPerAttempt + world.random.nextInt((world.purpurConfig.phantomSpawnMaxPerAttempt < 0 ? difficultydamagescaler.getDifficulty().getId() : world.purpurConfig.phantomSpawnMaxPerAttempt - world.purpurConfig.phantomSpawnMinPerAttempt) + 1); // Purpur
for (int l = 0; l < k; ++l) {
// Paper start - PhantomPreSpawnEvent
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 429c0bd678cb726b761e32d4b22b33c630f28097..8aebaf667907aa61355ae3a0846b4ee67f204382 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1166,6 +1166,12 @@ public class PurpurWorldConfig {
public double phantomAttackedByCrystalRadius = 0.0D;
public float phantomAttackedByCrystalDamage = 1.0F;
public double phantomOrbitCrystalRadius = 0.0D;
+ public int phantomSpawnMinSkyDarkness = 5;
+ public boolean phantomSpawnOnlyAboveSeaLevel = true;
+ public boolean phantomSpawnOnlyWithVisibleSky = true;
+ public double phantomSpawnLocalDifficultyChance = 3.0D;
+ public int phantomSpawnMinPerAttempt = 1;
+ public int phantomSpawnMaxPerAttempt = -1;
private void phantomSettings() {
phantomRidable = getBoolean("mobs.phantom.ridable", phantomRidable);
phantomRidableInWater = getBoolean("mobs.phantom.ridable-in-water", phantomRidableInWater);
@@ -1190,6 +1196,12 @@ public class PurpurWorldConfig {
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);
+ 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);
+ phantomSpawnMinPerAttempt = getInt("mobs.phantom.spawn.per-attempt.min", phantomSpawnMinPerAttempt);
+ phantomSpawnMaxPerAttempt = getInt("mobs.phantom.spawn.per-attempt.max", phantomSpawnMaxPerAttempt);
}
public boolean pigRidable = false;

View File

@@ -1,60 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sat, 4 Jul 2020 13:12:43 -0500
Subject: [PATCH] Implement bed explosion options
diff --git a/src/main/java/net/minecraft/world/level/block/BedBlock.java b/src/main/java/net/minecraft/world/level/block/BedBlock.java
index c02c4834ace843633b77fb43eeadd3ddc7b1f743..3b19395f2ddee654a77df5738a1942a08c20c179 100644
--- a/src/main/java/net/minecraft/world/level/block/BedBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/BedBlock.java
@@ -106,7 +106,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock
Vec3 vec3d = pos.getCenter();
- world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK);
+ if (world.purpurConfig.bedExplode) world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d), (ExplosionDamageCalculator) null, vec3d, (float) world.purpurConfig.bedExplosionPower, world.purpurConfig.bedExplosionFire, world.purpurConfig.bedExplosionEffect); // Purpur
return InteractionResult.SUCCESS_SERVER;
} else if ((Boolean) state.getValue(BedBlock.OCCUPIED)) {
if (!BedBlock.canSetSpawn(world)) return this.explodeBed(state, world, pos); // Paper - check explode first
@@ -159,7 +159,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock
Vec3 vec3d = blockposition.getCenter();
- world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, blockState), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state
+ if (world.purpurConfig.bedExplode) world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, blockState), (ExplosionDamageCalculator) null, vec3d, (float) world.purpurConfig.bedExplosionPower, world.purpurConfig.bedExplosionFire, world.purpurConfig.bedExplosionEffect); // CraftBukkit - add state // Purpur
return InteractionResult.SUCCESS;
}
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 8aebaf667907aa61355ae3a0846b4ee67f204382..6ffef28deee0a1dfb8c59a9c4d2d2427f8b5eacc 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -279,6 +279,27 @@ public class PurpurWorldConfig {
});
}
+ public boolean bedExplode = true;
+ public double bedExplosionPower = 5.0D;
+ public boolean bedExplosionFire = true;
+ public net.minecraft.world.level.Level.ExplosionInteraction bedExplosionEffect = net.minecraft.world.level.Level.ExplosionInteraction.BLOCK;
+ private void bedSettings() {
+ if (PurpurConfig.version < 31) {
+ if ("DESTROY".equals(getString("blocks.bed.explosion-effect", bedExplosionEffect.name()))) {
+ set("blocks.bed.explosion-effect", "BLOCK");
+ }
+ }
+ bedExplode = getBoolean("blocks.bed.explode", bedExplode);
+ bedExplosionPower = getDouble("blocks.bed.explosion-power", bedExplosionPower);
+ bedExplosionFire = getBoolean("blocks.bed.explosion-fire", bedExplosionFire);
+ try {
+ bedExplosionEffect = net.minecraft.world.level.Level.ExplosionInteraction.valueOf(getString("blocks.bed.explosion-effect", bedExplosionEffect.name()));
+ } catch (IllegalArgumentException e) {
+ log(Level.SEVERE, "Unknown value for `blocks.bed.explosion-effect`! Using default of `BLOCK`");
+ bedExplosionEffect = net.minecraft.world.level.Level.ExplosionInteraction.BLOCK;
+ }
+ }
+
public boolean dispenserApplyCursedArmor = true;
private void dispenserSettings() {
dispenserApplyCursedArmor = getBoolean("blocks.dispenser.apply-cursed-to-armor-slots", dispenserApplyCursedArmor);

View File

@@ -1,51 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sat, 4 Jul 2020 13:23:19 -0500
Subject: [PATCH] Implement respawn anchor explosion options
diff --git a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
index 9117c035d5a6ff114b028fad3380ceb1fc2b9691..2c5e394156dbf76107adb4913a094dfd4a598dd7 100644
--- a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
@@ -149,7 +149,7 @@ public class RespawnAnchorBlock extends Block {
};
Vec3 vec3d = explodedPos.getCenter();
- world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, blockState), explosiondamagecalculator, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state
+ if (world.purpurConfig.respawnAnchorExplode) world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, blockState), explosiondamagecalculator, vec3d, (float) world.purpurConfig.respawnAnchorExplosionPower, world.purpurConfig.respawnAnchorExplosionFire, world.purpurConfig.respawnAnchorExplosionEffect); // CraftBukkit - add state // Purpur
}
public static boolean canSetSpawn(Level world) {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 6ffef28deee0a1dfb8c59a9c4d2d2427f8b5eacc..6e68accdf6d4067f69cf7b29381ee2eab7a2b20c 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -319,6 +319,27 @@ public class PurpurWorldConfig {
lavaSpeedNotNether = getInt("blocks.lava.speed.not-nether", lavaSpeedNotNether);
}
+ public boolean respawnAnchorExplode = true;
+ public double respawnAnchorExplosionPower = 5.0D;
+ public boolean respawnAnchorExplosionFire = true;
+ public net.minecraft.world.level.Level.ExplosionInteraction respawnAnchorExplosionEffect = net.minecraft.world.level.Level.ExplosionInteraction.BLOCK;
+ private void respawnAnchorSettings() {
+ if (PurpurConfig.version < 31) {
+ if ("DESTROY".equals(getString("blocks.respawn_anchor.explosion-effect", respawnAnchorExplosionEffect.name()))) {
+ set("blocks.respawn_anchor.explosion-effect", "BLOCK");
+ }
+ }
+ respawnAnchorExplode = getBoolean("blocks.respawn_anchor.explode", respawnAnchorExplode);
+ respawnAnchorExplosionPower = getDouble("blocks.respawn_anchor.explosion-power", respawnAnchorExplosionPower);
+ respawnAnchorExplosionFire = getBoolean("blocks.respawn_anchor.explosion-fire", respawnAnchorExplosionFire);
+ try {
+ respawnAnchorExplosionEffect = net.minecraft.world.level.Level.ExplosionInteraction.valueOf(getString("blocks.respawn_anchor.explosion-effect", respawnAnchorExplosionEffect.name()));
+ } catch (IllegalArgumentException e) {
+ log(Level.SEVERE, "Unknown value for `blocks.respawn_anchor.explosion-effect`! Using default of `BLOCK`");
+ respawnAnchorExplosionEffect = net.minecraft.world.level.Level.ExplosionInteraction.BLOCK;
+ }
+ }
+
public boolean turtleEggsBreakFromExpOrbs = false;
public boolean turtleEggsBreakFromItems = false;
public boolean turtleEggsBreakFromMinecarts = false;

View File

@@ -1,85 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sun, 5 Jul 2020 23:40:16 -0500
Subject: [PATCH] Add allow water in end world option
diff --git a/src/main/java/net/minecraft/world/item/BucketItem.java b/src/main/java/net/minecraft/world/item/BucketItem.java
index 3bddfb6f7412ab86e0c090d0cbc6cf254b3f891c..6aa8ee091d3a7d2826d08ab9a03f970ef71a81ea 100644
--- a/src/main/java/net/minecraft/world/item/BucketItem.java
+++ b/src/main/java/net/minecraft/world/item/BucketItem.java
@@ -196,7 +196,7 @@ public class BucketItem extends Item implements DispensibleContainerItem {
// CraftBukkit end
if (!flag2) {
return movingobjectpositionblock != null && this.emptyContents(entityhuman, world, movingobjectpositionblock.getBlockPos().relative(movingobjectpositionblock.getDirection()), (BlockHitResult) null, enumdirection, clicked, itemstack, enumhand); // CraftBukkit
- } else if (world.dimensionType().ultraWarm() && this.content.is(FluidTags.WATER)) {
+ } else if ((world.dimensionType().ultraWarm() || (world.isTheEnd() && !org.purpurmc.purpur.PurpurConfig.allowWaterPlacementInTheEnd)) && this.content.is(FluidTags.WATER)) { // Purpur
int i = blockposition.getX();
int j = blockposition.getY();
int k = blockposition.getZ();
@@ -204,7 +204,7 @@ public class BucketItem extends Item implements DispensibleContainerItem {
world.playSound(entityhuman, blockposition, SoundEvents.FIRE_EXTINGUISH, SoundSource.BLOCKS, 0.5F, 2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F);
for (int l = 0; l < 8; ++l) {
- world.addParticle(ParticleTypes.LARGE_SMOKE, (double) i + Math.random(), (double) j + Math.random(), (double) k + Math.random(), 0.0D, 0.0D, 0.0D);
+ ((ServerLevel) world).sendParticles(null, ParticleTypes.LARGE_SMOKE, (double) i + Math.random(), (double) j + Math.random(), (double) k + Math.random(), 1, 0.0D, 0.0D, 0.0D, 0.0D, true); // Purpur
}
return true;
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index e7b9c8a473403002a75b6840250439c91ed12c1c..77093e49fd60993e7cb6bf5712ec53e0fe221776 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -2044,4 +2044,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
return this.id;
}
}
+
+ // Purpur start
+ public boolean isNether() {
+ return getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER;
+ }
+
+ public boolean isTheEnd() {
+ return getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END;
+ }
+ // Purpur end
}
diff --git a/src/main/java/net/minecraft/world/level/block/IceBlock.java b/src/main/java/net/minecraft/world/level/block/IceBlock.java
index a94762e65853ccad38cf90b0049ca256106c0c9f..38633e168a9b36e37feea00964d53e657926639e 100644
--- a/src/main/java/net/minecraft/world/level/block/IceBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/IceBlock.java
@@ -42,7 +42,7 @@ public class IceBlock extends HalfTransparentBlock {
public void afterDestroy(Level world, BlockPos pos, ItemStack tool) {
// Paper end - Improve Block#breakNaturally API
if (!EnchantmentHelper.hasTag(tool, EnchantmentTags.PREVENTS_ICE_MELTING)) {
- if (world.dimensionType().ultraWarm()) {
+ if (world.isNether() || (world.isTheEnd() && !org.purpurmc.purpur.PurpurConfig.allowWaterPlacementInTheEnd)) { // Purpur
world.removeBlock(pos, false);
return;
}
@@ -70,7 +70,7 @@ public class IceBlock extends HalfTransparentBlock {
return;
}
// CraftBukkit end
- if (world.dimensionType().ultraWarm()) {
+ if (world.isNether() || (world.isTheEnd() && !org.purpurmc.purpur.PurpurConfig.allowWaterPlacementInTheEnd)) { // Purpur
world.removeBlock(pos, false);
} else {
world.setBlockAndUpdate(pos, IceBlock.meltsInto());
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index 6228d23bd84e59a9e1f01414cc9f00c33cc64cd0..9f98b87ccc60db9a531180de1ed649de118db56f 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -247,6 +247,11 @@ public class PurpurConfig {
enderChestPermissionRows = getBoolean("settings.blocks.ender_chest.use-permissions-for-rows", enderChestPermissionRows);
}
+ public static boolean allowWaterPlacementInTheEnd = true;
+ private static void allowWaterPlacementInEnd() {
+ allowWaterPlacementInTheEnd = getBoolean("settings.allow-water-placement-in-the-end", allowWaterPlacementInTheEnd);
+ }
+
public static boolean loggerSuppressInitLegacyMaterialError = false;
public static boolean loggerSuppressIgnoredAdvancementWarnings = false;
public static boolean loggerSuppressUnrecognizedRecipeErrors = false;

View File

@@ -1,89 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Tue, 3 Nov 2020 01:25:06 -0600
Subject: [PATCH] Allow color codes in books
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index f48b13b9b57e3a25e8afeb37f54e883fd1cadf4d..99a023e87428ee200fcb3b663c2ab6a1077b3bf0 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1249,10 +1249,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
Objects.requireNonNull(list);
optional.ifPresent(list::add);
list.addAll(packet.pages());
+ // Purpur start
+ boolean hasEditPerm = getCraftPlayer().hasPermission("purpur.book.color.edit");
+ boolean hasSignPerm = hasEditPerm || getCraftPlayer().hasPermission("purpur.book.color.sign");
+ // Purpur end
Consumer<List<FilteredText>> consumer = optional.isPresent() ? (list1) -> {
- this.signBook((FilteredText) list1.get(0), list1.subList(1, list1.size()), i);
+ this.signBook((FilteredText) list1.get(0), list1.subList(1, list1.size()), i, hasSignPerm); // Purpur
} : (list1) -> {
- this.updateBookContents(list1, i);
+ this.updateBookContents(list1, i, hasEditPerm); // Purpur
};
this.filterTextPacket((List) list).thenAcceptAsync(consumer, this.server);
@@ -1260,13 +1264,18 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
}
private void updateBookContents(List<FilteredText> pages, int slotId) {
+ // Purpur start
+ updateBookContents(pages, slotId, false);
+ }
+ private void updateBookContents(List<FilteredText> pages, int slotId, boolean hasPerm) {
+ // Purpur end
// CraftBukkit start
ItemStack handItem = this.player.getInventory().getItem(slotId);
ItemStack itemstack = handItem.copy();
// CraftBukkit end
if (itemstack.has(DataComponents.WRITABLE_BOOK_CONTENT)) {
- List<Filterable<String>> list1 = pages.stream().map(this::filterableFromOutgoing).toList();
+ List<Filterable<String>> list1 = pages.stream().map(filteredText -> filterableFromOutgoing(filteredText).map(s -> color(s, hasPerm))).toList(); // Purpur
itemstack.set(DataComponents.WRITABLE_BOOK_CONTENT, new WritableBookContent(list1));
this.player.getInventory().setItem(slotId, CraftEventFactory.handleEditBookEvent(this.player, slotId, handItem, itemstack)); // CraftBukkit // Paper - Don't ignore result (see other callsite for handleEditBookEvent)
@@ -1274,6 +1283,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
}
private void signBook(FilteredText title, List<FilteredText> pages, int slotId) {
+ // Purpur start
+ signBook(title, pages, slotId, false);
+ }
+ private void signBook(FilteredText title, List<FilteredText> pages, int slotId, boolean hasPerm) {
+ // Purpur end
ItemStack itemstack = this.player.getInventory().getItem(slotId);
if (itemstack.has(DataComponents.WRITABLE_BOOK_CONTENT)) {
@@ -1281,10 +1295,10 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
itemstack1.remove(DataComponents.WRITABLE_BOOK_CONTENT);
List<Filterable<Component>> list1 = (List<Filterable<Component>>) (List) pages.stream().map((filteredtext1) -> { // CraftBukkit - decompile error
- return this.filterableFromOutgoing(filteredtext1).map(Component::literal);
+ return this.filterableFromOutgoing(filteredtext1).map(s -> hexColor(s, hasPerm)); // Purpur
}).toList();
- itemstack1.set(DataComponents.WRITTEN_BOOK_CONTENT, new WrittenBookContent(this.filterableFromOutgoing(title), this.player.getName().getString(), 0, list1, true));
+ itemstack1.set(DataComponents.WRITTEN_BOOK_CONTENT, new WrittenBookContent(this.filterableFromOutgoing(title).map(s -> color(s, hasPerm)), this.player.getName().getString(), 0, list1, true)); // Purpur
CraftEventFactory.handleEditBookEvent(this.player, slotId, itemstack, itemstack1); // CraftBukkit
this.player.getInventory().setItem(slotId, itemstack); // CraftBukkit - event factory updates the hand book
}
@@ -1294,6 +1308,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
return this.player.isTextFilteringEnabled() ? Filterable.passThrough(message.filteredOrEmpty()) : Filterable.from(message);
}
+ // Purpur start
+ private Component hexColor(String str, boolean hasPerm) {
+ return hasPerm ? PaperAdventure.asVanilla(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacyAmpersand().deserialize(str)) : Component.literal(str);
+ }
+
+ private String color(String str, boolean hasPerm) {
+ return hasPerm ? org.bukkit.ChatColor.color(str, false) : str;
+ }
+ // Purpur end
+
@Override
public void handleEntityTagQuery(ServerboundEntityTagQueryPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());

View File

@@ -1,111 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sat, 11 Jul 2020 19:41:34 -0500
Subject: [PATCH] Entity lifespan
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 99a023e87428ee200fcb3b663c2ab6a1077b3bf0..f11dc92d796d3044adc8cbd97edf00e047ba72f1 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2857,6 +2857,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
AABB axisalignedbb = entity.getBoundingBox();
if (this.player.canInteractWithEntity(axisalignedbb, io.papermc.paper.configuration.GlobalConfiguration.get().misc.clientInteractionLeniencyDistance.or(3.0D))) { // Paper - configurable lenience value for interact range
+ if (entity instanceof Mob mob) mob.ticksSinceLastInteraction = 0; // Purpur
packet.dispatch(new ServerboundInteractPacket.Handler() {
private void performInteraction(InteractionHand enumhand, ServerGamePacketListenerImpl.EntityInteraction playerconnection_a, PlayerInteractEntityEvent event) { // CraftBukkit
ItemStack itemstack = ServerGamePacketListenerImpl.this.player.getItemInHand(enumhand);
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
index 6502676a94ebb663b6126a21896cda456066d55b..e99b72b89abdded3e988bd1a92d36055fb1a84dc 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
@@ -148,6 +148,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
private BlockPos restrictCenter;
private float restrictRadius;
+ public int ticksSinceLastInteraction; // Purpur
public boolean aware = true; // CraftBukkit
protected Mob(EntityType<? extends Mob> type, Level world) {
@@ -336,6 +337,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
entityliving = null;
}
}
+ if (entityliving instanceof net.minecraft.server.level.ServerPlayer) this.ticksSinceLastInteraction = 0; // Purpur
this.target = entityliving;
return true;
// CraftBukkit end
@@ -380,8 +382,28 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
}
gameprofilerfiller.pop();
+ incrementTicksSinceLastInteraction(); // Purpur
}
+ // Purpur start
+ private void incrementTicksSinceLastInteraction() {
+ ++this.ticksSinceLastInteraction;
+ if (getRider() != null) {
+ this.ticksSinceLastInteraction = 0;
+ return;
+ }
+ if (this.level().purpurConfig.entityLifeSpan <= 0) {
+ return; // feature disabled
+ }
+ if (!this.removeWhenFarAway(0) || isPersistenceRequired() || requiresCustomPersistence() || hasCustomName()) {
+ return; // mob persistent
+ }
+ if (this.ticksSinceLastInteraction > this.level().purpurConfig.entityLifeSpan) {
+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD);
+ }
+ }
+ // Purpur end
+
@Override
protected void playHurtSound(DamageSource damageSource) {
this.resetAmbientSoundTime();
@@ -549,6 +571,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
}
nbt.putBoolean("Bukkit.Aware", this.aware); // CraftBukkit
+ nbt.putInt("Purpur.ticksSinceLastInteraction", this.ticksSinceLastInteraction); // Purpur
}
@Override
@@ -626,6 +649,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
this.aware = nbt.getBoolean("Bukkit.Aware");
}
// CraftBukkit end
+ // Purpur start
+ if (nbt.contains("Purpur.ticksSinceLastInteraction")) {
+ this.ticksSinceLastInteraction = nbt.getInt("Purpur.ticksSinceLastInteraction");
+ }
+ // Purpur end
}
@Override
@@ -1741,6 +1769,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
this.playAttackSound();
}
+ if (target instanceof net.minecraft.server.level.ServerPlayer) this.ticksSinceLastInteraction = 0; // Purpur
return flag;
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 6e68accdf6d4067f69cf7b29381ee2eab7a2b20c..bfd03c3cdc2b80415730aa1a18fad5afe838df25 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -120,6 +120,11 @@ public class PurpurWorldConfig {
elytraDamagePerTridentBoost = getInt("gameplay-mechanics.elytra.damage-per-boost.trident", elytraDamagePerTridentBoost);
}
+ public int entityLifeSpan = 0;
+ private void entitySettings() {
+ entityLifeSpan = getInt("gameplay-mechanics.entity-lifespan", entityLifeSpan);
+ }
+
public List<Item> itemImmuneToCactus = new ArrayList<>();
public List<Item> itemImmuneToExplosion = new ArrayList<>();
public List<Item> itemImmuneToFire = new ArrayList<>();

View File

@@ -1,69 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Mon, 13 Jul 2020 11:40:00 -0500
Subject: [PATCH] Add option to teleport to spawn if outside world border
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index a91a4602b5bc72dc0162fd2d60eebf3a05df4065..cbe608df708d5530813230cddd78568c1a63b448 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -3410,4 +3410,26 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
return (CraftPlayer) super.getBukkitEntity();
}
// CraftBukkit end
+
+ // Purpur start
+ public void teleport(Location to) {
+ this.ejectPassengers();
+ this.stopRiding(true);
+
+ if (this.isSleeping()) {
+ this.stopSleepInBed(true, false);
+ }
+
+ if (this.containerMenu != this.inventoryMenu) {
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.TELEPORT);
+ }
+
+ ServerLevel toLevel = ((CraftWorld) to.getWorld()).getHandle();
+ if (this.level() == toLevel) {
+ this.connection.teleport(to);
+ } else {
+ this.server.getPlayerList().respawn(this, true, RemovalReason.KILLED, org.bukkit.event.player.PlayerRespawnEvent.RespawnReason.DEATH, to);
+ }
+ }
+ // Purpur end
}
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index c1a3103aa692bb5dfb4e162159c77a03d9c9a0e8..2007dd29cc2c1ee4cf88db27e0082c3548ebf344 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -479,6 +479,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
if (d1 < 0.0D) {
d0 = this.level().getWorldBorder().getDamagePerBlock();
if (d0 > 0.0D) {
+ if (level().purpurConfig.teleportIfOutsideBorder && this instanceof ServerPlayer serverPlayer) { serverPlayer.teleport(io.papermc.paper.util.MCUtil.toLocation(level(), ((ServerLevel) level()).getSharedSpawnPos())); return; } // Purpur
this.hurtServer(worldserver1, this.damageSources().outOfBorder(), (float) Math.max(1, Mth.floor(-d1 * d0)));
}
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index bfd03c3cdc2b80415730aa1a18fad5afe838df25..b5d714f137257810ced4b4457bd5bb01123d3452 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -237,6 +237,7 @@ public class PurpurWorldConfig {
public boolean idleTimeoutTargetPlayer = true;
public String playerDeathExpDropEquation = "expLevel * 7";
public int playerDeathExpDropMax = 100;
+ public boolean teleportIfOutsideBorder = false;
private void playerSettings() {
if (PurpurConfig.version < 19) {
boolean oldVal = getBoolean("gameplay-mechanics.player.idle-timeout.mods-target", idleTimeoutTargetPlayer);
@@ -250,6 +251,7 @@ public class PurpurWorldConfig {
idleTimeoutTargetPlayer = getBoolean("gameplay-mechanics.player.idle-timeout.mobs-target", idleTimeoutTargetPlayer);
playerDeathExpDropEquation = getString("gameplay-mechanics.player.exp-dropped-on-death.equation", playerDeathExpDropEquation);
playerDeathExpDropMax = getInt("gameplay-mechanics.player.exp-dropped-on-death.maximum", playerDeathExpDropMax);
+ teleportIfOutsideBorder = getBoolean("gameplay-mechanics.player.teleport-if-outside-border", teleportIfOutsideBorder);
}
public boolean silkTouchEnabled = false;

View File

@@ -1,38 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Mon, 13 Jul 2020 13:49:41 -0500
Subject: [PATCH] Squid EAR immunity
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index b5d714f137257810ced4b4457bd5bb01123d3452..0d4eaa2933d2b6501eeb64a0d95b2d4d67fb5523 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1586,6 +1586,7 @@ public class PurpurWorldConfig {
public boolean squidControllable = true;
public double squidMaxHealth = 10.0D;
public double squidScale = 1.0D;
+ public boolean squidImmuneToEAR = true;
private void squidSettings() {
squidRidable = getBoolean("mobs.squid.ridable", squidRidable);
squidControllable = getBoolean("mobs.squid.controllable", squidControllable);
@@ -1596,6 +1597,7 @@ public class PurpurWorldConfig {
}
squidMaxHealth = getDouble("mobs.squid.attributes.max_health", squidMaxHealth);
squidScale = Mth.clamp(getDouble("mobs.squid.attributes.scale", squidScale), 0.0625D, 16.0D);
+ squidImmuneToEAR = getBoolean("mobs.squid.immune-to-EAR", squidImmuneToEAR);
}
public boolean spiderRidable = false;
diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java
index a017374f2027946ef465cf41fd6ed6de7f00e19f..9b1a16747aa23b18e4cff986efaac6ce64b6ddb9 100644
--- a/src/main/java/org/spigotmc/ActivationRange.java
+++ b/src/main/java/org/spigotmc/ActivationRange.java
@@ -401,6 +401,7 @@ public class ActivationRange
*/
public static boolean checkIfActive(Entity entity)
{
+ if (entity.level().purpurConfig.squidImmuneToEAR && entity instanceof net.minecraft.world.entity.animal.Squid) return true; // Purpur
// Never safe to skip fireworks or item gravity
if (entity instanceof FireworkRocketEntity || (entity instanceof ItemEntity && (entity.tickCount + entity.getId()) % 4 == 0)) { // Paper - Needed for item gravity, see ItemEntity tick
return true;

View File

@@ -1,76 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: draycia <lonelyyordle@gmail.com>
Date: Sun, 12 Apr 2020 20:41:59 -0700
Subject: [PATCH] Phantoms burn in light
diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
index bd1c23d849269df504c94da9d0ca0a6846b22c41..987b860f85a1be3159233fb3291773792d291348 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
@@ -49,6 +49,7 @@ public class Phantom extends FlyingMob implements Enemy {
Vec3 moveTargetPoint;
public BlockPos anchorPoint;
Phantom.AttackPhase attackPhase;
+ private static final net.minecraft.world.item.crafting.Ingredient TORCH = net.minecraft.world.item.crafting.Ingredient.of(net.minecraft.world.item.Items.TORCH, net.minecraft.world.item.Items.SOUL_TORCH); // Purpur
Vec3 crystalPosition; // Purpur
public Phantom(EntityType<? extends Phantom> type, Level world) {
@@ -241,7 +242,11 @@ public class Phantom extends FlyingMob implements Enemy {
@Override
public void aiStep() {
- if (this.isAlive() && this.shouldBurnInDay && this.isSunBurnTick()) { // Paper - shouldBurnInDay API
+ // Purpur start
+ boolean burnFromDaylight = this.shouldBurnInDay && this.isSunBurnTick() && this.level().purpurConfig.phantomBurnInDaylight;
+ boolean burnFromLightSource = this.level().purpurConfig.phantomBurnInLight > 0 && this.level().getMaxLocalRawBrightness(blockPosition()) >= this.level().purpurConfig.phantomBurnInLight;
+ if (this.isAlive() && (burnFromDaylight || burnFromLightSource)) { // Paper - shouldBurnInDay API
+ // Purpur end
if (getRider() == null || !this.isControllable()) // Purpur
this.igniteForSeconds(8.0F);
}
@@ -641,6 +646,12 @@ public class Phantom extends FlyingMob implements Enemy {
return false;
} else if (!entityliving.isAlive()) {
return false;
+ // Purpur start
+ } else if (level().purpurConfig.phantomBurnInLight > 0 && level().getLightEmission(new BlockPos(Phantom.this)) >= level().purpurConfig.phantomBurnInLight) {
+ return false;
+ } else if (level().purpurConfig.phantomIgnorePlayersWithTorch && (TORCH.test(entityliving.getItemInHand(net.minecraft.world.InteractionHand.MAIN_HAND)) || TORCH.test(entityliving.getItemInHand(net.minecraft.world.InteractionHand.OFF_HAND)))) {
+ return false;
+ // Purpur end
} else {
if (entityliving instanceof Player) {
Player entityhuman = (Player) entityliving;
@@ -787,6 +798,7 @@ public class Phantom extends FlyingMob implements Enemy {
ServerLevel worldserver = getServerLevel(Phantom.this.level());
List<Player> list = worldserver.getNearbyPlayers(this.attackTargeting, Phantom.this, Phantom.this.getBoundingBox().inflate(16.0D, 64.0D, 16.0D));
+ if (level().purpurConfig.phantomIgnorePlayersWithTorch) list.removeIf(human -> TORCH.test(human.getItemInHand(net.minecraft.world.InteractionHand.MAIN_HAND)) || TORCH.test(human.getItemInHand(net.minecraft.world.InteractionHand.OFF_HAND)));// Purpur
if (!list.isEmpty()) {
list.sort(Comparator.comparing((Entity e) -> { return e.getY(); }).reversed()); // CraftBukkit - decompile error
Iterator iterator = list.iterator();
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 0d4eaa2933d2b6501eeb64a0d95b2d4d67fb5523..4fc86678e3c6459d88a0f7114dd858c6850290df 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1221,6 +1221,9 @@ public class PurpurWorldConfig {
public double phantomSpawnLocalDifficultyChance = 3.0D;
public int phantomSpawnMinPerAttempt = 1;
public int phantomSpawnMaxPerAttempt = -1;
+ public int phantomBurnInLight = 0;
+ public boolean phantomIgnorePlayersWithTorch = false;
+ public boolean phantomBurnInDaylight = true;
private void phantomSettings() {
phantomRidable = getBoolean("mobs.phantom.ridable", phantomRidable);
phantomRidableInWater = getBoolean("mobs.phantom.ridable-in-water", phantomRidableInWater);
@@ -1251,6 +1254,9 @@ public class PurpurWorldConfig {
phantomSpawnLocalDifficultyChance = getDouble("mobs.phantom.spawn.local-difficulty-chance", phantomSpawnLocalDifficultyChance);
phantomSpawnMinPerAttempt = getInt("mobs.phantom.spawn.per-attempt.min", phantomSpawnMinPerAttempt);
phantomSpawnMaxPerAttempt = getInt("mobs.phantom.spawn.per-attempt.max", phantomSpawnMaxPerAttempt);
+ phantomBurnInLight = getInt("mobs.phantom.burn-in-light", phantomBurnInLight);
+ phantomBurnInDaylight = getBoolean("mobs.phantom.burn-in-daylight", phantomBurnInDaylight);
+ phantomIgnorePlayersWithTorch = getBoolean("mobs.phantom.ignore-players-with-torch", phantomIgnorePlayersWithTorch);
}
public boolean pigRidable = false;

View File

@@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: draycia <lonelyyordle@gmail.com>
Date: Tue, 31 Mar 2020 23:48:55 -0700
Subject: [PATCH] Configurable villager breeding
diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java
index 394c8667cfe57fa1fba93231a1ebb5be6dc63c63..3528cc251ebae1011ec3dac4b893157e446a1e22 100644
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
@@ -769,7 +769,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
@Override
public boolean canBreed() {
- return this.foodLevel + this.countFoodPointsInInventory() >= 12 && !this.isSleeping() && this.getAge() == 0;
+ return this.level().purpurConfig.villagerCanBreed && this.foodLevel + this.countFoodPointsInInventory() >= 12 && !this.isSleeping() && this.getAge() == 0; // Purpur
}
private boolean hungry() {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 4fc86678e3c6459d88a0f7114dd858c6850290df..83af43e5f1d3e80170104771b2d38526d1ab3e3a 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1759,6 +1759,7 @@ public class PurpurWorldConfig {
public boolean villagerFollowEmeraldBlock = false;
public double villagerTemptRange = 10.0D;
public boolean villagerCanBeLeashed = false;
+ public boolean villagerCanBreed = true;
private void villagerSettings() {
villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable);
villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater);
@@ -1773,6 +1774,7 @@ public class PurpurWorldConfig {
villagerFollowEmeraldBlock = getBoolean("mobs.villager.follow-emerald-blocks", villagerFollowEmeraldBlock);
villagerTemptRange = getDouble("mobs.villager.attributes.tempt_range", villagerTemptRange);
villagerCanBeLeashed = getBoolean("mobs.villager.can-be-leashed", villagerCanBeLeashed);
+ villagerCanBreed = getBoolean("mobs.villager.can-breed", villagerCanBreed);
}
public boolean vindicatorRidable = false;

View File

@@ -1,34 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: draycia <lonelyyordle@gmail.com>
Date: Tue, 14 Apr 2020 00:35:12 -0700
Subject: [PATCH] Redstone deactivates spawners
diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java
index 7de66aa435dd36899b80f4ecc64480680e474d94..bb4411cfdf1bc7adc12c2f918d2eec830299f38b 100644
--- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
+++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
@@ -59,6 +59,7 @@ public abstract class BaseSpawner {
}
public boolean isNearPlayer(Level world, BlockPos pos) {
+ if (world.purpurConfig.spawnerDeactivateByRedstone && world.hasNeighborSignal(pos)) return false; // Purpur
return world.hasNearbyAlivePlayerThatAffectsSpawning((double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, (double) this.requiredPlayerRange); // Paper - Affects Spawning API
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 83af43e5f1d3e80170104771b2d38526d1ab3e3a..be44e9597b595f8a4b63a9a198f63e7db411b6ce 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -347,6 +347,11 @@ public class PurpurWorldConfig {
}
}
+ public boolean spawnerDeactivateByRedstone = false;
+ private void spawnerSettings() {
+ spawnerDeactivateByRedstone = getBoolean("blocks.spawner.deactivate-by-redstone", spawnerDeactivateByRedstone);
+ }
+
public boolean turtleEggsBreakFromExpOrbs = false;
public boolean turtleEggsBreakFromItems = false;
public boolean turtleEggsBreakFromMinecarts = false;

View File

@@ -1,49 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: draycia <lonelyyordle@gmail.com>
Date: Wed, 29 Apr 2020 00:45:58 -0700
Subject: [PATCH] Totems work in inventory
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 2007dd29cc2c1ee4cf88db27e0082c3548ebf344..f8ec83a135feab4140ec075ee45250ebfc511993 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -1720,6 +1720,18 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
}
+ // Purpur start
+ if (level().purpurConfig.totemOfUndyingWorksInInventory && this instanceof ServerPlayer player && (itemstack == null || itemstack.getItem() != Items.TOTEM_OF_UNDYING) && player.getBukkitEntity().hasPermission("purpur.inventory_totem")) {
+ for (ItemStack item : player.getInventory().items) {
+ if (item.getItem() == Items.TOTEM_OF_UNDYING) {
+ itemstack1 = item;
+ itemstack = item.copy();
+ break;
+ }
+ }
+ }
+ // Purpur end
+
org.bukkit.inventory.EquipmentSlot handSlot = (hand != null) ? org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand) : null;
EntityResurrectEvent event = new EntityResurrectEvent((org.bukkit.entity.LivingEntity) this.getBukkitEntity(), handSlot);
event.setCancelled(itemstack == null);
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index be44e9597b595f8a4b63a9a198f63e7db411b6ce..35ce3c0385f72feea1a0741ee055994f5cf0190a 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -238,6 +238,7 @@ public class PurpurWorldConfig {
public String playerDeathExpDropEquation = "expLevel * 7";
public int playerDeathExpDropMax = 100;
public boolean teleportIfOutsideBorder = false;
+ public boolean totemOfUndyingWorksInInventory = false;
private void playerSettings() {
if (PurpurConfig.version < 19) {
boolean oldVal = getBoolean("gameplay-mechanics.player.idle-timeout.mods-target", idleTimeoutTargetPlayer);
@@ -252,6 +253,7 @@ public class PurpurWorldConfig {
playerDeathExpDropEquation = getString("gameplay-mechanics.player.exp-dropped-on-death.equation", playerDeathExpDropEquation);
playerDeathExpDropMax = getInt("gameplay-mechanics.player.exp-dropped-on-death.maximum", playerDeathExpDropMax);
teleportIfOutsideBorder = getBoolean("gameplay-mechanics.player.teleport-if-outside-border", teleportIfOutsideBorder);
+ totemOfUndyingWorksInInventory = getBoolean("gameplay-mechanics.player.totem-of-undying-works-in-inventory", totemOfUndyingWorksInInventory);
}
public boolean silkTouchEnabled = false;

View File

@@ -1,42 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Fri, 24 Jul 2020 19:38:21 -0500
Subject: [PATCH] Add vindicator johnny spawn chance
diff --git a/src/main/java/net/minecraft/world/entity/monster/Vindicator.java b/src/main/java/net/minecraft/world/entity/monster/Vindicator.java
index 2bfce82bee8f3a16a33bd937eb610d9df1b6ceeb..2f7da09e14787395e95211acadd5c693cf07fba3 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Vindicator.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Vindicator.java
@@ -157,6 +157,11 @@ public class Vindicator extends AbstractIllager {
RandomSource randomSource = world.getRandom();
this.populateDefaultEquipmentSlots(randomSource, difficulty);
this.populateDefaultEquipmentEnchantments(world, randomSource, difficulty);
+ // Purpur start
+ if (level().purpurConfig.vindicatorJohnnySpawnChance > 0D && random.nextDouble() <= level().purpurConfig.vindicatorJohnnySpawnChance) {
+ setCustomName(Component.translatable("Johnny"));
+ }
+ // Purpur end
return spawnGroupData;
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 35ce3c0385f72feea1a0741ee055994f5cf0190a..a4c20f7b679150425b192a9e4411fa987aed8e1f 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1789,6 +1789,7 @@ public class PurpurWorldConfig {
public boolean vindicatorControllable = true;
public double vindicatorMaxHealth = 24.0D;
public double vindicatorScale = 1.0D;
+ public double vindicatorJohnnySpawnChance = 0D;
private void vindicatorSettings() {
vindicatorRidable = getBoolean("mobs.vindicator.ridable", vindicatorRidable);
vindicatorRidableInWater = getBoolean("mobs.vindicator.ridable-in-water", vindicatorRidableInWater);
@@ -1800,6 +1801,7 @@ public class PurpurWorldConfig {
}
vindicatorMaxHealth = getDouble("mobs.vindicator.attributes.max_health", vindicatorMaxHealth);
vindicatorScale = Mth.clamp(getDouble("mobs.vindicator.attributes.scale", vindicatorScale), 0.0625D, 16.0D);
+ vindicatorJohnnySpawnChance = getDouble("mobs.vindicator.johnny.spawn-chance", vindicatorJohnnySpawnChance);
}
public boolean wanderingTraderRidable = false;

View File

@@ -1,48 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Tue, 4 Aug 2020 21:11:03 -0500
Subject: [PATCH] Dispensers place anvils option
diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
index 0d12605dc84dad49faa18bf1fd058c3c168623ee..c6490554a3025f4de3f3218178fad76cd1848a19 100644
--- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
+++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
@@ -930,5 +930,22 @@ public interface DispenseItemBehavior {
DispenserBlock.registerBehavior(Items.TNT_MINECART, new MinecartDispenseItemBehavior(EntityType.TNT_MINECART));
DispenserBlock.registerBehavior(Items.HOPPER_MINECART, new MinecartDispenseItemBehavior(EntityType.HOPPER_MINECART));
DispenserBlock.registerBehavior(Items.COMMAND_BLOCK_MINECART, new MinecartDispenseItemBehavior(EntityType.COMMAND_BLOCK_MINECART));
+ // Purpur start
+ DispenserBlock.registerBehavior(Items.ANVIL, (new OptionalDispenseItemBehavior() {
+ @Override
+ public ItemStack execute(BlockSource dispenser, ItemStack stack) {
+ net.minecraft.world.level.Level level = dispenser.level();
+ if (!level.purpurConfig.dispenserPlaceAnvils) return super.execute(dispenser, stack);
+ Direction facing = dispenser.blockEntity().getBlockState().getValue(DispenserBlock.FACING);
+ BlockPos pos = dispenser.pos().relative(facing);
+ BlockState state = level.getBlockState(pos);
+ if (state.isAir()) {
+ level.setBlockAndUpdate(pos, Blocks.ANVIL.defaultBlockState().setValue(net.minecraft.world.level.block.AnvilBlock.FACING, facing.getAxis() == Direction.Axis.Y ? Direction.NORTH : facing.getClockWise()));
+ stack.shrink(1);
+ }
+ return stack;
+ }
+ }));
+ // Purpur end
}
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index a4c20f7b679150425b192a9e4411fa987aed8e1f..efebca2a6dd217d853a27516c29be89421c1df68 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -310,8 +310,10 @@ public class PurpurWorldConfig {
}
public boolean dispenserApplyCursedArmor = true;
+ public boolean dispenserPlaceAnvils = false;
private void dispenserSettings() {
dispenserApplyCursedArmor = getBoolean("blocks.dispenser.apply-cursed-to-armor-slots", dispenserApplyCursedArmor);
+ dispenserPlaceAnvils = getBoolean("blocks.dispenser.place-anvils", dispenserPlaceAnvils);
}
public boolean farmlandGetsMoistFromBelow = false;

View File

@@ -1,83 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Tue, 4 Aug 2020 22:08:23 -0500
Subject: [PATCH] Allow anvil colors
diff --git a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
index f8c0a4fd95f341cbf8f6a06dfae408d505b0f018..a7c3338ed6edcd26fce869ec66fdcaa4c32c0e4f 100644
--- a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
+++ b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
@@ -285,6 +285,54 @@ public class AnvilMenu extends ItemCombinerMenu {
if (!this.itemName.equals(itemstack.getHoverName().getString())) {
b0 = 1;
i += b0;
+ // Purpur start
+ if (this.player != null) {
+ org.bukkit.craftbukkit.entity.CraftHumanEntity player = this.player.getBukkitEntity();
+ String name = this.itemName;
+ boolean removeItalics = false;
+ if (player.hasPermission("purpur.anvil.remove_italics")) {
+ if (name.startsWith("&r")) {
+ name = name.substring(2);
+ removeItalics = true;
+ } else if (name.startsWith("<r>")) {
+ name = name.substring(3);
+ removeItalics = true;
+ } else if (name.startsWith("<reset>")) {
+ name = name.substring(7);
+ removeItalics = true;
+ }
+ }
+ if (this.player.level().purpurConfig.anvilAllowColors) {
+ if (player.hasPermission("purpur.anvil.color")) {
+ java.util.regex.Matcher matcher = java.util.regex.Pattern.compile("(?i)&([0-9a-fr])").matcher(name);
+ while (matcher.find()) {
+ String match = matcher.group(1);
+ name = name.replace("&" + match, "\u00a7" + match.toLowerCase(java.util.Locale.ROOT));
+ }
+ //name = name.replaceAll("(?i)&([0-9a-fr])", "\u00a7$1");
+ }
+ if (player.hasPermission("purpur.anvil.format")) {
+ java.util.regex.Matcher matcher = java.util.regex.Pattern.compile("(?i)&([k-or])").matcher(name);
+ while (matcher.find()) {
+ String match = matcher.group(1);
+ name = name.replace("&" + match, "\u00a7" + match.toLowerCase(java.util.Locale.ROOT));
+ }
+ //name = name.replaceAll("(?i)&([l-or])", "\u00a7$1");
+ }
+ }
+ net.kyori.adventure.text.Component component;
+ if (this.player.level().purpurConfig.anvilColorsUseMiniMessage && player.hasPermission("purpur.anvil.minimessage")) {
+ component = net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.bukkit.ChatColor.stripColor(name));
+ } else {
+ component = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(name);
+ }
+ if (removeItalics) {
+ component = component.decoration(net.kyori.adventure.text.format.TextDecoration.ITALIC, false);
+ }
+ itemstack1.set(DataComponents.CUSTOM_NAME, io.papermc.paper.adventure.PaperAdventure.asVanilla(component));
+ }
+ else
+ // Purpur end
itemstack1.set(DataComponents.CUSTOM_NAME, Component.literal(this.itemName));
}
} else if (itemstack.has(DataComponents.CUSTOM_NAME)) {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index efebca2a6dd217d853a27516c29be89421c1df68..7a7b8725f7a0b1a193b4e19510c386b46604f006 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -288,6 +288,13 @@ public class PurpurWorldConfig {
});
}
+ public boolean anvilAllowColors = false;
+ public boolean anvilColorsUseMiniMessage;
+ private void anvilSettings() {
+ anvilAllowColors = getBoolean("blocks.anvil.allow-colors", anvilAllowColors);
+ anvilColorsUseMiniMessage = getBoolean("blocks.anvil.use-mini-message", anvilColorsUseMiniMessage);
+ }
+
public boolean bedExplode = true;
public double bedExplosionPower = 5.0D;
public boolean bedExplosionFire = true;

View File

@@ -1,38 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Sat, 8 Aug 2020 16:11:51 -0500
Subject: [PATCH] Add option to disable dolphin treasure searching
diff --git a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java
index a5a23c7f733d49c20c870f819eec2607781dccbf..be74a5732bc24eb3c909d28b4ef46d5175d999d2 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java
@@ -493,6 +493,7 @@ public class Dolphin extends AgeableWaterCreature {
@Override
public boolean canUse() {
+ if (this.dolphin.level().purpurConfig.dolphinDisableTreasureSearching) return false; // Purpur
return this.dolphin.gotFish() && this.dolphin.getAirSupply() >= 100;
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 7a7b8725f7a0b1a193b4e19510c386b46604f006..109c2d5ba677eee65f44cd93b0fdcee22d04d17b 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -669,6 +669,7 @@ public class PurpurWorldConfig {
public float dolphinSpitDamage = 2.0F;
public double dolphinMaxHealth = 10.0D;
public double dolphinScale = 1.0D;
+ public boolean dolphinDisableTreasureSearching = false;
private void dolphinSettings() {
dolphinRidable = getBoolean("mobs.dolphin.ridable", dolphinRidable);
dolphinControllable = getBoolean("mobs.dolphin.controllable", dolphinControllable);
@@ -682,6 +683,7 @@ public class PurpurWorldConfig {
}
dolphinMaxHealth = getDouble("mobs.dolphin.attributes.max_health", dolphinMaxHealth);
dolphinScale = Mth.clamp(getDouble("mobs.dolphin.attributes.scale", dolphinScale), 0.0625D, 16.0D);
+ dolphinDisableTreasureSearching = getBoolean("mobs.dolphin.disable-treasure-searching", dolphinDisableTreasureSearching);
}
public boolean donkeyRidableInWater = false;

View File

@@ -1,49 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Mon, 10 Aug 2020 21:46:22 -0500
Subject: [PATCH] Short enderman height
diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
index 23b921a79bd563fd0a1bf7afd55a8e52ff1da521..40ae00146381a9a1ec70ffae5c683b46c72c56ff 100644
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
@@ -389,7 +389,8 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
@Nullable
private Component description;
private final Optional<ResourceKey<LootTable>> lootTable;
- private final EntityDimensions dimensions;
+ private EntityDimensions dimensions; // Purpur - remove final
+ public void setDimensions(EntityDimensions dimensions) { this.dimensions = dimensions; } // Purpur
private final float spawnDimensionsScale;
private final FeatureFlagSet requiredFeatures;
diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
index 04fdefe4c38ef9ed3001f95b34d1632944fcae85..257eac851b6f4628b94784cab7a5cd4ec804944a 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
@@ -415,6 +415,7 @@ public class EnderMan extends Monster implements NeutralMob {
if (this.isInvulnerableTo(world, source)) {
return false;
} else if (getRider() != null && this.isControllable()) { return super.hurtServer(world, source, amount); // Purpur - no teleporting on damage
+ } else if (org.purpurmc.purpur.PurpurConfig.endermanShortHeight && source.is(net.minecraft.world.damagesource.DamageTypes.IN_WALL)) { return false; // Purpur - no suffocation damage if short height
} else {
boolean flag = source.getDirectEntity() instanceof ThrownPotion;
boolean flag1;
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index 9f98b87ccc60db9a531180de1ed649de118db56f..0cafa4bbc530a80277cbf323f8d62dee9b08a426 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -247,6 +247,12 @@ public class PurpurConfig {
enderChestPermissionRows = getBoolean("settings.blocks.ender_chest.use-permissions-for-rows", enderChestPermissionRows);
}
+ public static boolean endermanShortHeight = false;
+ private static void entitySettings() {
+ endermanShortHeight = getBoolean("settings.entity.enderman.short-height", endermanShortHeight);
+ if (endermanShortHeight) EntityType.ENDERMAN.setDimensions(EntityDimensions.scalable(0.6F, 1.9F));
+ }
+
public static boolean allowWaterPlacementInTheEnd = true;
private static void allowWaterPlacementInEnd() {
allowWaterPlacementInTheEnd = getBoolean("settings.allow-water-placement-in-the-end", allowWaterPlacementInTheEnd);

View File

@@ -1,75 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Thu, 13 Aug 2020 04:00:26 -0500
Subject: [PATCH] Stop squids floating on top of water
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 56225797f1cf0294c1e6aa824d8c146dca530e9f..bf22cfc2b770fd4dc73168745d535fb6598412ca 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -4748,6 +4748,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return Mth.lerp(delta, this.yRotO, this.yRot);
}
+ // Purpur start
+ public AABB getAxisForFluidCheck() {
+ return this.getBoundingBox().deflate(0.001D);
+ }
+ // Purpur end
+
// Paper start - optimise collisions
public boolean updateFluidHeightAndDoFluidPushing(final TagKey<Fluid> fluid, final double flowScale) {
if (this.touchingUnloadedChunk()) {
diff --git a/src/main/java/net/minecraft/world/entity/animal/Squid.java b/src/main/java/net/minecraft/world/entity/animal/Squid.java
index 6275cb4ca2b06d8b1b3d53a2b79115bd36da4129..7891d015d2f8dadcff8f457145574ea8ba48fe8d 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Squid.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Squid.java
@@ -78,6 +78,12 @@ public class Squid extends AgeableWaterCreature {
this.getAttribute(Attributes.SCALE).setBaseValue(this.level().purpurConfig.squidScale);
}
+ @Override
+ public net.minecraft.world.phys.AABB getAxisForFluidCheck() {
+ // Stops squids from floating just over the water
+ return super.getAxisForFluidCheck().offsetY(level().purpurConfig.squidOffsetWaterCheck);
+ }
+
@Override
protected void registerGoals() {
this.goalSelector.addGoal(0, new Squid.SquidRandomMovementGoal(this));
diff --git a/src/main/java/net/minecraft/world/phys/AABB.java b/src/main/java/net/minecraft/world/phys/AABB.java
index 6cf6d4ec7b9e43c7b2b4c0e2fb080964ff588130..e74866e5195a5eeae7666ad7be750edac5947094 100644
--- a/src/main/java/net/minecraft/world/phys/AABB.java
+++ b/src/main/java/net/minecraft/world/phys/AABB.java
@@ -551,4 +551,10 @@ public class AABB {
public static AABB ofSize(Vec3 center, double dx, double dy, double dz) {
return new AABB(center.x - dx / 2.0, center.y - dy / 2.0, center.z - dz / 2.0, center.x + dx / 2.0, center.y + dy / 2.0, center.z + dz / 2.0);
}
+
+ // Purpur - tuinity added method
+ public final AABB offsetY(double dy) {
+ return new AABB(this.minX, this.minY + dy, this.minZ, this.maxX, this.maxY + dy, this.maxZ);
+ }
+ // Purpur
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 109c2d5ba677eee65f44cd93b0fdcee22d04d17b..b04c1c2534bec8f2eee873b43969843f54644dca 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1611,6 +1611,7 @@ public class PurpurWorldConfig {
public double squidMaxHealth = 10.0D;
public double squidScale = 1.0D;
public boolean squidImmuneToEAR = true;
+ public double squidOffsetWaterCheck = 0.0D;
private void squidSettings() {
squidRidable = getBoolean("mobs.squid.ridable", squidRidable);
squidControllable = getBoolean("mobs.squid.controllable", squidControllable);
@@ -1622,6 +1623,7 @@ public class PurpurWorldConfig {
squidMaxHealth = getDouble("mobs.squid.attributes.max_health", squidMaxHealth);
squidScale = Mth.clamp(getDouble("mobs.squid.attributes.scale", squidScale), 0.0625D, 16.0D);
squidImmuneToEAR = getBoolean("mobs.squid.immune-to-EAR", squidImmuneToEAR);
+ squidOffsetWaterCheck = getDouble("mobs.squid.water-offset-check", squidOffsetWaterCheck);
}
public boolean spiderRidable = false;

View File

@@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Mon, 17 Aug 2020 17:34:33 -0500
Subject: [PATCH] Crying obsidian valid for portal frames
diff --git a/src/main/java/net/minecraft/world/level/portal/PortalShape.java b/src/main/java/net/minecraft/world/level/portal/PortalShape.java
index 90056822cd17f3d33d14b3f94b34750ee522a0a9..acdff7b4a00d563739fd301c3633a266875296fa 100644
--- a/src/main/java/net/minecraft/world/level/portal/PortalShape.java
+++ b/src/main/java/net/minecraft/world/level/portal/PortalShape.java
@@ -35,7 +35,7 @@ public class PortalShape {
private static final int MIN_HEIGHT = 3;
public static final int MAX_HEIGHT = 21;
private static final BlockBehaviour.StatePredicate FRAME = (iblockdata, iblockaccess, blockposition) -> {
- return iblockdata.is(Blocks.OBSIDIAN);
+ return iblockdata.is(Blocks.OBSIDIAN) || (org.purpurmc.purpur.PurpurConfig.cryingObsidianValidForPortalFrame && iblockdata.is(Blocks.CRYING_OBSIDIAN)); // Purpur
};
private static final float SAFE_TRAVEL_MAX_ENTITY_XY = 4.0F;
private static final double SAFE_TRAVEL_MAX_VERTICAL_DELTA = 1.0D;
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index 0cafa4bbc530a80277cbf323f8d62dee9b08a426..80335c5915da347cc779dfd2c44d87e8329ad336 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -215,6 +215,7 @@ public class PurpurConfig {
public static int barrelRows = 3;
public static boolean enderChestSixRows = false;
public static boolean enderChestPermissionRows = false;
+ public static boolean cryingObsidianValidForPortalFrame = false;
private static void blockSettings() {
if (version < 3) {
boolean oldValue = getBoolean("settings.barrel.packed-barrels", true);
@@ -245,6 +246,7 @@ public class PurpurConfig {
enderChestSixRows = getBoolean("settings.blocks.ender_chest.six-rows", enderChestSixRows);
org.bukkit.event.inventory.InventoryType.ENDER_CHEST.setDefaultSize(enderChestSixRows ? 54 : 27);
enderChestPermissionRows = getBoolean("settings.blocks.ender_chest.use-permissions-for-rows", enderChestPermissionRows);
+ cryingObsidianValidForPortalFrame = getBoolean("settings.blocks.crying_obsidian.valid-for-portal-frame", cryingObsidianValidForPortalFrame);
}
public static boolean endermanShortHeight = false;

View File

@@ -1,47 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Mon, 17 Aug 2020 19:32:05 -0500
Subject: [PATCH] Entities can use portals
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index bf22cfc2b770fd4dc73168745d535fb6598412ca..c5880e627ff48e5e176baf483c08f35a1af488f8 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -3441,7 +3441,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
public void setAsInsidePortal(Portal portal, BlockPos pos) {
if (this.isOnPortalCooldown()) {
this.setPortalCooldown();
- } else {
+ } else if (this.level.purpurConfig.entitiesCanUsePortals || this instanceof ServerPlayer) { // Purpur - Entities can use portals
if (this.portalProcess != null && this.portalProcess.isSamePortal(portal)) {
if (!this.portalProcess.isInsidePortalThisTick()) {
this.portalProcess.updateEntryPosition(pos.immutable());
@@ -4160,7 +4160,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
// CraftBukkit end
public boolean canUsePortal(boolean allowVehicles) {
- return (allowVehicles || !this.isPassenger()) && this.isAlive();
+ return (allowVehicles || !this.isPassenger()) && this.isAlive() && (this.level.purpurConfig.entitiesCanUsePortals || this instanceof ServerPlayer); // Purpur - Entities can use portals
}
public boolean canTeleport(Level from, Level to) {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index b04c1c2534bec8f2eee873b43969843f54644dca..a28548332baf610521a308a560a858b3fc737b60 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -101,12 +101,14 @@ public class PurpurWorldConfig {
public boolean disableDropsOnCrammingDeath = false;
public boolean milkCuresBadOmen = true;
public double tridentLoyaltyVoidReturnHeight = 0.0D;
+ public boolean entitiesCanUsePortals = true;
private void miscGameplayMechanicsSettings() {
useBetterMending = getBoolean("gameplay-mechanics.use-better-mending", useBetterMending);
boatEjectPlayersOnLand = getBoolean("gameplay-mechanics.boat.eject-players-on-land", boatEjectPlayersOnLand);
disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath);
milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen);
tridentLoyaltyVoidReturnHeight = getDouble("gameplay-mechanics.trident-loyalty-void-return-height", tridentLoyaltyVoidReturnHeight);
+ entitiesCanUsePortals = getBoolean("gameplay-mechanics.entities-can-use-portals", entitiesCanUsePortals);
}
public int elytraDamagePerSecond = 1;

View File

@@ -1,46 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Thu, 20 Aug 2020 17:38:12 -0700
Subject: [PATCH] Customizable wither health and healing
Adds the ability to customize the health of the wither, as well as the amount that it heals, and how often.
diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
index 19a7f7926eeb9c4e4d5bbd5e4768d99c456e8f71..e808cd292afc9531d5ec6025e1e83076ba487c0f 100644
--- a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
+++ b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
@@ -526,8 +526,10 @@ public class WitherBoss extends Monster implements RangedAttackMob {
}
}
- if (this.tickCount % 20 == 0) {
- this.heal(1.0F, EntityRegainHealthEvent.RegainReason.REGEN); // CraftBukkit
+ // Purpur start - customizable heal rate and amount
+ if (this.tickCount % level().purpurConfig.witherHealthRegenDelay == 0) {
+ this.heal(level().purpurConfig.witherHealthRegenAmount, EntityRegainHealthEvent.RegainReason.REGEN); // CraftBukkit
+ // Purpur end
}
this.bossEvent.setProgress(this.getHealth() / this.getMaxHealth());
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index a28548332baf610521a308a560a858b3fc737b60..e323914f8694043e7b08a2518169695f582bc1a8 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1876,6 +1876,8 @@ public class PurpurWorldConfig {
public double witherMaxY = 320D;
public double witherMaxHealth = 300.0D;
public double witherScale = 1.0D;
+ public float witherHealthRegenAmount = 1.0f;
+ public int witherHealthRegenDelay = 20;
private void witherSettings() {
witherRidable = getBoolean("mobs.wither.ridable", witherRidable);
witherRidableInWater = getBoolean("mobs.wither.ridable-in-water", witherRidableInWater);
@@ -1892,6 +1894,8 @@ public class PurpurWorldConfig {
}
witherMaxHealth = getDouble("mobs.wither.attributes.max_health", witherMaxHealth);
witherScale = Mth.clamp(getDouble("mobs.wither.attributes.scale", witherScale), 0.0625D, 16.0D);
+ witherHealthRegenAmount = (float) getDouble("mobs.wither.health-regen-amount", witherHealthRegenAmount);
+ witherHealthRegenDelay = getInt("mobs.wither.health-regen-delay", witherHealthRegenDelay);
}
public boolean witherSkeletonRidable = false;

View File

@@ -1,99 +0,0 @@
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 c05d0d836ced6db6b4a3e85fe0973dd7b1aaad81..7f12f6a0f8ea0a2570ccb8f6e7f786197ee0ef11 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -605,7 +605,24 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
// CraftBukkit end
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 net.minecraft.world.level.levelgen.PhantomSpawner());
+ }
+ if (purpurConfig.patrolSpawning) {
+ customSpawners.add(new net.minecraft.world.level.levelgen.PatrolSpawner());
+ }
+ if (purpurConfig.catSpawning) {
+ customSpawners.add(new net.minecraft.world.entity.npc.CatSpawner());
+ }
+ if (purpurConfig.villageSiegeSpawning) {
+ customSpawners.add(new net.minecraft.world.entity.ai.village.VillageSiege());
+ }
+ if (purpurConfig.villagerTraderSpawning) {
+ customSpawners.add(new net.minecraft.world.entity.npc.WanderingTraderSpawner(iworlddataserver));
+ }
+ // Purpur end
this.serverLevelData = iworlddataserver;
ChunkGenerator chunkgenerator = worlddimension.generator();
// CraftBukkit start
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 a728dcbf956f108f01c966c7531449a506a14a87..4c1378132201c1e5d1bc01f8c0cbba91629bcffa 100644
--- a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java
+++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java
@@ -160,7 +160,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(net.minecraft.core.Direction.DOWN);
+ } while (!world.getBlockState(blockposition2).isAir());
+ do {
+ blockposition2.relative(net.minecraft.core.Direction.DOWN);
+ } while (world.getBlockState(blockposition2).isAir() && blockposition2.getY() > 0);
+ }
+ // Purpur end
if (spawnplacementtype.isSpawnPositionOk(world, blockposition2, EntityType.WANDERING_TRADER)) {
blockposition1 = blockposition2;
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index e323914f8694043e7b08a2518169695f582bc1a8..9072bdd2fdb1c15ea1dbc599cb96fd82750ddcc6 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -70,6 +70,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<Boolean> 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));
@@ -232,6 +238,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<Boolean> 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;

View File

@@ -1,70 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Thu, 27 Aug 2020 13:48:52 -0700
Subject: [PATCH] Raid cooldown setting
diff --git a/src/main/java/net/minecraft/world/entity/raid/Raids.java b/src/main/java/net/minecraft/world/entity/raid/Raids.java
index 439d61d8689fabe940006b9b317a6810175dccfb..6b30941a84054efb5fcccb5d9e6c80d713a23889 100644
--- a/src/main/java/net/minecraft/world/entity/raid/Raids.java
+++ b/src/main/java/net/minecraft/world/entity/raid/Raids.java
@@ -26,6 +26,7 @@ import net.minecraft.world.phys.Vec3;
public class Raids extends SavedData {
private static final String RAID_FILE_ID = "raids";
+ public final Map<java.util.UUID, Integer> playerCooldowns = Maps.newHashMap();
public final Map<Integer, Raid> raidMap = Maps.newHashMap();
private final ServerLevel level;
private int nextAvailableID;
@@ -51,6 +52,17 @@ public class Raids extends SavedData {
public void tick() {
++this.tick;
+ // Purpur start
+ if (level.purpurConfig.raidCooldownSeconds != 0 && this.tick % 20 == 0) {
+ com.google.common.collect.ImmutableMap.copyOf(playerCooldowns).forEach((uuid, i) -> {
+ if (i < 1) {
+ playerCooldowns.remove(uuid);
+ } else {
+ playerCooldowns.put(uuid, i - 1);
+ }
+ });
+ }
+ // Purpur end
Iterator<Raid> iterator = this.raidMap.values().iterator();
while (iterator.hasNext()) {
@@ -122,11 +134,13 @@ public class Raids extends SavedData {
*/
if (!raid.isStarted() || (raid.isInProgress() && raid.getRaidOmenLevel() < raid.getMaxRaidOmenLevel())) { // CraftBukkit - fixed a bug with raid: players could add up Bad Omen level even when the raid had finished
+ if (level.purpurConfig.raidCooldownSeconds != 0 && playerCooldowns.containsKey(player.getUUID())) return null; // Purpur
// CraftBukkit start
if (!org.bukkit.craftbukkit.event.CraftEventFactory.callRaidTriggerEvent(raid, player)) {
player.removeEffect(net.minecraft.world.effect.MobEffects.RAID_OMEN);
return null;
}
+ if (level.purpurConfig.raidCooldownSeconds != 0) playerCooldowns.put(player.getUUID(), level.purpurConfig.raidCooldownSeconds); // Purpur
if (!raid.isStarted() && !this.raidMap.containsKey(raid.getId())) {
this.raidMap.put(raid.getId(), raid);
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 9072bdd2fdb1c15ea1dbc599cb96fd82750ddcc6..0e7473973fe06f51e28bb8651856ed52a9a51d92 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -108,6 +108,7 @@ public class PurpurWorldConfig {
public boolean milkCuresBadOmen = true;
public double tridentLoyaltyVoidReturnHeight = 0.0D;
public boolean entitiesCanUsePortals = true;
+ public int raidCooldownSeconds = 0;
private void miscGameplayMechanicsSettings() {
useBetterMending = getBoolean("gameplay-mechanics.use-better-mending", useBetterMending);
boatEjectPlayersOnLand = getBoolean("gameplay-mechanics.boat.eject-players-on-land", boatEjectPlayersOnLand);
@@ -115,6 +116,7 @@ public class PurpurWorldConfig {
milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen);
tridentLoyaltyVoidReturnHeight = getDouble("gameplay-mechanics.trident-loyalty-void-return-height", tridentLoyaltyVoidReturnHeight);
entitiesCanUsePortals = getBoolean("gameplay-mechanics.entities-can-use-portals", entitiesCanUsePortals);
+ raidCooldownSeconds = getInt("gameplay-mechanics.raid-cooldown-seconds", raidCooldownSeconds);
}
public int elytraDamagePerSecond = 1;

View File

@@ -1,91 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: nitricspace <nitricspace@users.noreply.github.com>
Date: Mon, 21 Sep 2020 23:19:43 +0100
Subject: [PATCH] Add option to disable zombie aggressiveness towards villagers
diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java
index 3470720466fc81f977c18e3a97bb918926025a22..c8651af322927c46d075f88890fcd0476bd85440 100644
--- a/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java
+++ b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java
@@ -136,6 +136,10 @@ public class MobGoalHelper {
static {
// TODO these kinda should be checked on each release, in case obfuscation changes
deobfuscationMap.put("abstract_skeleton_1", "abstract_skeleton_melee");
+ // Purpur start
+ deobfuscationMap.put("zombie_1", "zombie_attack_villager");
+ deobfuscationMap.put("drowned_1", "drowned_attack_villager");
+ // Purpur end
ignored.add("goal_selector_1");
ignored.add("goal_selector_2");
diff --git a/src/main/java/net/minecraft/world/entity/monster/Drowned.java b/src/main/java/net/minecraft/world/entity/monster/Drowned.java
index 7dc7f8734ffb3c5e50c763cb4e750d20c6e22281..7b3c999a03d91c167dfc1a1c90750b2efd4eb675 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Drowned.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Drowned.java
@@ -125,7 +125,19 @@ public class Drowned extends Zombie implements RangedAttackMob {
this.goalSelector.addGoal(7, new RandomStrollGoal(this, 1.0));
this.targetSelector.addGoal(1, new HurtByTargetGoal(this, Drowned.class).setAlertOthers(ZombifiedPiglin.class));
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (target, world) -> this.okTarget(target)));
- if (this.level().spigotConfig.zombieAggressiveTowardsVillager) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false)); // Paper - Check drowned for villager aggression config
+ // Purpur start
+ if (this.level().spigotConfig.zombieAggressiveTowardsVillager) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false) { // Paper - Check drowned for villager aggression config
+ @Override
+ public boolean canUse() {
+ return (level().purpurConfig.zombieAggressiveTowardsVillagerWhenLagging || !level().getServer().server.isLagging()) && super.canUse();
+ }
+
+ @Override
+ public boolean canContinueToUse() {
+ return (level().purpurConfig.zombieAggressiveTowardsVillagerWhenLagging || !level().getServer().server.isLagging()) && super.canContinueToUse();
+ }
+ });
+ // Purpur end
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true));
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Axolotl.class, true, false));
this.targetSelector.addGoal(5, new NearestAttackableTargetGoal<>(this, Turtle.class, 10, true, false, Turtle.BABY_ON_LAND_SELECTOR));
diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
index cb5cf34781de4e87074a70a447fd463280147bdc..e6fb53b828c1a2e76d398e88449260f6206145c3 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
@@ -161,7 +161,19 @@ public class Zombie extends Monster {
this.goalSelector.addGoal(7, new WaterAvoidingRandomStrollGoal(this, 1.0D));
this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[0])).setAlertOthers(ZombifiedPiglin.class));
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true));
- if ( this.level().spigotConfig.zombieAggressiveTowardsVillager ) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false)); // Spigot
+ // Purpur start
+ if ( this.level().spigotConfig.zombieAggressiveTowardsVillager ) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false) { // Spigot
+ @Override
+ public boolean canUse() {
+ return (level().purpurConfig.zombieAggressiveTowardsVillagerWhenLagging || !level().getServer().server.isLagging()) && super.canUse();
+ }
+
+ @Override
+ public boolean canContinueToUse() {
+ return (level().purpurConfig.zombieAggressiveTowardsVillagerWhenLagging || !level().getServer().server.isLagging()) && super.canContinueToUse();
+ }
+ });
+ // Purpur end
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true));
this.targetSelector.addGoal(5, new NearestAttackableTargetGoal<>(this, Turtle.class, 10, true, false, Turtle.BABY_ON_LAND_SELECTOR));
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 0e7473973fe06f51e28bb8651856ed52a9a51d92..f6771afafe3e9e672059f504982e90449492449c 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1984,6 +1984,7 @@ public class PurpurWorldConfig {
public boolean zombieJockeyOnlyBaby = true;
public double zombieJockeyChance = 0.05D;
public boolean zombieJockeyTryExistingChickens = true;
+ public boolean zombieAggressiveTowardsVillagerWhenLagging = true;
private void zombieSettings() {
zombieRidable = getBoolean("mobs.zombie.ridable", zombieRidable);
zombieRidableInWater = getBoolean("mobs.zombie.ridable-in-water", zombieRidableInWater);
@@ -1999,6 +2000,7 @@ public class PurpurWorldConfig {
zombieJockeyOnlyBaby = getBoolean("mobs.zombie.jockey.only-babies", zombieJockeyOnlyBaby);
zombieJockeyChance = getDouble("mobs.zombie.jockey.chance", zombieJockeyChance);
zombieJockeyTryExistingChickens = getBoolean("mobs.zombie.jockey.try-existing-chickens", zombieJockeyTryExistingChickens);
+ zombieAggressiveTowardsVillagerWhenLagging = getBoolean("mobs.zombie.aggressive-towards-villager-when-lagging", zombieAggressiveTowardsVillagerWhenLagging);
}
public boolean zombieHorseRidable = false;

View File

@@ -1,42 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Sat, 3 Oct 2020 17:40:52 -0500
Subject: [PATCH] Add predicate to recipe's ExactChoice ingredient
diff --git a/src/main/java/net/minecraft/world/item/crafting/Ingredient.java b/src/main/java/net/minecraft/world/item/crafting/Ingredient.java
index 812f919a7a7e309c8513f44104f092496037608f..10730b307971915f52b3e41068a864b8ee1352b4 100644
--- a/src/main/java/net/minecraft/world/item/crafting/Ingredient.java
+++ b/src/main/java/net/minecraft/world/item/crafting/Ingredient.java
@@ -45,6 +45,7 @@ public final class Ingredient implements Predicate<ItemStack> {
// CraftBukkit start
@Nullable
private List<ItemStack> itemStacks;
+ public Predicate<org.bukkit.inventory.ItemStack> predicate; // Purpur
public boolean isExact() {
return this.itemStacks != null;
@@ -100,6 +101,11 @@ public final class Ingredient implements Predicate<ItemStack> {
return false;
}
+ // Purpur start
+ if (predicate != null) {
+ return predicate.test(itemstack.asBukkitCopy());
+ }
+ // Purpur end
// CraftBukkit end
List<Holder<Item>> list = this.items();
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
index 3592091c6d1371224e82e1f95b003951ad2f8779..4fdc78a9c74b42a8894030221e0452493d68020e 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
@@ -38,6 +38,7 @@ public interface CraftRecipe extends Recipe {
stack = Ingredient.of(((RecipeChoice.MaterialChoice) bukkit).getChoices().stream().map((mat) -> CraftItemType.bukkitToMinecraft(mat)));
} else if (bukkit instanceof RecipeChoice.ExactChoice) {
stack = Ingredient.ofStacks(((RecipeChoice.ExactChoice) bukkit).getChoices().stream().map((mat) -> CraftItemStack.asNMSCopy(mat)).toList());
+ stack.predicate = ((RecipeChoice.ExactChoice) bukkit).getPredicate(); // Purpur
// Paper start - support "empty" choices - legacy method that spigot might incorrectly call
// Their impl of Ingredient.of() will error, ingredients need at least one entry.
// Callers running into this exception may have passed an incorrect empty() recipe choice to a non-empty slot or

View File

@@ -1,93 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Sun, 4 Oct 2020 12:00:42 -0500
Subject: [PATCH] Flying squids! Oh my!
diff --git a/src/main/java/net/minecraft/world/entity/GlowSquid.java b/src/main/java/net/minecraft/world/entity/GlowSquid.java
index 27aee968718af1ae78e2076ddc890114b2c9bb94..0f5be53c6f6a66c61dc3f2bebeb18ca61d06c10d 100644
--- a/src/main/java/net/minecraft/world/entity/GlowSquid.java
+++ b/src/main/java/net/minecraft/world/entity/GlowSquid.java
@@ -43,6 +43,11 @@ public class GlowSquid extends Squid {
this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.glowSquidMaxHealth);
}
+ @Override
+ public boolean canFly() {
+ return this.level().purpurConfig.glowSquidsCanFly;
+ }
+
@Override
protected ParticleOptions getInkParticle() {
return ParticleTypes.GLOW_SQUID_INK;
diff --git a/src/main/java/net/minecraft/world/entity/animal/Squid.java b/src/main/java/net/minecraft/world/entity/animal/Squid.java
index 7891d015d2f8dadcff8f457145574ea8ba48fe8d..4d2992a16865fa60dd38d0ff6dc341f9c5f6bd00 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Squid.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Squid.java
@@ -84,6 +84,15 @@ public class Squid extends AgeableWaterCreature {
return super.getAxisForFluidCheck().offsetY(level().purpurConfig.squidOffsetWaterCheck);
}
+ public boolean canFly() {
+ return this.level().purpurConfig.squidsCanFly;
+ }
+
+ @Override
+ public boolean isInWater() {
+ return this.wasTouchingWater || canFly();
+ }
+
@Override
protected void registerGoals() {
this.goalSelector.addGoal(0, new Squid.SquidRandomMovementGoal(this));
@@ -162,6 +171,7 @@ public class Squid extends AgeableWaterCreature {
}
if (this.isInWaterOrBubble()) {
+ if (canFly()) setNoGravity(!wasTouchingWater); // Purpur
if (this.tentacleMovement < (float) Math.PI) {
float f = this.tentacleMovement / (float) Math.PI;
this.tentacleAngle = Mth.sin(f * f * (float) Math.PI) * (float) Math.PI * 0.25F;
@@ -374,7 +384,7 @@ public class Squid extends AgeableWaterCreature {
int i = this.squid.getNoActionTime();
if (i > 100) {
this.squid.movementVector = Vec3.ZERO;
- } else if (this.squid.getRandom().nextInt(reducedTickDelay(50)) == 0 || !this.squid.wasTouchingWater || !this.squid.hasMovementVector()) {
+ } else if (this.squid.getRandom().nextInt(reducedTickDelay(50)) == 0 || !this.squid.isInWater() || !this.squid.hasMovementVector()) { // Purpur
float f = this.squid.getRandom().nextFloat() * (float) (Math.PI * 2);
this.squid.movementVector = new Vec3(
(double)(Mth.cos(f) * 0.2F), (double)(-0.1F + this.squid.getRandom().nextFloat() * 0.2F), (double)(Mth.sin(f) * 0.2F)
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index f6771afafe3e9e672059f504982e90449492449c..fea279b9fbd7f989bf26f0fc1254b1ecb8ac4342 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -946,11 +946,13 @@ public class PurpurWorldConfig {
public boolean glowSquidControllable = true;
public double glowSquidMaxHealth = 10.0D;
public double glowSquidScale = 1.0D;
+ public boolean glowSquidsCanFly = false;
private void glowSquidSettings() {
glowSquidRidable = getBoolean("mobs.glow_squid.ridable", glowSquidRidable);
glowSquidControllable = getBoolean("mobs.glow_squid.controllable", glowSquidControllable);
glowSquidMaxHealth = getDouble("mobs.glow_squid.attributes.max_health", glowSquidMaxHealth);
glowSquidScale = Mth.clamp(getDouble("mobs.glow_squid.attributes.scale", glowSquidScale), 0.0625D, 16.0D);
+ glowSquidsCanFly = getBoolean("mobs.glow_squid.can-fly", glowSquidsCanFly);
}
public boolean goatRidable = false;
@@ -1637,6 +1639,7 @@ public class PurpurWorldConfig {
public double squidScale = 1.0D;
public boolean squidImmuneToEAR = true;
public double squidOffsetWaterCheck = 0.0D;
+ public boolean squidsCanFly = false;
private void squidSettings() {
squidRidable = getBoolean("mobs.squid.ridable", squidRidable);
squidControllable = getBoolean("mobs.squid.controllable", squidControllable);
@@ -1649,6 +1652,7 @@ public class PurpurWorldConfig {
squidScale = Mth.clamp(getDouble("mobs.squid.attributes.scale", squidScale), 0.0625D, 16.0D);
squidImmuneToEAR = getBoolean("mobs.squid.immune-to-EAR", squidImmuneToEAR);
squidOffsetWaterCheck = getDouble("mobs.squid.water-offset-check", squidOffsetWaterCheck);
+ squidsCanFly = getBoolean("mobs.squid.can-fly", squidsCanFly);
}
public boolean spiderRidable = false;

View File

@@ -1,47 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Sun, 4 Oct 2020 19:08:53 -0500
Subject: [PATCH] Infinity bow settings
diff --git a/src/main/java/net/minecraft/world/item/BowItem.java b/src/main/java/net/minecraft/world/item/BowItem.java
index bb593209c95c9cf1f9c5d52d52fab4a33ddbabcf..1d4d0799a86b9940b5e3b614c5a188ade5133f7e 100644
--- a/src/main/java/net/minecraft/world/item/BowItem.java
+++ b/src/main/java/net/minecraft/world/item/BowItem.java
@@ -28,6 +28,11 @@ public class BowItem extends ProjectileWeaponItem {
return false;
} else {
ItemStack itemStack = player.getProjectile(stack);
+ // Purpur start
+ if (world.purpurConfig.infinityWorksWithoutArrows && itemStack.isEmpty() && net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.INFINITY, stack) > 0) {
+ itemStack = new ItemStack(Items.ARROW);
+ }
+ // Purpur end
if (itemStack.isEmpty()) {
return false;
} else {
@@ -89,7 +94,7 @@ public class BowItem extends ProjectileWeaponItem {
public InteractionResult use(Level world, Player user, InteractionHand hand) {
ItemStack itemStack = user.getItemInHand(hand);
boolean bl = !user.getProjectile(itemStack).isEmpty();
- if (!user.hasInfiniteMaterials() && !bl) {
+ if (!user.hasInfiniteMaterials() && !bl && !(world.purpurConfig.infinityWorksWithoutArrows && net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.INFINITY, itemStack) > 0)) { // Purpur
return InteractionResult.FAIL;
} else {
user.startUsingItem(hand);
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index fea279b9fbd7f989bf26f0fc1254b1ecb8ac4342..0716bd2728be4fcaa4f13485591008ce270ecf82 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -135,6 +135,11 @@ public class PurpurWorldConfig {
entityLifeSpan = getInt("gameplay-mechanics.entity-lifespan", entityLifeSpan);
}
+ public boolean infinityWorksWithoutArrows = false;
+ private void infinityArrowsSettings() {
+ infinityWorksWithoutArrows = getBoolean("gameplay-mechanics.infinity-bow.works-without-arrows", infinityWorksWithoutArrows);
+ }
+
public List<Item> itemImmuneToCactus = new ArrayList<>();
public List<Item> itemImmuneToExplosion = new ArrayList<>();
public List<Item> itemImmuneToFire = new ArrayList<>();

View File

@@ -1,94 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Sat, 10 Oct 2020 14:29:55 -0500
Subject: [PATCH] Configurable daylight cycle
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index e1858bc2b043f0edf5d3f1393340f40aa7bcb36a..1349b2bbdc38e9f13617c78d3f1079b9e36aece4 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1858,7 +1858,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
long worldTime = level.getGameTime();
final ClientboundSetTimePacket worldPacket = new ClientboundSetTimePacket(worldTime, dayTime, doDaylight);
for (Player entityhuman : level.players()) {
- if (!(entityhuman instanceof ServerPlayer) || (tickCount + entityhuman.getId()) % 20 != 0) {
+ if (!(entityhuman instanceof ServerPlayer) || (!level.isForceTime() && (tickCount + entityhuman.getId()) % 20 != 0)) { // Purpur
continue;
}
ServerPlayer entityplayer = (ServerPlayer) entityhuman;
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 8584dfc20fcbf8c1f490dfe117f2cd72a5aaf3be..cc1edc2e4d62501fcce5353e622e24268b1ab698 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -223,6 +223,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
private final StructureManager structureManager;
private final StructureCheck structureCheck;
private final boolean tickTime;
+ private double preciseTime; // Purpur
+ private boolean forceTime; // Purpur
private final RandomSequences randomSequences;
// CraftBukkit start
@@ -694,6 +696,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
this.chunkDataController = new ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.ChunkDataController((ServerLevel)(Object)this, this.chunkTaskScheduler);
// Paper end - rewrite chunk system
this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit
+ this.preciseTime = this.serverLevelData.getDayTime(); // Purpur
}
// Paper start
@@ -873,6 +876,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
this.serverLevelData.getScheduledEvents().tick(this.server, i);
Profiler.get().pop();
if (this.serverLevelData.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)) {
+ // Purpur start
+ int incrementTicks = isDay() ? this.purpurConfig.daytimeTicks : this.purpurConfig.nighttimeTicks;
+ if (incrementTicks != 12000) {
+ this.preciseTime += 12000 / (double) incrementTicks;
+ this.setDayTime(this.preciseTime);
+ } else
+ // Purpur end
this.setDayTime(this.levelData.getDayTime() + 1L);
}
@@ -881,7 +891,21 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
public void setDayTime(long timeOfDay) {
this.serverLevelData.setDayTime(timeOfDay);
+ // Purpur start
+ this.preciseTime = timeOfDay;
+ this.forceTime = false;
}
+ public void setDayTime(double i) {
+ this.serverLevelData.setDayTime((long) i);
+ this.forceTime = true;
+ // Purpur end
+ }
+
+ // Purpur start
+ public boolean isForceTime() {
+ return this.forceTime;
+ }
+ // Purpur end
public void tickCustomSpawners(boolean spawnMonsters, boolean spawnAnimals) {
Iterator iterator = this.customSpawners.iterator();
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 0716bd2728be4fcaa4f13485591008ce270ecf82..1060208faaa18020c5762a2eb4851f6148b5f215 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -119,6 +119,13 @@ public class PurpurWorldConfig {
raidCooldownSeconds = getInt("gameplay-mechanics.raid-cooldown-seconds", raidCooldownSeconds);
}
+ public int daytimeTicks = 12000;
+ public int nighttimeTicks = 12000;
+ private void daytimeCycleSettings() {
+ daytimeTicks = getInt("gameplay-mechanics.daylight-cycle-ticks.daytime", daytimeTicks);
+ nighttimeTicks = getInt("gameplay-mechanics.daylight-cycle-ticks.nighttime", nighttimeTicks);
+ }
+
public int elytraDamagePerSecond = 1;
public double elytraDamageMultiplyBySpeed = 0;
public int elytraDamagePerFireworkBoost = 0;

View File

@@ -1,62 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Mon, 19 Oct 2020 15:14:01 -0500
Subject: [PATCH] Furnace uses lava from underneath
diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
index 15e0861486a2bda3e2f4049b1b5a299c870acd31..91a158ed90b7ce3eac7277fd962682a0226c08ed 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
@@ -219,6 +219,21 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
}
ItemStack itemstack = (ItemStack) blockEntity.items.get(1);
+ // Purpur start
+ boolean usedLavaFromUnderneath = false;
+ if (world.purpurConfig.furnaceUseLavaFromUnderneath && !blockEntity.isLit() && itemstack.isEmpty() && !blockEntity.items.get(0).isEmpty() && world.getGameTime() % 20 == 0) {
+ BlockPos below = blockEntity.getBlockPos().below();
+ BlockState belowState = world.getBlockStateIfLoaded(below);
+ if (belowState != null && belowState.is(Blocks.LAVA)) {
+ net.minecraft.world.level.material.FluidState fluidState = belowState.getFluidState();
+ if (fluidState != null && fluidState.isSource()) {
+ world.setBlock(below, Blocks.AIR.defaultBlockState(), 3);
+ itemstack = Items.LAVA_BUCKET.getDefaultInstance();
+ usedLavaFromUnderneath = true;
+ }
+ }
+ }
+ // Purpur end
ItemStack itemstack1 = (ItemStack) blockEntity.items.get(0);
boolean flag2 = !itemstack1.isEmpty();
boolean flag3 = !itemstack.isEmpty();
@@ -308,6 +323,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
setChanged(world, pos, state);
}
+ if (usedLavaFromUnderneath) blockEntity.items.set(1, ItemStack.EMPTY); // Purpur
}
private static boolean canBurn(RegistryAccess dynamicRegistryManager, @Nullable RecipeHolder<? extends AbstractCookingRecipe> recipe, SingleRecipeInput input, NonNullList<ItemStack> inventory, int maxCount) {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 1060208faaa18020c5762a2eb4851f6148b5f215..fda9fcf681927334937d25706c9127fbbecd2ed5 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -365,6 +365,17 @@ public class PurpurWorldConfig {
farmlandGetsMoistFromBelow = getBoolean("blocks.farmland.gets-moist-from-below", farmlandGetsMoistFromBelow);
}
+ public boolean furnaceUseLavaFromUnderneath = false;
+ private void furnaceSettings() {
+ if (PurpurConfig.version < 17) {
+ furnaceUseLavaFromUnderneath = getBoolean("blocks.furnace.infinite-fuel", furnaceUseLavaFromUnderneath);
+ boolean oldValue = getBoolean("blocks.furnace.infinite-fuel", furnaceUseLavaFromUnderneath);
+ set("blocks.furnace.infinite-fuel", null);
+ set("blocks.furnace.use-lava-from-underneath", oldValue);
+ }
+ furnaceUseLavaFromUnderneath = getBoolean("blocks.furnace.use-lava-from-underneath", furnaceUseLavaFromUnderneath);
+ }
+
public int lavaInfiniteRequiredSources = 2;
public int lavaSpeedNether = 10;
public int lavaSpeedNotNether = 30;

View File

@@ -1,37 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Wed, 4 Nov 2020 13:12:50 -0600
Subject: [PATCH] Arrows should not reset despawn counter
This prevents keeping arrows alive indefinitely (such as when the block
the arrow is stuck in gets removed, like a piston head going up/down)
diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
index 571f0699772eecbe02d71845da82a142321f2142..b7dccbf33feb978b3937522bb0d62d154699ae9f 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
@@ -371,7 +371,7 @@ public abstract class AbstractArrow extends Projectile {
Vec3 vec3d = this.getDeltaMovement();
this.setDeltaMovement(vec3d.multiply((double) (this.random.nextFloat() * 0.2F), (double) (this.random.nextFloat() * 0.2F), (double) (this.random.nextFloat() * 0.2F)));
- this.life = 0;
+ if (this.level().purpurConfig.arrowMovementResetsDespawnCounter) this.life = 0; // Purpur - do not reset despawn counter
}
public boolean isInGround() {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index fda9fcf681927334937d25706c9127fbbecd2ed5..2e807c72b8469210c4acdc591386368589913e61 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -102,6 +102,11 @@ public class PurpurWorldConfig {
armorstandStepHeight = (float) getDouble("gameplay-mechanics.armorstand.step-height", armorstandStepHeight);
}
+ public boolean arrowMovementResetsDespawnCounter = true;
+ private void arrowSettings() {
+ arrowMovementResetsDespawnCounter = getBoolean("gameplay-mechanics.arrow.movement-resets-despawn-counter", arrowMovementResetsDespawnCounter);
+ }
+
public boolean useBetterMending = false;
public boolean boatEjectPlayersOnLand = false;
public boolean disableDropsOnCrammingDeath = false;

View File

@@ -1,40 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yive <admin@yive.me>
Date: Sat, 14 Nov 2020 08:06:20 -0800
Subject: [PATCH] Ability to re-add farmland mechanics from Alpha
diff --git a/src/main/java/net/minecraft/world/level/block/FarmBlock.java b/src/main/java/net/minecraft/world/level/block/FarmBlock.java
index df89b18f0d5d2dad5745ec65bcd9e4a7bf2f1f2b..e744a117d2f25ad24c87263ba2ab7f760b6e594d 100644
--- a/src/main/java/net/minecraft/world/level/block/FarmBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/FarmBlock.java
@@ -126,6 +126,14 @@ public class FarmBlock extends Block {
return;
}
+ // Purpur start
+ if (world.purpurConfig.farmlandAlpha) {
+ Block block = world.getBlockState(pos.below()).getBlock();
+ if (block instanceof FenceBlock || block instanceof WallBlock) {
+ return;
+ }
+ }
+ // Purpur end
if (!CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.DIRT.defaultBlockState())) {
return;
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 2e807c72b8469210c4acdc591386368589913e61..acc45259de6b0178408146b71ebaf4de9d1891bd 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -366,8 +366,10 @@ public class PurpurWorldConfig {
}
public boolean farmlandGetsMoistFromBelow = false;
+ public boolean farmlandAlpha = false;
private void farmlandSettings() {
farmlandGetsMoistFromBelow = getBoolean("blocks.farmland.gets-moist-from-below", farmlandGetsMoistFromBelow);
+ farmlandAlpha = getBoolean("blocks.farmland.use-alpha-farmland", farmlandAlpha);
}
public boolean furnaceUseLavaFromUnderneath = false;

View File

@@ -1,137 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: montlikadani <montlikada@gmail.com>
Date: Fri, 13 Nov 2020 17:52:40 +0100
Subject: [PATCH] Add adjustable breeding cooldown to config
diff --git a/src/main/java/net/minecraft/world/entity/animal/Animal.java b/src/main/java/net/minecraft/world/entity/animal/Animal.java
index 5677dc97ed83652f261100cf391883cfac7d16fe..4637d062b6a4c4d6de2ef54ec3cfdeb4344ff38e 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Animal.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Animal.java
@@ -157,7 +157,7 @@ public abstract class Animal extends AgeableMob {
if (this.isFood(itemstack)) {
int i = this.getAge();
- if (!this.level().isClientSide && i == 0 && this.canFallInLove()) {
+ if (!this.level().isClientSide && i == 0 && this.canFallInLove() && (this.level().purpurConfig.animalBreedingCooldownSeconds <= 0 || !this.level().hasBreedingCooldown(player.getUUID(), this.getClass()))) { // Purpur
final ItemStack breedCopy = itemstack.copy(); // Paper - Fix EntityBreedEvent copying
this.usePlayerItem(player, hand, itemstack);
this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying
@@ -261,12 +261,20 @@ public abstract class Animal extends AgeableMob {
AgeableMob entityageable = this.getBreedOffspring(world, other);
if (entityageable != null) {
- entityageable.setBaby(true);
- entityageable.moveTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F);
- // CraftBukkit start - call EntityBreedEvent
+ // Purpur start
ServerPlayer breeder = Optional.ofNullable(this.getLoveCause()).or(() -> {
return Optional.ofNullable(other.getLoveCause());
}).orElse(null);
+ if (breeder != null && world.purpurConfig.animalBreedingCooldownSeconds > 0) {
+ if (world.hasBreedingCooldown(breeder.getUUID(), this.getClass())) {
+ return;
+ }
+ world.addBreedingCooldown(breeder.getUUID(), this.getClass());
+ }
+ entityageable.setBaby(true);
+ entityageable.moveTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F);
+ // CraftBukkit start - call EntityBreedEvent
+ // Purpur end
int experience = this.getRandom().nextInt(7) + 1;
EntityBreedEvent entityBreedEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreedEvent(entityageable, this, other, breeder, this.breedItem, experience);
if (entityBreedEvent.isCancelled()) {
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 77093e49fd60993e7cb6bf5712ec53e0fe221776..34e8eb828be517d9ee3973597c74c5cac3d75c99 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -182,6 +182,49 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
public final Map<ServerExplosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
public java.util.ArrayDeque<net.minecraft.world.level.block.RedstoneTorchBlock.Toggle> redstoneUpdateInfos; // Paper - Faster redstone torch rapid clock removal; Move from Map in BlockRedstoneTorch to here
+ // Purpur start
+ private com.google.common.cache.Cache<BreedingCooldownPair, Object> playerBreedingCooldowns;
+
+ private com.google.common.cache.Cache<BreedingCooldownPair, Object> getNewBreedingCooldownCache() {
+ return com.google.common.cache.CacheBuilder.newBuilder().expireAfterWrite(this.purpurConfig.animalBreedingCooldownSeconds, java.util.concurrent.TimeUnit.SECONDS).build();
+ }
+
+ public void resetBreedingCooldowns() {
+ this.playerBreedingCooldowns = this.getNewBreedingCooldownCache();
+ }
+
+ public boolean hasBreedingCooldown(java.util.UUID player, Class<? extends net.minecraft.world.entity.animal.Animal> animalType) { // Purpur
+ return this.playerBreedingCooldowns.getIfPresent(new BreedingCooldownPair(player, animalType)) != null;
+ }
+
+ public void addBreedingCooldown(java.util.UUID player, Class<? extends net.minecraft.world.entity.animal.Animal> animalType) {
+ this.playerBreedingCooldowns.put(new BreedingCooldownPair(player, animalType), new Object());
+ }
+
+ private static final class BreedingCooldownPair {
+ private final java.util.UUID playerUUID;
+ private final Class<? extends net.minecraft.world.entity.animal.Animal> animalType;
+
+ public BreedingCooldownPair(java.util.UUID playerUUID, Class<? extends net.minecraft.world.entity.animal.Animal> animalType) {
+ this.playerUUID = playerUUID;
+ this.animalType = animalType;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ BreedingCooldownPair that = (BreedingCooldownPair) o;
+ return playerUUID.equals(that.playerUUID) && animalType.equals(that.animalType);
+ }
+
+ @Override
+ public int hashCode() {
+ return java.util.Objects.hash(playerUUID, animalType);
+ }
+ }
+ // Purpur end
+
public CraftWorld getWorld() {
return this.world;
}
@@ -844,6 +887,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot
this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config
this.purpurConfig = new org.purpurmc.purpur.PurpurWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName(), env); // Purpur
+ this.playerBreedingCooldowns = this.getNewBreedingCooldownCache(); // Purpur
this.generator = gen;
this.world = new CraftWorld((ServerLevel) this, gen, biomeProvider, env);
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index acc45259de6b0178408146b71ebaf4de9d1891bd..6805a2f2803bb4e859afba5369308dd4d2ac5165 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -114,6 +114,7 @@ public class PurpurWorldConfig {
public double tridentLoyaltyVoidReturnHeight = 0.0D;
public boolean entitiesCanUsePortals = true;
public int raidCooldownSeconds = 0;
+ public int animalBreedingCooldownSeconds = 0;
private void miscGameplayMechanicsSettings() {
useBetterMending = getBoolean("gameplay-mechanics.use-better-mending", useBetterMending);
boatEjectPlayersOnLand = getBoolean("gameplay-mechanics.boat.eject-players-on-land", boatEjectPlayersOnLand);
@@ -122,6 +123,7 @@ public class PurpurWorldConfig {
tridentLoyaltyVoidReturnHeight = getDouble("gameplay-mechanics.trident-loyalty-void-return-height", tridentLoyaltyVoidReturnHeight);
entitiesCanUsePortals = getBoolean("gameplay-mechanics.entities-can-use-portals", entitiesCanUsePortals);
raidCooldownSeconds = getInt("gameplay-mechanics.raid-cooldown-seconds", raidCooldownSeconds);
+ animalBreedingCooldownSeconds = getInt("gameplay-mechanics.animal-breeding-cooldown-seconds", animalBreedingCooldownSeconds);
}
public int daytimeTicks = 12000;
diff --git a/src/main/java/org/purpurmc/purpur/command/PurpurCommand.java b/src/main/java/org/purpurmc/purpur/command/PurpurCommand.java
index afdf04f8b22ad0b7c0b41675e44687b49c2f86d6..2621e54879e9ab0029a875f1d09eee67878b90d5 100644
--- a/src/main/java/org/purpurmc/purpur/command/PurpurCommand.java
+++ b/src/main/java/org/purpurmc/purpur/command/PurpurCommand.java
@@ -49,6 +49,7 @@ public class PurpurCommand extends Command {
PurpurConfig.init((File) console.options.valueOf("purpur-settings"));
for (ServerLevel level : console.getAllLevels()) {
level.purpurConfig.init();
+ level.resetBreedingCooldowns();
}
console.server.reloadCount++;

View File

@@ -1,982 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Sun, 15 Nov 2020 02:18:15 -0800
Subject: [PATCH] Make entity breeding times configurable
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java
index 0a608418f87b71d5d71706712e1f82da0d7e4d34..03e7ca83e4c28dfaa5b52bcb100bd542db105970 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java
@@ -125,8 +125,10 @@ public class VillagerMakeLove extends Behavior<Villager> {
return Optional.empty();
}
// Move age setting down
- parent.setAge(6000);
- partner.setAge(6000);
+ // Purpur start
+ parent.setAge(world.purpurConfig.villagerBreedingTicks);
+ partner.setAge(world.purpurConfig.villagerBreedingTicks);
+ // Purpur end
world.addFreshEntityWithPassengers(entityvillager2, CreatureSpawnEvent.SpawnReason.BREEDING);
// CraftBukkit end
world.broadcastEntityEvent(entityvillager2, (byte) 12);
diff --git a/src/main/java/net/minecraft/world/entity/animal/Animal.java b/src/main/java/net/minecraft/world/entity/animal/Animal.java
index 4637d062b6a4c4d6de2ef54ec3cfdeb4344ff38e..9987d28ea145f6d0126cb4ea22001e0922fb51bd 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Animal.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Animal.java
@@ -49,6 +49,7 @@ public abstract class Animal extends AgeableMob {
@Nullable
public UUID loveCause;
public ItemStack breedItem; // CraftBukkit - Add breedItem variable
+ public abstract int getPurpurBreedTime(); // Purpur
protected Animal(EntityType<? extends Animal> type, Level world) {
super(type, world);
@@ -302,8 +303,10 @@ public abstract class Animal extends AgeableMob {
entityplayer.awardStat(Stats.ANIMALS_BRED);
CriteriaTriggers.BRED_ANIMALS.trigger(entityplayer, this, entityanimal, entityageable);
} // Paper
- this.setAge(6000);
- entityanimal.setAge(6000);
+ // Purpur start
+ this.setAge(this.getPurpurBreedTime());
+ entityanimal.setAge(entityanimal.getPurpurBreedTime());
+ // Purpur end
this.resetLove();
entityanimal.resetLove();
worldserver.broadcastEntityEvent(this, (byte) 18);
diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java
index d000acd339a1967d2c448ed8d66c4f1347f797fd..51b736979e43cd0e60a8ecaf2cf95511b9f4d858 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Bee.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java
@@ -491,6 +491,11 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
this.getAttribute(Attributes.SCALE).setBaseValue(this.level().purpurConfig.beeScale);
}
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.beeBreedingTicks;
+ }
+
@Override
public int getRemainingPersistentAngerTime() {
return (Integer) this.entityData.get(Bee.DATA_REMAINING_ANGER_TIME);
diff --git a/src/main/java/net/minecraft/world/entity/animal/Cat.java b/src/main/java/net/minecraft/world/entity/animal/Cat.java
index 6c773af722ccb9e144d8858a013c120ecbbcfa4c..f79146925e99da08492e7b445006be003a56f340 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Cat.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Cat.java
@@ -129,6 +129,11 @@ public class Cat extends TamableAnimal implements VariantHolder<Holder<CatVarian
this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.catMaxHealth);
this.getAttribute(Attributes.SCALE).setBaseValue(this.level().purpurConfig.catScale);
}
+
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.catBreedingTicks;
+ }
// Purpur end
@Override
diff --git a/src/main/java/net/minecraft/world/entity/animal/Chicken.java b/src/main/java/net/minecraft/world/entity/animal/Chicken.java
index 798a59046c3ac9a3838f7bcaf7bb21e738b76e44..16cc3fdf412bfb46e766b56d25a92bdf93cffeed 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Chicken.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Chicken.java
@@ -79,6 +79,11 @@ public class Chicken extends Animal {
}
// Purpur end
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.chickenBreedingTicks;
+ }
+
@Override
protected void registerGoals() {
this.goalSelector.addGoal(0, new FloatGoal(this));
diff --git a/src/main/java/net/minecraft/world/entity/animal/Cow.java b/src/main/java/net/minecraft/world/entity/animal/Cow.java
index e6fa66a8c88d4f20a7383e8fd5b3df44718478fa..826927ec3d3ace50fb353333a666e35502a96171 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Cow.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Cow.java
@@ -67,6 +67,11 @@ public class Cow extends Animal {
}
// Purpur end
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.cowBreedingTicks;
+ }
+
@Override
protected void registerGoals() {
this.goalSelector.addGoal(0, new FloatGoal(this));
diff --git a/src/main/java/net/minecraft/world/entity/animal/Fox.java b/src/main/java/net/minecraft/world/entity/animal/Fox.java
index 355965d88d5ef008111cc72f39e4f8d35741fdfd..0024345d1906e6fb6bbdb189f6d4dbc631b90f9f 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Fox.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Fox.java
@@ -188,6 +188,11 @@ public class Fox extends Animal implements VariantHolder<Fox.Variant> {
this.getAttribute(Attributes.SCALE).setBaseValue(this.level().purpurConfig.foxScale);
}
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.foxBreedingTicks;
+ }
+
@Override
protected void defineSynchedData(SynchedEntityData.Builder builder) {
super.defineSynchedData(builder);
@@ -976,8 +981,10 @@ public class Fox extends Animal implements VariantHolder<Fox.Variant> {
CriteriaTriggers.BRED_ANIMALS.trigger(entityplayer2, this.animal, this.partner, entityfox);
}
- this.animal.setAge(6000);
- this.partner.setAge(6000);
+ // Purpur start
+ this.animal.setAge(this.animal.getPurpurBreedTime());
+ this.partner.setAge(this.partner.getPurpurBreedTime());
+ // Purpur end
this.animal.resetLove();
this.partner.resetLove();
worldserver.addFreshEntityWithPassengers(entityfox, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - added SpawnReason
diff --git a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java
index c7039d7d5e38392fef8787f6e245a44842e2f2a3..3397fa689c6e36981f3944586c2059c8eb7b1e50 100644
--- a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java
+++ b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java
@@ -87,6 +87,11 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder<Mushroo
this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.mooshroomMaxHealth);
}
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.mooshroomBreedingTicks;
+ }
+
@Override
public float getWalkTargetValue(BlockPos pos, LevelReader world) {
return world.getBlockState(pos.below()).is(Blocks.MYCELIUM) ? 10.0F : world.getPathfindingCostFromLightLevels(pos);
diff --git a/src/main/java/net/minecraft/world/entity/animal/Ocelot.java b/src/main/java/net/minecraft/world/entity/animal/Ocelot.java
index 33384f84cb2b9fe7f702040a1d7669e956bb90f4..b86dfe9a4545189a1ab37fab2f0ed1e63b98a8ca 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Ocelot.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Ocelot.java
@@ -88,6 +88,11 @@ public class Ocelot extends Animal {
this.getAttribute(Attributes.SCALE).setBaseValue(this.level().purpurConfig.ocelotScale);
}
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.ocelotBreedingTicks;
+ }
+
public boolean isTrusting() {
return (Boolean) this.entityData.get(Ocelot.DATA_TRUSTING);
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/Panda.java b/src/main/java/net/minecraft/world/entity/animal/Panda.java
index cf62e808687b81985073baa1be5773a2fe1cca69..3da181a7baa04e7852f7cdf7f12728ec448d707b 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Panda.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Panda.java
@@ -145,6 +145,11 @@ public class Panda extends Animal {
setAttributes();
}
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.pandaBreedingTicks;
+ }
+
@Override
protected boolean canDispenserEquipIntoSlot(EquipmentSlot slot) {
return slot == EquipmentSlot.MAINHAND && this.canPickUpLoot();
diff --git a/src/main/java/net/minecraft/world/entity/animal/Parrot.java b/src/main/java/net/minecraft/world/entity/animal/Parrot.java
index 47249c0f73c79b82be302d318eca10a92c8bceb8..e99e33fecba3d6506d704a0a27c578f1efeaf77b 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Parrot.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Parrot.java
@@ -194,6 +194,11 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder<Parrot
this.getAttribute(Attributes.SCALE).setBaseValue(this.level().purpurConfig.parrotScale);
}
+ @Override
+ public int getPurpurBreedTime() {
+ return 6000;
+ }
+
@Nullable
@Override
public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, EntitySpawnReason spawnReason, @Nullable SpawnGroupData entityData) {
diff --git a/src/main/java/net/minecraft/world/entity/animal/Pig.java b/src/main/java/net/minecraft/world/entity/animal/Pig.java
index 294545914dec0a06eadb6c2f139222b3f1a6f64c..73e288133ee12561053f9225121e55955a963127 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Pig.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Pig.java
@@ -88,6 +88,11 @@ public class Pig extends Animal implements ItemSteerable, Saddleable {
this.getAttribute(Attributes.SCALE).setBaseValue(this.level().purpurConfig.pigScale);
}
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.pigBreedingTicks;
+ }
+
@Override
protected void registerGoals() {
this.goalSelector.addGoal(0, new FloatGoal(this));
diff --git a/src/main/java/net/minecraft/world/entity/animal/PolarBear.java b/src/main/java/net/minecraft/world/entity/animal/PolarBear.java
index 511d0559743655ed7b43a948fccc2621c906be02..472487c3cb8bdfb28625ffdf25f14d990737f8e4 100644
--- a/src/main/java/net/minecraft/world/entity/animal/PolarBear.java
+++ b/src/main/java/net/minecraft/world/entity/animal/PolarBear.java
@@ -120,6 +120,11 @@ public class PolarBear extends Animal implements NeutralMob {
}
}
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.polarBearBreedingTicks;
+ }
+
@Nullable
@Override
public AgeableMob getBreedOffspring(ServerLevel world, AgeableMob entity) {
diff --git a/src/main/java/net/minecraft/world/entity/animal/Rabbit.java b/src/main/java/net/minecraft/world/entity/animal/Rabbit.java
index b0cdc25f6592d44a3ad3fdf4d461e95887105257..629a0729cae629dea89fdf491afa9eed96e7a38a 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Rabbit.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Rabbit.java
@@ -145,6 +145,11 @@ public class Rabbit extends Animal implements VariantHolder<Rabbit.Variant> {
this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.rabbitMaxHealth);
this.getAttribute(Attributes.SCALE).setBaseValue(this.level().purpurConfig.rabbitScale);
}
+
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.rabbitBreedingTicks;
+ }
// Purpur end
@Override
diff --git a/src/main/java/net/minecraft/world/entity/animal/Sheep.java b/src/main/java/net/minecraft/world/entity/animal/Sheep.java
index 38799a817742b1bbaf921f1e24cf2fc44ab52050..8d94e1a33ac7748ded0f75212738ba13bd18d492 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Sheep.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Sheep.java
@@ -114,6 +114,11 @@ public class Sheep extends Animal implements Shearable {
this.getAttribute(Attributes.SCALE).setBaseValue(this.level().purpurConfig.sheepScale);
}
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.sheepBreedingTicks;
+ }
+
@Override
protected void registerGoals() {
this.eatBlockGoal = new EatBlockGoal(this);
diff --git a/src/main/java/net/minecraft/world/entity/animal/Turtle.java b/src/main/java/net/minecraft/world/entity/animal/Turtle.java
index 500676a78aedc525aca989ccd0380cd2cc1a711b..6b2e27e2f8aeccfc4d84c73be0fa5a04f5a962e2 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java
@@ -109,6 +109,11 @@ public class Turtle extends Animal {
this.getAttribute(Attributes.SCALE).setBaseValue(this.level().purpurConfig.turtleScale);
}
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.turtleBreedingTicks;
+ }
+
public void setHomePos(BlockPos pos) {
this.entityData.set(Turtle.HOME_POS, pos);
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/Wolf.java b/src/main/java/net/minecraft/world/entity/animal/Wolf.java
index 40a766e20d1a2111d561cc05aa49e2ac50187d19..bb2e5e97d33ffaf95a6c88b3c077de1a89a60c6e 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Wolf.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Wolf.java
@@ -152,6 +152,11 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder<Hol
this.getAttribute(Attributes.SCALE).setBaseValue(this.level().purpurConfig.wolfScale);
}
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.wolfBreedingTicks;
+ }
+
@Override
protected void registerGoals() {
this.goalSelector.addGoal(1, new FloatGoal(this));
diff --git a/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java b/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java
index a7fdb54b1bda83e7a365447f2cb5701238ba6847..9ef53608f1608e88de7a7b3e96b43d8d2b4230ae 100644
--- a/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java
+++ b/src/main/java/net/minecraft/world/entity/animal/armadillo/Armadillo.java
@@ -103,6 +103,11 @@ public class Armadillo extends Animal {
this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.armadilloMaxHealth);
this.getAttribute(Attributes.SCALE).setBaseValue(this.level().purpurConfig.armadilloScale);
}
+
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.armadilloBreedingTicks;
+ }
// Purpur end
@Override
diff --git a/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java b/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java
index 79102c8819ce3d49538306db3ce4a723ea5d765d..f6b3bb53a0f6ad596322d6270bf27c5749d13c7b 100644
--- a/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java
+++ b/src/main/java/net/minecraft/world/entity/animal/axolotl/Axolotl.java
@@ -121,6 +121,11 @@ public class Axolotl extends Animal implements VariantHolder<Axolotl.Variant>, B
this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.axolotlMaxHealth);
this.getAttribute(Attributes.SCALE).setBaseValue(this.level().purpurConfig.axolotlScale);
}
+
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.axolotlBreedingTicks;
+ }
// Purpur end
@Override
diff --git a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java
index 9b9e7c9048f453d01ccf13ffdc7ee0f2151155a9..dbce71f45c008da883b6d244a06343d83ae25e7e 100644
--- a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java
+++ b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java
@@ -92,6 +92,10 @@ public class Camel extends AbstractHorse {
public boolean dismountsUnderwater() {
return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.camelRidableInWater;
}
+
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.camelBreedingTicks;
+ }
// Purpur end
@Override
diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java
index 066006dc4fcdd03113242f3fa4bc8dc7b4add81a..02581f47d1ca58c2b8abffc478adf48343585c8b 100644
--- a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java
+++ b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java
@@ -165,6 +165,10 @@ public class Frog extends Animal implements VariantHolder<Holder<FrogVariant>> {
}
// Purpur end
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.frogBreedingTicks;
+ }
+
@Override
protected Brain.Provider<Frog> brainProvider() {
return Brain.provider(MEMORY_TYPES, SENSOR_TYPES);
diff --git a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
index 2e9fb07b2974209cce5bd31aca095def474c51c2..3d862b7a0acc75b4f5ac502e5ef756fde8fe183e 100644
--- a/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
+++ b/src/main/java/net/minecraft/world/entity/animal/goat/Goat.java
@@ -110,6 +110,11 @@ public class Goat extends Animal {
}
// Purpur end
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.goatBreedingTicks;
+ }
+
@Override
protected Brain.Provider<Goat> brainProvider() {
return Brain.provider(Goat.MEMORY_TYPES, Goat.SENSOR_TYPES);
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/Donkey.java b/src/main/java/net/minecraft/world/entity/animal/horse/Donkey.java
index 7362597d2ca9ea5375118d280e17b6c2719352a7..ba0b6c0154d72dd13acf9e1c0966e394d59943c7 100644
--- a/src/main/java/net/minecraft/world/entity/animal/horse/Donkey.java
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/Donkey.java
@@ -38,6 +38,11 @@ public class Donkey extends AbstractChestedHorse {
return generateSpeed(this.level().purpurConfig.donkeyMovementSpeedMin, this.level().purpurConfig.donkeyMovementSpeedMax);
}
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.donkeyBreedingTicks;
+ }
+
@Override
protected SoundEvent getAmbientSound() {
return SoundEvents.DONKEY_AMBIENT;
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/Horse.java b/src/main/java/net/minecraft/world/entity/animal/horse/Horse.java
index b0392780b35866bf1903f49cb16c4ab79335882d..b9a406cd4e317c663a12d897b8cf1f4f6eeca662 100644
--- a/src/main/java/net/minecraft/world/entity/animal/horse/Horse.java
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/Horse.java
@@ -65,6 +65,11 @@ public class Horse extends AbstractHorse implements VariantHolder<Variant> {
return generateSpeed(this.level().purpurConfig.horseMovementSpeedMin, this.level().purpurConfig.horseMovementSpeedMax);
}
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.horseBreedingTicks;
+ }
+
@Override
protected void randomizeAttributes(RandomSource random) {
this.getAttribute(Attributes.MAX_HEALTH).setBaseValue((double)generateMaxHealth(random::nextInt));
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java
index 4a412a8a582e092a920029791a48c085527cbbd0..7ad4285f820360cf5ccff1ea564afac81eb24e35 100644
--- a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java
@@ -139,6 +139,11 @@ public class Llama extends AbstractChestedHorse implements VariantHolder<Llama.V
return generateSpeed(this.level().purpurConfig.llamaMovementSpeedMin, this.level().purpurConfig.llamaMovementSpeedMax);
}
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.llamaBreedingTicks;
+ }
+
public boolean isTraderLlama() {
return false;
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/Mule.java b/src/main/java/net/minecraft/world/entity/animal/horse/Mule.java
index 7ec14013c9200f0fe4a565b2c923f92712aabc3c..9fbcc46ef7bc02ce5b265704545870d245e9b1f2 100644
--- a/src/main/java/net/minecraft/world/entity/animal/horse/Mule.java
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/Mule.java
@@ -37,6 +37,11 @@ public class Mule extends AbstractChestedHorse {
return generateSpeed(this.level().purpurConfig.muleMovementSpeedMin, this.level().purpurConfig.muleMovementSpeedMax);
}
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.muleBreedingTicks;
+ }
+
@Override
protected SoundEvent getAmbientSound() {
return SoundEvents.MULE_AMBIENT;
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonHorse.java
index d3b9763aa745154fd796f725c2d5babfaaf22050..069783ed1bb4bbb7dece4b7883fe4d306a1b92bd 100644
--- a/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonHorse.java
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonHorse.java
@@ -64,6 +64,11 @@ public class SkeletonHorse extends AbstractHorse {
return generateSpeed(this.level().purpurConfig.skeletonHorseMovementSpeedMin, this.level().purpurConfig.skeletonHorseMovementSpeedMax);
}
+ @Override
+ public int getPurpurBreedTime() {
+ return 6000;
+ }
+
public static AttributeSupplier.Builder createAttributes() {
return createBaseHorseAttributes().add(Attributes.MAX_HEALTH, 15.0D).add(Attributes.MOVEMENT_SPEED, 0.20000000298023224D);
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/TraderLlama.java b/src/main/java/net/minecraft/world/entity/animal/horse/TraderLlama.java
index 10074787bbb3935685b9bd78c018309b2e468d87..845f75a48f07e7f25e71ed7b04a2f6b1dc87cbb8 100644
--- a/src/main/java/net/minecraft/world/entity/animal/horse/TraderLlama.java
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/TraderLlama.java
@@ -70,6 +70,11 @@ public class TraderLlama extends Llama {
return generateSpeed(this.level().purpurConfig.traderLlamaMovementSpeedMin, this.level().purpurConfig.traderLlamaMovementSpeedMax);
}
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.traderLlamaBreedingTicks;
+ }
+
@Override
public boolean isTraderLlama() {
return true;
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/ZombieHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/ZombieHorse.java
index f2cb87234d8e60b9737c6dfbe3297857a9efc3a1..b7eda8855bc7162566975849f9bae7f182ad801c 100644
--- a/src/main/java/net/minecraft/world/entity/animal/horse/ZombieHorse.java
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/ZombieHorse.java
@@ -60,6 +60,11 @@ public class ZombieHorse extends AbstractHorse {
return generateSpeed(this.level().purpurConfig.zombieHorseMovementSpeedMin, this.level().purpurConfig.zombieHorseMovementSpeedMax);
}
+ @Override
+ public int getPurpurBreedTime() {
+ return 6000;
+ }
+
public static AttributeSupplier.Builder createAttributes() {
return createBaseHorseAttributes().add(Attributes.MAX_HEALTH, 15.0).add(Attributes.MOVEMENT_SPEED, 0.2F);
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java
index d08ff3f70ed3024dba7cf4405ba08d547ed5bf2d..464a16df15d8759d66f94ad080d1ea28b3f6474c 100644
--- a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java
+++ b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java
@@ -111,6 +111,11 @@ public class Sniffer extends Animal {
this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.snifferMaxHealth);
this.getAttribute(Attributes.SCALE).setBaseValue(this.level().purpurConfig.snifferScale);
}
+
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.snifferBreedingTicks;
+ }
// Purpur end
@Override
diff --git a/src/main/java/net/minecraft/world/entity/monster/Strider.java b/src/main/java/net/minecraft/world/entity/monster/Strider.java
index 6a45a62c578f033558c26935681f7de74dd98bac..0cc49b0a600a5e6fb4fc21e698e3a5fef5996df1 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Strider.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Strider.java
@@ -120,6 +120,11 @@ public class Strider extends Animal implements ItemSteerable, Saddleable {
this.getAttribute(Attributes.SCALE).setBaseValue(this.level().purpurConfig.striderScale);
}
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.striderBreedingTicks;
+ }
+
public static boolean checkStriderSpawnRules(EntityType<Strider> type, LevelAccessor world, EntitySpawnReason spawnReason, BlockPos pos, RandomSource random) {
BlockPos.MutableBlockPos blockposition_mutableblockposition = pos.mutable();
diff --git a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java
index fc78df484bf747d4a00acd85a3f9f3775dcdd8b1..0ee5bdae0d8e42b3d6475bfe49bfa41ee3192769 100644
--- a/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java
+++ b/src/main/java/net/minecraft/world/entity/monster/hoglin/Hoglin.java
@@ -99,6 +99,11 @@ public class Hoglin extends Animal implements Enemy, HoglinBase {
this.timeInOverworld = timeInOverworld;
}
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.hoglinBreedingTicks;
+ }
+
@Override
public boolean canBeLeashed() {
return true;
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 6805a2f2803bb4e859afba5369308dd4d2ac5165..e363a93bdfcef7408ecdd5618b63c345ab9525b4 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -463,23 +463,27 @@ public class PurpurWorldConfig {
public boolean armadilloControllable = true;
public double armadilloMaxHealth = 12.0D;
public double armadilloScale = 1.0D;
+ public int armadilloBreedingTicks = 6000;
private void armadilloSettings() {
armadilloRidable = getBoolean("mobs.armadillo.ridable", armadilloRidable);
armadilloRidableInWater = getBoolean("mobs.armadillo.ridable-in-water", armadilloRidableInWater);
armadilloControllable = getBoolean("mobs.armadillo.controllable", armadilloControllable);
armadilloMaxHealth = getDouble("mobs.armadillo.attributes.max_health", armadilloMaxHealth);
armadilloScale = Mth.clamp(getDouble("mobs.armadillo.attributes.scale", armadilloScale), 0.0625D, 16.0D);
+ armadilloBreedingTicks = getInt("mobs.armadillo.breeding-delay-ticks", armadilloBreedingTicks);
}
public boolean axolotlRidable = false;
public boolean axolotlControllable = true;
public double axolotlMaxHealth = 14.0D;
public double axolotlScale = 1.0D;
+ public int axolotlBreedingTicks = 6000;
private void axolotlSettings() {
axolotlRidable = getBoolean("mobs.axolotl.ridable", axolotlRidable);
axolotlControllable = getBoolean("mobs.axolotl.controllable", axolotlControllable);
axolotlMaxHealth = getDouble("mobs.axolotl.attributes.max_health", axolotlMaxHealth);
axolotlScale = Mth.clamp(getDouble("mobs.axolotl.attributes.scale", axolotlScale), 0.0625D, 16.0D);
+ axolotlBreedingTicks = getInt("mobs.axolotl.breeding-delay-ticks", axolotlBreedingTicks);
}
public boolean batRidable = false;
@@ -522,6 +526,7 @@ public class PurpurWorldConfig {
public double beeMaxY = 320D;
public double beeMaxHealth = 10.0D;
public double beeScale = 1.0D;
+ public int beeBreedingTicks = 6000;
private void beeSettings() {
beeRidable = getBoolean("mobs.bee.ridable", beeRidable);
beeRidableInWater = getBoolean("mobs.bee.ridable-in-water", beeRidableInWater);
@@ -534,6 +539,7 @@ public class PurpurWorldConfig {
}
beeMaxHealth = getDouble("mobs.bee.attributes.max_health", beeMaxHealth);
beeScale = Mth.clamp(getDouble("mobs.bee.attributes.scale", beeScale), 0.0625D, 16.0D);
+ beeBreedingTicks = getInt("mobs.bee.breeding-delay-ticks", beeBreedingTicks);
}
public boolean blazeRidable = false;
@@ -576,6 +582,7 @@ public class PurpurWorldConfig {
public double camelJumpStrengthMax = 0.42D;
public double camelMovementSpeedMin = 0.09D;
public double camelMovementSpeedMax = 0.09D;
+ public int camelBreedingTicks = 6000;
private void camelSettings() {
camelRidableInWater = getBoolean("mobs.camel.ridable-in-water", camelRidableInWater);
camelMaxHealthMin = getDouble("mobs.camel.attributes.max_health.min", camelMaxHealthMin);
@@ -584,6 +591,7 @@ public class PurpurWorldConfig {
camelJumpStrengthMax = getDouble("mobs.camel.attributes.jump_strength.max", camelJumpStrengthMax);
camelMovementSpeedMin = getDouble("mobs.camel.attributes.movement_speed.min", camelMovementSpeedMin);
camelMovementSpeedMax = getDouble("mobs.camel.attributes.movement_speed.max", camelMovementSpeedMax);
+ camelBreedingTicks = getInt("mobs.camel.breeding-delay-ticks", camelBreedingTicks);
}
public boolean catRidable = false;
@@ -594,6 +602,7 @@ public class PurpurWorldConfig {
public int catSpawnDelay = 1200;
public int catSpawnSwampHutScanRange = 16;
public int catSpawnVillageScanRange = 48;
+ public int catBreedingTicks = 6000;
private void catSettings() {
catRidable = getBoolean("mobs.cat.ridable", catRidable);
catRidableInWater = getBoolean("mobs.cat.ridable-in-water", catRidableInWater);
@@ -608,6 +617,7 @@ public class PurpurWorldConfig {
catSpawnDelay = getInt("mobs.cat.spawn-delay", catSpawnDelay);
catSpawnSwampHutScanRange = getInt("mobs.cat.scan-range-for-other-cats.swamp-hut", catSpawnSwampHutScanRange);
catSpawnVillageScanRange = getInt("mobs.cat.scan-range-for-other-cats.village", catSpawnVillageScanRange);
+ catBreedingTicks = getInt("mobs.cat.breeding-delay-ticks", catBreedingTicks);
}
public boolean caveSpiderRidable = false;
@@ -634,6 +644,7 @@ public class PurpurWorldConfig {
public double chickenMaxHealth = 4.0D;
public double chickenScale = 1.0D;
public boolean chickenRetaliate = false;
+ public int chickenBreedingTicks = 6000;
private void chickenSettings() {
chickenRidable = getBoolean("mobs.chicken.ridable", chickenRidable);
chickenRidableInWater = getBoolean("mobs.chicken.ridable-in-water", chickenRidableInWater);
@@ -646,6 +657,7 @@ public class PurpurWorldConfig {
chickenMaxHealth = getDouble("mobs.chicken.attributes.max_health", chickenMaxHealth);
chickenScale = Mth.clamp(getDouble("mobs.chicken.attributes.scale", chickenScale), 0.0625D, 16.0D);
chickenRetaliate = getBoolean("mobs.chicken.retaliate", chickenRetaliate);
+ chickenBreedingTicks = getInt("mobs.chicken.breeding-delay-ticks", chickenBreedingTicks);
}
public boolean codRidable = false;
@@ -670,6 +682,7 @@ public class PurpurWorldConfig {
public double cowMaxHealth = 10.0D;
public double cowScale = 1.0D;
public int cowFeedMushrooms = 0;
+ public int cowBreedingTicks = 6000;
private void cowSettings() {
cowRidable = getBoolean("mobs.cow.ridable", cowRidable);
cowRidableInWater = getBoolean("mobs.cow.ridable-in-water", cowRidableInWater);
@@ -682,6 +695,7 @@ public class PurpurWorldConfig {
cowMaxHealth = getDouble("mobs.cow.attributes.max_health", cowMaxHealth);
cowScale = Mth.clamp(getDouble("mobs.cow.attributes.scale", cowScale), 0.0625D, 16.0D);
cowFeedMushrooms = getInt("mobs.cow.feed-mushrooms-for-mooshroom", cowFeedMushrooms);
+ cowBreedingTicks = getInt("mobs.cow.breeding-delay-ticks", cowBreedingTicks);
}
public boolean creakingRidable = false;
@@ -750,6 +764,7 @@ public class PurpurWorldConfig {
public double donkeyJumpStrengthMax = 0.5D;
public double donkeyMovementSpeedMin = 0.175D;
public double donkeyMovementSpeedMax = 0.175D;
+ public int donkeyBreedingTicks = 6000;
private void donkeySettings() {
donkeyRidableInWater = getBoolean("mobs.donkey.ridable-in-water", donkeyRidableInWater);
if (PurpurConfig.version < 10) {
@@ -765,6 +780,7 @@ public class PurpurWorldConfig {
donkeyJumpStrengthMax = getDouble("mobs.donkey.attributes.jump_strength.max", donkeyJumpStrengthMax);
donkeyMovementSpeedMin = getDouble("mobs.donkey.attributes.movement_speed.min", donkeyMovementSpeedMin);
donkeyMovementSpeedMax = getDouble("mobs.donkey.attributes.movement_speed.max", donkeyMovementSpeedMax);
+ donkeyBreedingTicks = getInt("mobs.donkey.breeding-delay-ticks", donkeyBreedingTicks);
}
public boolean drownedRidable = false;
@@ -895,6 +911,7 @@ public class PurpurWorldConfig {
public double foxMaxHealth = 10.0D;
public double foxScale = 1.0D;
public boolean foxTypeChangesWithTulips = false;
+ public int foxBreedingTicks = 6000;
private void foxSettings() {
foxRidable = getBoolean("mobs.fox.ridable", foxRidable);
foxRidableInWater = getBoolean("mobs.fox.ridable-in-water", foxRidableInWater);
@@ -907,17 +924,20 @@ public class PurpurWorldConfig {
foxMaxHealth = getDouble("mobs.fox.attributes.max_health", foxMaxHealth);
foxScale = Mth.clamp(getDouble("mobs.fox.attributes.scale", foxScale), 0.0625D, 16.0D);
foxTypeChangesWithTulips = getBoolean("mobs.fox.tulips-change-type", foxTypeChangesWithTulips);
+ foxBreedingTicks = getInt("mobs.fox.breeding-delay-ticks", foxBreedingTicks);
}
public boolean frogRidable = false;
public boolean frogRidableInWater = true;
public boolean frogControllable = true;
public float frogRidableJumpHeight = 0.65F;
+ public int frogBreedingTicks = 6000;
private void frogSettings() {
frogRidable = getBoolean("mobs.frog.ridable", frogRidable);
frogRidableInWater = getBoolean("mobs.frog.ridable-in-water", frogRidableInWater);
frogControllable = getBoolean("mobs.frog.controllable", frogControllable);
frogRidableJumpHeight = (float) getDouble("mobs.frog.ridable-jump-height", frogRidableJumpHeight);
+ frogBreedingTicks = getInt("mobs.frog.breeding-delay-ticks", frogBreedingTicks);
}
public boolean ghastRidable = false;
@@ -992,12 +1012,14 @@ public class PurpurWorldConfig {
public boolean goatControllable = true;
public double goatMaxHealth = 10.0D;
public double goatScale = 1.0D;
+ public int goatBreedingTicks = 6000;
private void goatSettings() {
goatRidable = getBoolean("mobs.goat.ridable", goatRidable);
goatRidableInWater = getBoolean("mobs.goat.ridable-in-water", goatRidableInWater);
goatControllable = getBoolean("mobs.goat.controllable", goatControllable);
goatMaxHealth = getDouble("mobs.goat.attributes.max_health", goatMaxHealth);
goatScale = Mth.clamp(getDouble("mobs.goat.attributes.scale", goatScale), 0.0625D, 16.0D);
+ goatBreedingTicks = getInt("mobs.goat.breeding-delay-ticks", goatBreedingTicks);
}
public boolean guardianRidable = false;
@@ -1021,6 +1043,7 @@ public class PurpurWorldConfig {
public boolean hoglinControllable = true;
public double hoglinMaxHealth = 40.0D;
public double hoglinScale = 1.0D;
+ public int hoglinBreedingTicks = 6000;
private void hoglinSettings() {
hoglinRidable = getBoolean("mobs.hoglin.ridable", hoglinRidable);
hoglinRidableInWater = getBoolean("mobs.hoglin.ridable-in-water", hoglinRidableInWater);
@@ -1032,6 +1055,7 @@ public class PurpurWorldConfig {
}
hoglinMaxHealth = getDouble("mobs.hoglin.attributes.max_health", hoglinMaxHealth);
hoglinScale = Mth.clamp(getDouble("mobs.hoglin.attributes.scale", hoglinScale), 0.0625D, 16.0D);
+ hoglinBreedingTicks = getInt("mobs.hoglin.breeding-delay-ticks", hoglinBreedingTicks);
}
public boolean horseRidableInWater = false;
@@ -1041,6 +1065,7 @@ public class PurpurWorldConfig {
public double horseJumpStrengthMax = 1.0D;
public double horseMovementSpeedMin = 0.1125D;
public double horseMovementSpeedMax = 0.3375D;
+ public int horseBreedingTicks = 6000;
private void horseSettings() {
horseRidableInWater = getBoolean("mobs.horse.ridable-in-water", horseRidableInWater);
if (PurpurConfig.version < 10) {
@@ -1056,6 +1081,7 @@ public class PurpurWorldConfig {
horseJumpStrengthMax = getDouble("mobs.horse.attributes.jump_strength.max", horseJumpStrengthMax);
horseMovementSpeedMin = getDouble("mobs.horse.attributes.movement_speed.min", horseMovementSpeedMin);
horseMovementSpeedMax = getDouble("mobs.horse.attributes.movement_speed.max", horseMovementSpeedMax);
+ horseBreedingTicks = getInt("mobs.horse.breeding-delay-ticks", horseBreedingTicks);
}
public boolean huskRidable = false;
@@ -1139,6 +1165,7 @@ public class PurpurWorldConfig {
public double llamaJumpStrengthMax = 0.5D;
public double llamaMovementSpeedMin = 0.175D;
public double llamaMovementSpeedMax = 0.175D;
+ public int llamaBreedingTicks = 6000;
private void llamaSettings() {
llamaRidable = getBoolean("mobs.llama.ridable", llamaRidable);
llamaRidableInWater = getBoolean("mobs.llama.ridable-in-water", llamaRidableInWater);
@@ -1156,6 +1183,7 @@ public class PurpurWorldConfig {
llamaJumpStrengthMax = getDouble("mobs.llama.attributes.jump_strength.max", llamaJumpStrengthMax);
llamaMovementSpeedMin = getDouble("mobs.llama.attributes.movement_speed.min", llamaMovementSpeedMin);
llamaMovementSpeedMax = getDouble("mobs.llama.attributes.movement_speed.max", llamaMovementSpeedMax);
+ llamaBreedingTicks = getInt("mobs.llama.breeding-delay-ticks", llamaBreedingTicks);
}
public boolean magmaCubeRidable = false;
@@ -1185,6 +1213,7 @@ public class PurpurWorldConfig {
public boolean mooshroomControllable = true;
public double mooshroomMaxHealth = 10.0D;
public double mooshroomScale = 1.0D;
+ public int mooshroomBreedingTicks = 6000;
private void mooshroomSettings() {
mooshroomRidable = getBoolean("mobs.mooshroom.ridable", mooshroomRidable);
mooshroomRidableInWater = getBoolean("mobs.mooshroom.ridable-in-water", mooshroomRidableInWater);
@@ -1196,6 +1225,7 @@ public class PurpurWorldConfig {
}
mooshroomMaxHealth = getDouble("mobs.mooshroom.attributes.max_health", mooshroomMaxHealth);
mooshroomScale = Mth.clamp(getDouble("mobs.mooshroom.attributes.scale", mooshroomScale), 0.0625D, 16.0D);
+ mooshroomBreedingTicks = getInt("mobs.mooshroom.breeding-delay-ticks", mooshroomBreedingTicks);
}
public boolean muleRidableInWater = false;
@@ -1205,6 +1235,7 @@ public class PurpurWorldConfig {
public double muleJumpStrengthMax = 0.5D;
public double muleMovementSpeedMin = 0.175D;
public double muleMovementSpeedMax = 0.175D;
+ public int muleBreedingTicks = 6000;
private void muleSettings() {
muleRidableInWater = getBoolean("mobs.mule.ridable-in-water", muleRidableInWater);
if (PurpurConfig.version < 10) {
@@ -1220,6 +1251,7 @@ public class PurpurWorldConfig {
muleJumpStrengthMax = getDouble("mobs.mule.attributes.jump_strength.max", muleJumpStrengthMax);
muleMovementSpeedMin = getDouble("mobs.mule.attributes.movement_speed.min", muleMovementSpeedMin);
muleMovementSpeedMax = getDouble("mobs.mule.attributes.movement_speed.max", muleMovementSpeedMax);
+ muleBreedingTicks = getInt("mobs.mule.breeding-delay-ticks", muleBreedingTicks);
}
public boolean ocelotRidable = false;
@@ -1227,6 +1259,7 @@ public class PurpurWorldConfig {
public boolean ocelotControllable = true;
public double ocelotMaxHealth = 10.0D;
public double ocelotScale = 1.0D;
+ public int ocelotBreedingTicks = 6000;
private void ocelotSettings() {
ocelotRidable = getBoolean("mobs.ocelot.ridable", ocelotRidable);
ocelotRidableInWater = getBoolean("mobs.ocelot.ridable-in-water", ocelotRidableInWater);
@@ -1238,6 +1271,7 @@ public class PurpurWorldConfig {
}
ocelotMaxHealth = getDouble("mobs.ocelot.attributes.max_health", ocelotMaxHealth);
ocelotScale = Mth.clamp(getDouble("mobs.ocelot.attributes.scale", ocelotScale), 0.0625D, 16.0D);
+ ocelotBreedingTicks = getInt("mobs.ocelot.breeding-delay-ticks", ocelotBreedingTicks);
}
public boolean pandaRidable = false;
@@ -1245,6 +1279,7 @@ public class PurpurWorldConfig {
public boolean pandaControllable = true;
public double pandaMaxHealth = 20.0D;
public double pandaScale = 1.0D;
+ public int pandaBreedingTicks = 6000;
private void pandaSettings() {
pandaRidable = getBoolean("mobs.panda.ridable", pandaRidable);
pandaRidableInWater = getBoolean("mobs.panda.ridable-in-water", pandaRidableInWater);
@@ -1256,6 +1291,7 @@ public class PurpurWorldConfig {
}
pandaMaxHealth = getDouble("mobs.panda.attributes.max_health", pandaMaxHealth);
pandaScale = Mth.clamp(getDouble("mobs.panda.attributes.scale", pandaScale), 0.0625D, 16.0D);
+ pandaBreedingTicks = getInt("mobs.panda.breeding-delay-ticks", pandaBreedingTicks);
}
public boolean parrotRidable = false;
@@ -1342,6 +1378,7 @@ public class PurpurWorldConfig {
public double pigMaxHealth = 10.0D;
public double pigScale = 1.0D;
public boolean pigGiveSaddleBack = false;
+ public int pigBreedingTicks = 6000;
private void pigSettings() {
pigRidable = getBoolean("mobs.pig.ridable", pigRidable);
pigRidableInWater = getBoolean("mobs.pig.ridable-in-water", pigRidableInWater);
@@ -1354,6 +1391,7 @@ public class PurpurWorldConfig {
pigMaxHealth = getDouble("mobs.pig.attributes.max_health", pigMaxHealth);
pigScale = Mth.clamp(getDouble("mobs.pig.attributes.scale", pigScale), 0.0625D, 16.0D);
pigGiveSaddleBack = getBoolean("mobs.pig.give-saddle-back", pigGiveSaddleBack);
+ pigBreedingTicks = getInt("mobs.pig.breeding-delay-ticks", pigBreedingTicks);
}
public boolean piglinRidable = false;
@@ -1417,6 +1455,7 @@ public class PurpurWorldConfig {
public double polarBearScale = 1.0D;
public String polarBearBreedableItemString = "";
public Item polarBearBreedableItem = null;
+ public int polarBearBreedingTicks = 6000;
private void polarBearSettings() {
polarBearRidable = getBoolean("mobs.polar_bear.ridable", polarBearRidable);
polarBearRidableInWater = getBoolean("mobs.polar_bear.ridable-in-water", polarBearRidableInWater);
@@ -1431,6 +1470,7 @@ public class PurpurWorldConfig {
polarBearBreedableItemString = getString("mobs.polar_bear.breedable-item", polarBearBreedableItemString);
Item item = BuiltInRegistries.ITEM.getValue(ResourceLocation.parse(polarBearBreedableItemString));
if (item != Items.AIR) polarBearBreedableItem = item;
+ polarBearBreedingTicks = getInt("mobs.polar_bear.breeding-delay-ticks", polarBearBreedingTicks);
}
public boolean pufferfishRidable = false;
@@ -1456,6 +1496,7 @@ public class PurpurWorldConfig {
public double rabbitScale = 1.0D;
public double rabbitNaturalToast = 0.0D;
public double rabbitNaturalKiller = 0.0D;
+ public int rabbitBreedingTicks = 6000;
private void rabbitSettings() {
rabbitRidable = getBoolean("mobs.rabbit.ridable", rabbitRidable);
rabbitRidableInWater = getBoolean("mobs.rabbit.ridable-in-water", rabbitRidableInWater);
@@ -1469,6 +1510,7 @@ public class PurpurWorldConfig {
rabbitScale = Mth.clamp(getDouble("mobs.rabbit.attributes.scale", rabbitScale), 0.0625D, 16.0D);
rabbitNaturalToast = getDouble("mobs.rabbit.spawn-toast-chance", rabbitNaturalToast);
rabbitNaturalKiller = getDouble("mobs.rabbit.spawn-killer-rabbit-chance", rabbitNaturalKiller);
+ rabbitBreedingTicks = getInt("mobs.rabbit.breeding-delay-ticks", rabbitBreedingTicks);
}
public boolean ravagerRidable = false;
@@ -1510,6 +1552,7 @@ public class PurpurWorldConfig {
public boolean sheepControllable = true;
public double sheepMaxHealth = 8.0D;
public double sheepScale = 1.0D;
+ public int sheepBreedingTicks = 6000;
private void sheepSettings() {
sheepRidable = getBoolean("mobs.sheep.ridable", sheepRidable);
sheepRidableInWater = getBoolean("mobs.sheep.ridable-in-water", sheepRidableInWater);
@@ -1521,6 +1564,7 @@ public class PurpurWorldConfig {
}
sheepMaxHealth = getDouble("mobs.sheep.attributes.max_health", sheepMaxHealth);
sheepScale = Mth.clamp(getDouble("mobs.sheep.attributes.scale", sheepScale), 0.0625D, 16.0D);
+ sheepBreedingTicks = getInt("mobs.sheep.breeding-delay-ticks", sheepBreedingTicks);
}
public boolean shulkerRidable = false;
@@ -1657,12 +1701,14 @@ public class PurpurWorldConfig {
public boolean snifferControllable = true;
public double snifferMaxHealth = 14.0D;
public double snifferScale = 1.0D;
+ public int snifferBreedingTicks = 6000;
private void snifferSettings() {
snifferRidable = getBoolean("mobs.sniffer.ridable", snifferRidable);
snifferRidableInWater = getBoolean("mobs.sniffer.ridable-in-water", snifferRidableInWater);
snifferControllable = getBoolean("mobs.sniffer.controllable", snifferControllable);
snifferMaxHealth = getDouble("mobs.sniffer.attributes.max_health", snifferMaxHealth);
snifferScale = Mth.clamp(getDouble("mobs.sniffer.attributes.scale", snifferScale), 0.0625D, 16.0D);
+ snifferBreedingTicks = getInt("mobs.sniffer.breeding-delay-ticks", snifferBreedingTicks);
}
public boolean squidRidable = false;
@@ -1728,6 +1774,7 @@ public class PurpurWorldConfig {
public boolean striderControllable = true;
public double striderMaxHealth = 20.0D;
public double striderScale = 1.0D;
+ public int striderBreedingTicks = 6000;
private void striderSettings() {
striderRidable = getBoolean("mobs.strider.ridable", striderRidable);
striderRidableInWater = getBoolean("mobs.strider.ridable-in-water", striderRidableInWater);
@@ -1739,6 +1786,7 @@ public class PurpurWorldConfig {
}
striderMaxHealth = getDouble("mobs.strider.attributes.max_health", striderMaxHealth);
striderScale = Mth.clamp(getDouble("mobs.strider.attributes.scale", striderScale), 0.0625D, 16.0D);
+ striderBreedingTicks = getInt("mobs.strider.breeding-delay-ticks", striderBreedingTicks);
}
public boolean tadpoleRidable = false;
@@ -1759,6 +1807,7 @@ public class PurpurWorldConfig {
public double traderLlamaJumpStrengthMax = 0.5D;
public double traderLlamaMovementSpeedMin = 0.175D;
public double traderLlamaMovementSpeedMax = 0.175D;
+ public int traderLlamaBreedingTicks = 6000;
private void traderLlamaSettings() {
traderLlamaRidable = getBoolean("mobs.trader_llama.ridable", traderLlamaRidable);
traderLlamaRidableInWater = getBoolean("mobs.trader_llama.ridable-in-water", traderLlamaRidableInWater);
@@ -1776,6 +1825,7 @@ public class PurpurWorldConfig {
traderLlamaJumpStrengthMax = getDouble("mobs.trader_llama.attributes.jump_strength.max", traderLlamaJumpStrengthMax);
traderLlamaMovementSpeedMin = getDouble("mobs.trader_llama.attributes.movement_speed.min", traderLlamaMovementSpeedMin);
traderLlamaMovementSpeedMax = getDouble("mobs.trader_llama.attributes.movement_speed.max", traderLlamaMovementSpeedMax);
+ traderLlamaBreedingTicks = getInt("mobs.trader_llama.breeding-delay-ticks", traderLlamaBreedingTicks);
}
public boolean tropicalFishRidable = false;
@@ -1799,6 +1849,7 @@ public class PurpurWorldConfig {
public boolean turtleControllable = true;
public double turtleMaxHealth = 30.0D;
public double turtleScale = 1.0D;
+ public int turtleBreedingTicks = 6000;
private void turtleSettings() {
turtleRidable = getBoolean("mobs.turtle.ridable", turtleRidable);
turtleRidableInWater = getBoolean("mobs.turtle.ridable-in-water", turtleRidableInWater);
@@ -1810,6 +1861,7 @@ public class PurpurWorldConfig {
}
turtleMaxHealth = getDouble("mobs.turtle.attributes.max_health", turtleMaxHealth);
turtleScale = Mth.clamp(getDouble("mobs.turtle.attributes.scale", turtleScale), 0.0625D, 16.0D);
+ turtleBreedingTicks = getInt("mobs.turtle.breeding-delay-ticks", turtleBreedingTicks);
}
public boolean vexRidable = false;
@@ -1841,6 +1893,7 @@ public class PurpurWorldConfig {
public double villagerTemptRange = 10.0D;
public boolean villagerCanBeLeashed = false;
public boolean villagerCanBreed = true;
+ public int villagerBreedingTicks = 6000;
private void villagerSettings() {
villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable);
villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater);
@@ -1856,6 +1909,7 @@ public class PurpurWorldConfig {
villagerTemptRange = getDouble("mobs.villager.attributes.tempt_range", villagerTemptRange);
villagerCanBeLeashed = getBoolean("mobs.villager.can-be-leashed", villagerCanBeLeashed);
villagerCanBreed = getBoolean("mobs.villager.can-breed", villagerCanBreed);
+ villagerBreedingTicks = getInt("mobs.villager.breeding-delay-ticks", villagerBreedingTicks);
}
public boolean vindicatorRidable = false;
@@ -1980,6 +2034,7 @@ public class PurpurWorldConfig {
public boolean wolfControllable = true;
public double wolfMaxHealth = 8.0D;
public double wolfScale = 1.0D;
+ public int wolfBreedingTicks = 6000;
private void wolfSettings() {
wolfRidable = getBoolean("mobs.wolf.ridable", wolfRidable);
wolfRidableInWater = getBoolean("mobs.wolf.ridable-in-water", wolfRidableInWater);
@@ -1991,6 +2046,7 @@ public class PurpurWorldConfig {
}
wolfMaxHealth = getDouble("mobs.wolf.attributes.max_health", wolfMaxHealth);
wolfScale = Mth.clamp(getDouble("mobs.wolf.attributes.scale", wolfScale), 0.0625D, 16.0D);
+ wolfBreedingTicks = getInt("mobs.wolf.breeding-delay-ticks", wolfBreedingTicks);
}
public boolean zoglinRidable = false;

View File

@@ -1,159 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Tue, 17 Nov 2020 03:23:48 -0800
Subject: [PATCH] Apply display names from item forms of entities to entities
and vice versa
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
index edb0cd90e28016c44b0aaf5c9ed5d7bdbced5295..12ff824ffa81ea45f76337ec2b6d80b01047b698 100644
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
@@ -618,6 +618,7 @@ public class ArmorStand extends LivingEntity {
private org.bukkit.event.entity.EntityDeathEvent brokenByPlayer(ServerLevel world, DamageSource damageSource) { // Paper
ItemStack itemstack = new ItemStack(Items.ARMOR_STAND);
+ if (this.level().purpurConfig.persistentDroppableEntityDisplayNames)
itemstack.set(DataComponents.CUSTOM_NAME, this.getCustomName());
this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior
return this.brokenByAnything(world, damageSource); // Paper
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java
index bbdaaa1cc0b4aed28bc39385508d221055b99d4d..bd5e034ce58ebe53d2121209d76ae60134ce72fe 100644
--- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java
+++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java
@@ -240,7 +240,13 @@ public class ItemFrame extends HangingEntity {
}
if (dropSelf) {
- this.spawnAtLocation(world, this.getFrameItemStack());
+ // Purpur start
+ final ItemStack itemFrame = this.getFrameItemStack();
+ if (!this.level().purpurConfig.persistentDroppableEntityDisplayNames) {
+ itemFrame.set(DataComponents.CUSTOM_NAME, null);
+ }
+ this.spawnAtLocation(world, itemFrame);
+ // Purpur end
}
if (!itemstack.isEmpty()) {
diff --git a/src/main/java/net/minecraft/world/entity/decoration/Painting.java b/src/main/java/net/minecraft/world/entity/decoration/Painting.java
index fd0e78a2318e3950d011c17358245e107b38154a..0fcab828e81176323cbdf16c0ec714d9a2846ae5 100644
--- a/src/main/java/net/minecraft/world/entity/decoration/Painting.java
+++ b/src/main/java/net/minecraft/world/entity/decoration/Painting.java
@@ -179,7 +179,13 @@ public class Painting extends HangingEntity implements VariantHolder<Holder<Pain
}
}
- this.spawnAtLocation(world, (ItemLike) Items.PAINTING);
+ // Purpur start
+ final ItemStack painting = new ItemStack((ItemLike) Items.PAINTING);
+ if (!this.level().purpurConfig.persistentDroppableEntityDisplayNames) {
+ painting.set(net.minecraft.core.component.DataComponents.CUSTOM_NAME, null);
+ }
+ this.spawnAtLocation(world, painting);
+ // Purpur end
}
}
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java
index e523f651e8776a89ffba015921d708f569fad8f3..56c265940208bc94f531a5af94f564b59f35ebf3 100644
--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java
+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java
@@ -930,7 +930,13 @@ public abstract class AbstractBoat extends VehicleEntity implements Leashable {
@Override
public final ItemStack getPickResult() {
- return new ItemStack((ItemLike) this.dropItem.get());
+ // Purpur start
+ final ItemStack boat = new ItemStack((ItemLike) this.dropItem.get());
+ if (!this.level().purpurConfig.persistentDroppableEntityDisplayNames) {
+ boat.set(net.minecraft.core.component.DataComponents.CUSTOM_NAME, null);
+ }
+ return boat;
+ // Purpur end
}
public static enum Status {
diff --git a/src/main/java/net/minecraft/world/item/ArmorStandItem.java b/src/main/java/net/minecraft/world/item/ArmorStandItem.java
index cb4baebe22eeab17aed67a5ecc506b932fe2230b..c1a6734cc08de1c9fc413b1fa81a199ac9547ec2 100644
--- a/src/main/java/net/minecraft/world/item/ArmorStandItem.java
+++ b/src/main/java/net/minecraft/world/item/ArmorStandItem.java
@@ -59,6 +59,14 @@ public class ArmorStandItem extends Item {
return InteractionResult.FAIL;
}
// CraftBukkit end
+ // Purpur start
+ if (!world.purpurConfig.persistentDroppableEntityDisplayNames) {
+ entityarmorstand.setCustomName(null);
+ }
+ if (world.purpurConfig.armorstandSetNameVisible && entityarmorstand.getCustomName() != null) {
+ entityarmorstand.setCustomNameVisible(true);
+ }
+ // Purpur end
worldserver.addFreshEntityWithPassengers(entityarmorstand);
world.playSound((Player) null, entityarmorstand.getX(), entityarmorstand.getY(), entityarmorstand.getZ(), SoundEvents.ARMOR_STAND_PLACE, SoundSource.BLOCKS, 0.75F, 0.8F);
entityarmorstand.gameEvent(GameEvent.ENTITY_PLACE, context.getPlayer());
diff --git a/src/main/java/net/minecraft/world/item/BoatItem.java b/src/main/java/net/minecraft/world/item/BoatItem.java
index e51ffd6c5047ee907a58f3029f0ea7fc66aedfa7..78d41d57df9cb61b295f1f54db1e1d62c13db701 100644
--- a/src/main/java/net/minecraft/world/item/BoatItem.java
+++ b/src/main/java/net/minecraft/world/item/BoatItem.java
@@ -71,6 +71,11 @@ public class BoatItem extends Item {
return InteractionResult.FAIL;
} else {
abstractboat.setYRot(user.getYRot());
+ // Purpur start
+ if (!world.purpurConfig.persistentDroppableEntityDisplayNames) {
+ abstractboat.setCustomName(null);
+ }
+ // Purpur end
if (!world.noCollision(abstractboat, abstractboat.getBoundingBox())) {
return InteractionResult.FAIL;
} else {
diff --git a/src/main/java/net/minecraft/world/item/HangingEntityItem.java b/src/main/java/net/minecraft/world/item/HangingEntityItem.java
index cdc17ad948d8ac5de62f14b1a561433d33211f32..44a7cee7df2927a923455e8cedaab59307b42506 100644
--- a/src/main/java/net/minecraft/world/item/HangingEntityItem.java
+++ b/src/main/java/net/minecraft/world/item/HangingEntityItem.java
@@ -75,6 +75,11 @@ public class HangingEntityItem extends Item {
if (!customdata.isEmpty()) {
EntityType.updateCustomEntityTag(world, entityhuman, (Entity) object, customdata);
+ // Purpur start
+ if (!world.purpurConfig.persistentDroppableEntityDisplayNames) {
+ ((Entity) object).setCustomName(null);
+ }
+ // Purpur end
}
if (((HangingEntity) object).survives()) {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index e363a93bdfcef7408ecdd5618b63c345ab9525b4..4efb19a627b3735fe2ded2108576d76296b605f3 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -98,8 +98,10 @@ public class PurpurWorldConfig {
}
public float armorstandStepHeight = 0.0F;
+ public boolean armorstandSetNameVisible = false;
private void armorstandSettings() {
armorstandStepHeight = (float) getDouble("gameplay-mechanics.armorstand.step-height", armorstandStepHeight);
+ armorstandSetNameVisible = getBoolean("gameplay-mechanics.armorstand.set-name-visible-when-placing-with-custom-name", armorstandSetNameVisible);
}
public boolean arrowMovementResetsDespawnCounter = true;
@@ -115,6 +117,7 @@ public class PurpurWorldConfig {
public boolean entitiesCanUsePortals = true;
public int raidCooldownSeconds = 0;
public int animalBreedingCooldownSeconds = 0;
+ public boolean persistentDroppableEntityDisplayNames = true;
private void miscGameplayMechanicsSettings() {
useBetterMending = getBoolean("gameplay-mechanics.use-better-mending", useBetterMending);
boatEjectPlayersOnLand = getBoolean("gameplay-mechanics.boat.eject-players-on-land", boatEjectPlayersOnLand);
@@ -124,6 +127,8 @@ public class PurpurWorldConfig {
entitiesCanUsePortals = getBoolean("gameplay-mechanics.entities-can-use-portals", entitiesCanUsePortals);
raidCooldownSeconds = getInt("gameplay-mechanics.raid-cooldown-seconds", raidCooldownSeconds);
animalBreedingCooldownSeconds = getInt("gameplay-mechanics.animal-breeding-cooldown-seconds", animalBreedingCooldownSeconds);
+ persistentDroppableEntityDisplayNames = getBoolean("gameplay-mechanics.persistent-droppable-entity-display-names", persistentDroppableEntityDisplayNames);
+
}
public int daytimeTicks = 12000;