200 patches...

This commit is contained in:
granny
2024-10-25 23:54:53 -07:00
parent a2899425e7
commit bc370d5521
52 changed files with 443 additions and 469 deletions

View File

@@ -1,52 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Tue, 13 Apr 2021 11:19:35 -0500
Subject: [PATCH] Piglin portal spawn modifier
Allows changing the modifier for the piglin spawn chance from a portal block
based on the world difficulty.
For example, with the default vanilla value of 2000 there is a 2 out of 2000 chance
for a piglin to spawn in a portal block each tick in normal mode.
Equation: random.nextInt(modifier) < difficulty
Difficulties:
0 - peaceful
1 - easy
2 - normal
3 - hard
diff --git a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
index e8cccf3d89ecef13c0523c2357ef4b07e30a25b4..971dd866fe5d6fcef573cb52582ccb7faf01b2f1 100644
--- a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
@@ -77,7 +77,7 @@ public class NetherPortalBlock extends Block implements Portal {
@Override
protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
- if (world.spigotConfig.enableZombiePigmenPortalSpawns && world.dimensionType().natural() && world.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && random.nextInt(2000) < world.getDifficulty().getId()) { // Spigot
+ if (world.spigotConfig.enableZombiePigmenPortalSpawns && world.dimensionType().natural() && world.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && random.nextInt(world.purpurConfig.piglinPortalSpawnModifier) < world.getDifficulty().getId()) { // Spigot // Purpur
while (world.getBlockState(pos).is((Block) this)) {
pos = pos.below();
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 22de19aeb28795484525ddb22df96b89f915eceb..e3522c713a2ed08ee7ef35c048dd7913cb1b2567 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1702,6 +1702,7 @@ public class PurpurWorldConfig {
public double piglinScale = 1.0D;
public boolean piglinBypassMobGriefing = false;
public boolean piglinTakeDamageFromWater = false;
+ public int piglinPortalSpawnModifier = 2000;
private void piglinSettings() {
piglinRidable = getBoolean("mobs.piglin.ridable", piglinRidable);
piglinRidableInWater = getBoolean("mobs.piglin.ridable-in-water", piglinRidableInWater);
@@ -1715,6 +1716,7 @@ public class PurpurWorldConfig {
piglinScale = Mth.clamp(getDouble("mobs.piglin.attributes.scale", piglinScale), 0.0625D, 16.0D);
piglinBypassMobGriefing = getBoolean("mobs.piglin.bypass-mob-griefing", piglinBypassMobGriefing);
piglinTakeDamageFromWater = getBoolean("mobs.piglin.takes-damage-from-water", piglinTakeDamageFromWater);
+ piglinPortalSpawnModifier = getInt("mobs.piglin.portal-spawn-modifier", piglinPortalSpawnModifier);
}
public boolean piglinBruteRidable = false;

View File

@@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: DoctaEnkoda <bierquejason@gmail.com>
Date: Thu, 29 Apr 2021 19:37:48 +0200
Subject: [PATCH] Config to change max number of bees
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
index f933fa419a4b55b0096ff42caf1b071d027b8e7e..fb84af3b1709101fa572d11a1c27970a316f2eab 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
@@ -59,7 +59,7 @@ public class BeehiveBlockEntity extends BlockEntity {
private List<BeehiveBlockEntity.BeeData> stored = Lists.newArrayList();
@Nullable
public BlockPos savedFlowerPos;
- public int maxBees = 3; // CraftBukkit - allow setting max amount of bees a hive can hold
+ public int maxBees = org.purpurmc.purpur.PurpurConfig.beeInsideBeeHive; // CraftBukkit - allow setting max amount of bees a hive can hold // Purpur
public BeehiveBlockEntity(BlockPos pos, BlockState state) {
super(BlockEntityType.BEEHIVE, pos, state);
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index b37daca2ca99d79210ec5e8e9d589e27702a57e5..24e3148c51c3d558a3945827842c414d9cdc2e40 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -252,6 +252,7 @@ public class PurpurConfig {
public static boolean enderChestSixRows = false;
public static boolean enderChestPermissionRows = false;
public static boolean cryingObsidianValidForPortalFrame = false;
+ public static int beeInsideBeeHive = 3;
private static void blockSettings() {
if (version < 3) {
boolean oldValue = getBoolean("settings.barrel.packed-barrels", true);
@@ -283,6 +284,7 @@ public class PurpurConfig {
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);
+ beeInsideBeeHive = getInt("settings.blocks.beehive.max-bees-inside", beeInsideBeeHive);
}
public static boolean allowInapplicableEnchants = false;

View File

@@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ben Kerllenevich <ben@omega24.dev>
Date: Thu, 29 Apr 2021 14:39:07 -0400
Subject: [PATCH] Config for wither explosion radius
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 e472df057d087fe46bd40b798c050ed6e38a283c..999453409c19abf7f5b5c2dc399699856e57329e 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java
@@ -103,7 +103,7 @@ public class WitherSkull extends AbstractHurtingProjectile {
if (!this.level().isClientSide) {
// CraftBukkit start
// this.level().explode(this, this.getX(), this.getY(), this.getZ(), 1.0F, false, World.a.MOB);
- ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 1.0F, false);
+ ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), this.level().purpurConfig.witherExplosionRadius, false); // Purpur
this.level().getCraftServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index e3522c713a2ed08ee7ef35c048dd7913cb1b2567..b3cee9f29fc9ee891d4b18ebfec219e80126a390 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -2399,6 +2399,7 @@ public class PurpurWorldConfig {
public boolean witherBypassMobGriefing = false;
public boolean witherTakeDamageFromWater = false;
public boolean witherCanRideVehicles = false;
+ public float witherExplosionRadius = 1.0F;
private void witherSettings() {
witherRidable = getBoolean("mobs.wither.ridable", witherRidable);
witherRidableInWater = getBoolean("mobs.wither.ridable-in-water", witherRidableInWater);
@@ -2420,6 +2421,7 @@ public class PurpurWorldConfig {
witherBypassMobGriefing = getBoolean("mobs.wither.bypass-mob-griefing", witherBypassMobGriefing);
witherTakeDamageFromWater = getBoolean("mobs.wither.takes-damage-from-water", witherTakeDamageFromWater);
witherCanRideVehicles = getBoolean("mobs.wither.can-ride-vehicles", witherCanRideVehicles);
+ witherExplosionRadius = (float) getDouble("mobs.wither.explosion-radius", witherExplosionRadius);
}
public boolean witherSkeletonRidable = false;

View File

@@ -1,94 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Fri, 30 Apr 2021 13:39:39 -0500
Subject: [PATCH] Gamemode extra permissions
diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java
index 2f7ed5b38e8930b3a615f160cdf4c5b0ec932a8d..08e783882d0b2ef3ebf88e664f1a3d8bf65f49f2 100644
--- a/src/main/java/net/minecraft/commands/CommandSourceStack.java
+++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java
@@ -209,6 +209,19 @@ public class CommandSourceStack implements ExecutionCommandSource<CommandSourceS
}
// CraftBukkit end
+ // Purpur start
+ public boolean testPermission(int i, String bukkitPermission) {
+ if (hasPermission(i, bukkitPermission)) {
+ return true;
+ }
+ net.kyori.adventure.text.Component permissionMessage = getLevel().getServer().server.permissionMessage();
+ if (!permissionMessage.equals(net.kyori.adventure.text.Component.empty())) {
+ sendFailure(io.papermc.paper.adventure.PaperAdventure.asVanilla(permissionMessage.replaceText(net.kyori.adventure.text.TextReplacementConfig.builder().matchLiteral("<permission>").replacement(bukkitPermission).build())));
+ }
+ return false;
+ }
+ // Purpur end
+
public Vec3 getPosition() {
return this.worldPosition;
}
diff --git a/src/main/java/net/minecraft/server/commands/GameModeCommand.java b/src/main/java/net/minecraft/server/commands/GameModeCommand.java
index d1da3600dc07107309b20ebe6e7c0c4da0e8de76..244b4719c689f153fa36381a60acc280bb0bd9b3 100644
--- a/src/main/java/net/minecraft/server/commands/GameModeCommand.java
+++ b/src/main/java/net/minecraft/server/commands/GameModeCommand.java
@@ -57,6 +57,18 @@ public class GameModeCommand {
}
private static int setMode(CommandContext<CommandSourceStack> context, Collection<ServerPlayer> targets, GameType gameMode) {
+ // Purpur start
+ if (org.purpurmc.purpur.PurpurConfig.commandGamemodeRequiresPermission) {
+ String gamemode = gameMode.getName();
+ CommandSourceStack sender = context.getSource();
+ if (!sender.testPermission(2, "minecraft.command.gamemode." + gamemode)) {
+ return 0;
+ }
+ if (sender.getEntity() instanceof ServerPlayer player && (targets.size() > 1 || !targets.contains(player)) && !sender.testPermission(2, "minecraft.command.gamemode." + gamemode + ".other")) {
+ return 0;
+ }
+ }
+ // Purpur end
int i = 0;
for (ServerPlayer serverPlayer : targets) {
diff --git a/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java b/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java
index 52649f82351ab4f675c3cc3cd6640956b0f76b91..eb51c88c7a0658190d3a8bfd5d18dca79d85fba0 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java
@@ -23,7 +23,15 @@ public final class CommandPermissions {
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "kick", "Allows the user to kick players", PermissionDefault.OP, commands);
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "stop", "Allows the user to stop the server", PermissionDefault.OP, commands);
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "list", "Allows the user to list all online players", PermissionDefault.OP, commands);
- DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "gamemode", "Allows the user to change the gamemode of another player", PermissionDefault.OP, commands);
+ // Purpur start
+ Permission gamemodeVanilla = DefaultPermissions.registerPermission(PREFIX + "gamemode", "Allows the user to change the gamemode", PermissionDefault.OP, commands);
+ for (net.minecraft.world.level.GameType gametype : net.minecraft.world.level.GameType.values()) {
+ Permission gamemodeSelf = DefaultPermissions.registerPermission(PREFIX + "gamemode." + gametype.getName(), "Allows the user to set " + gametype.getName() + " gamemode for self", PermissionDefault.OP);
+ Permission gamemodeOther = DefaultPermissions.registerPermission(PREFIX + "gamemode." + gametype.getName() + ".other", "Allows the user to set " + gametype.getName() + " gamemode for other players", PermissionDefault.OP);
+ gamemodeSelf.addParent(gamemodeOther, true);
+ gamemodeVanilla.addParent(gamemodeSelf, true);
+ }
+ // Purpur end
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "experience", "Allows the user to give themselves or others arbitrary values of experience", PermissionDefault.OP, commands); // Paper - wrong permission; redirects are de-redirected and the root literal name is used, so xp -> experience
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "defaultgamemode", "Allows the user to change the default gamemode of the server", PermissionDefault.OP, commands);
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "seed", "Allows the user to view the seed of the world", PermissionDefault.OP, commands);
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index b0c3135d8af0fd73d6445bdbea91d51527f180b8..9d0fe642adec085ba308aa40a00f0ff99c18521e 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -235,6 +235,7 @@ public class PurpurConfig {
public static String commandTPSBarTextColorMedium = "<gradient:#ffff55:#ffaa00><text></gradient>";
public static String commandTPSBarTextColorLow = "<gradient:#ff5555:#aa0000><text></gradient>";
public static int commandTPSBarTickInterval = 20;
+ public static boolean commandGamemodeRequiresPermission = false;
private static void commandSettings() {
commandTPSBarTitle = getString("settings.command.tpsbar.title", commandTPSBarTitle);
commandTPSBarProgressOverlay = BossBar.Overlay.valueOf(getString("settings.command.tpsbar.overlay", commandTPSBarProgressOverlay.name()));
@@ -246,6 +247,7 @@ public class PurpurConfig {
commandTPSBarTextColorMedium = getString("settings.command.tpsbar.text-color.medium", commandTPSBarTextColorMedium);
commandTPSBarTextColorLow = getString("settings.command.tpsbar.text-color.low", commandTPSBarTextColorLow);
commandTPSBarTickInterval = getInt("settings.command.tpsbar.tick-interval", commandTPSBarTickInterval);
+ commandGamemodeRequiresPermission = getBoolean("settings.command.gamemode.requires-specific-permission", commandGamemodeRequiresPermission);
}
public static int barrelRows = 3;

View File

@@ -1,53 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: DoctaEnkoda <bierquejason@gmail.com>
Date: Sun, 2 May 2021 23:14:54 +0200
Subject: [PATCH] Configurable piston push limit
diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonStructureResolver.java b/src/main/java/net/minecraft/world/level/block/piston/PistonStructureResolver.java
index 205e223c356634bd6bc6bd58c6f0b7fda61a6f5f..bea05cb928d540a2f19b51bb7352d032b2dd69cd 100644
--- a/src/main/java/net/minecraft/world/level/block/piston/PistonStructureResolver.java
+++ b/src/main/java/net/minecraft/world/level/block/piston/PistonStructureResolver.java
@@ -81,7 +81,7 @@ public class PistonStructureResolver {
return true;
} else {
int i = 1;
- if (i + this.toPush.size() > 12) {
+ if (i + this.toPush.size() > this.level.purpurConfig.pistonBlockPushLimit) { // Purpur
return false;
} else {
while (isSticky(blockState)) {
@@ -95,7 +95,7 @@ public class PistonStructureResolver {
break;
}
- if (++i + this.toPush.size() > 12) {
+ if (++i + this.toPush.size() > this.level.purpurConfig.pistonBlockPushLimit) { // Purpur
return false;
}
}
@@ -140,7 +140,7 @@ public class PistonStructureResolver {
return true;
}
- if (this.toPush.size() >= 12) {
+ if (this.toPush.size() >= this.level.purpurConfig.pistonBlockPushLimit) { // Purpur
return false;
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index b3cee9f29fc9ee891d4b18ebfec219e80126a390..89932b59058db834174919eb57007638e0b92bbd 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -570,6 +570,11 @@ public class PurpurWorldConfig {
lavaSpeedNotNether = getInt("blocks.lava.speed.not-nether", lavaSpeedNotNether);
}
+ public int pistonBlockPushLimit = 12;
+ private void pistonSettings() {
+ pistonBlockPushLimit = getInt("blocks.piston.block-push-limit", pistonBlockPushLimit);
+ }
+
public boolean powderSnowBypassMobGriefing = false;
private void powderSnowSettings() {
powderSnowBypassMobGriefing = getBoolean("blocks.powder_snow.bypass-mob-griefing", powderSnowBypassMobGriefing);

View File

@@ -1,53 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: DoctaEnkoda <bierquejason@gmail.com>
Date: Mon, 3 May 2021 01:33:14 +0200
Subject: [PATCH] Configurable broadcast settings
diff --git a/src/main/java/net/minecraft/server/PlayerAdvancements.java b/src/main/java/net/minecraft/server/PlayerAdvancements.java
index c3cc63c7bbfab346cfd25b69fbb4872bf66b142f..8cd8a173ac262ef974c32faf23bffa5072e99ab8 100644
--- a/src/main/java/net/minecraft/server/PlayerAdvancements.java
+++ b/src/main/java/net/minecraft/server/PlayerAdvancements.java
@@ -250,6 +250,7 @@ public class PlayerAdvancements {
advancement.value().display().ifPresent((advancementdisplay) -> {
// Paper start - Add Adventure message to PlayerAdvancementDoneEvent
if (event.message() != null && this.player.level().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) {
+ if (org.purpurmc.purpur.PurpurConfig.advancementOnlyBroadcastToAffectedPlayer) this.player.sendMessage(message); else // Purpur
this.playerList.broadcastSystemMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.message()), false);
// Paper end
}
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 513ab3d7d3ff4fe0a5c9c609ca752357b2d8055a..e081734828f7991ffc33233843779fd65f9ea9d7 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -1082,6 +1082,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
}));
PlayerTeam scoreboardteam = this.getTeam();
+ if (org.purpurmc.purpur.PurpurConfig.deathMessageOnlyBroadcastToAffectedPlayer) this.sendSystemMessage(ichatbasecomponent); else // Purpur
if (scoreboardteam != null && scoreboardteam.getDeathMessageVisibility() != Team.Visibility.ALWAYS) {
if (scoreboardteam.getDeathMessageVisibility() == Team.Visibility.HIDE_FOR_OTHER_TEAMS) {
this.server.getPlayerList().broadcastSystemToTeam(this, ichatbasecomponent);
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index 9d0fe642adec085ba308aa40a00f0ff99c18521e..40e06f4d0547b391497944475f3ea30c4d8ff76c 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -205,6 +205,18 @@ public class PurpurConfig {
deathMsgRunWithScissors = getString("settings.messages.death-message.run-with-scissors", deathMsgRunWithScissors);
}
+ public static boolean advancementOnlyBroadcastToAffectedPlayer = false;
+ public static boolean deathMessageOnlyBroadcastToAffectedPlayer = false;
+ private static void broadcastSettings() {
+ if (version < 13) {
+ boolean oldValue = getBoolean("settings.advancement.only-broadcast-to-affected-player", false);
+ set("settings.broadcasts.advancement.only-broadcast-to-affected-player", oldValue);
+ set("settings.advancement.only-broadcast-to-affected-player", null);
+ }
+ advancementOnlyBroadcastToAffectedPlayer = getBoolean("settings.broadcasts.advancement.only-broadcast-to-affected-player", advancementOnlyBroadcastToAffectedPlayer);
+ deathMessageOnlyBroadcastToAffectedPlayer = getBoolean("settings.broadcasts.death.only-broadcast-to-affected-player", deathMessageOnlyBroadcastToAffectedPlayer);
+ }
+
public static String serverModName = io.papermc.paper.ServerBuildInfo.buildInfo().brandName();
private static void serverModName() {
serverModName = getString("settings.server-mod-name", serverModName);

View File

@@ -1,49 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Tue, 11 May 2021 21:00:53 -0400
Subject: [PATCH] Configurable mob blindness
Ported from https://github.com/raltsmc/mobblindness
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index d4ba4752b04ad3d1a8133c56144800af756f4aa6..b0d9f432eb9ebaf88196de4f1329ef530b422ca0 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -1042,6 +1042,17 @@ public abstract class LivingEntity extends Entity implements Attackable {
if (entitytypes == EntityType.SKELETON && itemstack.is(Items.SKELETON_SKULL) || entitytypes == EntityType.ZOMBIE && itemstack.is(Items.ZOMBIE_HEAD) || entitytypes == EntityType.PIGLIN && itemstack.is(Items.PIGLIN_HEAD) || entitytypes == EntityType.PIGLIN_BRUTE && itemstack.is(Items.PIGLIN_HEAD) || entitytypes == EntityType.CREEPER && itemstack.is(Items.CREEPER_HEAD)) {
d0 *= 0.5D;
}
+
+ // Purpur start
+ if (entity instanceof LivingEntity entityliving) {
+ if (entityliving.hasEffect(MobEffects.BLINDNESS)) {
+ int amplifier = entityliving.getEffect(MobEffects.BLINDNESS).getAmplifier();
+ for (int i = 0; i < amplifier; i++) {
+ d0 *= this.level().purpurConfig.mobsBlindnessMultiplier;
+ }
+ }
+ }
+ // Purpur end
}
return d0;
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 89932b59058db834174919eb57007638e0b92bbd..e9075362020d3dec49b3fbcbbe80a00264d3c6fd 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -135,6 +135,7 @@ public class PurpurWorldConfig {
public boolean persistentDroppableEntityDisplayNames = true;
public boolean projectilesBypassMobGriefing = false;
public boolean tickFluids = true;
+ public double mobsBlindnessMultiplier = 1;
public double tridentLoyaltyVoidReturnHeight = 0.0D;
public int raidCooldownSeconds = 0;
public int animalBreedingCooldownSeconds = 0;
@@ -155,6 +156,7 @@ public class PurpurWorldConfig {
persistentDroppableEntityDisplayNames = getBoolean("gameplay-mechanics.persistent-droppable-entity-display-names", persistentDroppableEntityDisplayNames);
projectilesBypassMobGriefing = getBoolean("gameplay-mechanics.projectiles-bypass-mob-griefing", projectilesBypassMobGriefing);
tickFluids = getBoolean("gameplay-mechanics.tick-fluids", tickFluids);
+ mobsBlindnessMultiplier = getDouble("gameplay-mechanics.entity-blindness-multiplier", mobsBlindnessMultiplier);
tridentLoyaltyVoidReturnHeight = getDouble("gameplay-mechanics.trident-loyalty-void-return-height", tridentLoyaltyVoidReturnHeight);
raidCooldownSeconds = getInt("gameplay-mechanics.raid-cooldown-seconds", raidCooldownSeconds);
animalBreedingCooldownSeconds = getInt("gameplay-mechanics.animal-breeding-cooldown-seconds", animalBreedingCooldownSeconds);

View File

@@ -1,80 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Thu, 13 May 2021 16:18:29 -0500
Subject: [PATCH] Hide hidden players from entity selector
diff --git a/src/main/java/net/minecraft/commands/arguments/selector/EntitySelector.java b/src/main/java/net/minecraft/commands/arguments/selector/EntitySelector.java
index c8d39e6e1c570c9219f6066da273dc0130920519..b455c7e9d18bac3654daa8510f85cc21202e254b 100644
--- a/src/main/java/net/minecraft/commands/arguments/selector/EntitySelector.java
+++ b/src/main/java/net/minecraft/commands/arguments/selector/EntitySelector.java
@@ -198,10 +198,10 @@ public class EntitySelector {
if (this.playerName != null) {
entityplayer = source.getServer().getPlayerList().getPlayerByName(this.playerName);
- return entityplayer == null ? List.of() : List.of(entityplayer);
+ return entityplayer == null || !canSee(source, entityplayer) ? List.of() : List.of(entityplayer); // Purpur
} else if (this.entityUUID != null) {
entityplayer = source.getServer().getPlayerList().getPlayer(this.entityUUID);
- return entityplayer == null ? List.of() : List.of(entityplayer);
+ return entityplayer == null || !canSee(source, entityplayer) ? List.of() : List.of(entityplayer); // Purpur
} else {
Vec3 vec3d = (Vec3) this.position.apply(source.getPosition());
AABB axisalignedbb = this.getAbsoluteAabb(vec3d);
@@ -214,7 +214,7 @@ public class EntitySelector {
ServerPlayer entityplayer1 = (ServerPlayer) entity;
if (predicate.test(entityplayer1)) {
- return List.of(entityplayer1);
+ return !canSee(source, entityplayer1) ? List.of() : List.of(entityplayer1); // Purpur
}
}
@@ -225,6 +225,7 @@ public class EntitySelector {
if (this.isWorldLimited()) {
object = source.getLevel().getPlayers(predicate, i);
+ ((List) object).removeIf(entityplayer3 -> !canSee(source, (ServerPlayer) entityplayer3)); // Purpur
} else {
object = new ObjectArrayList();
Iterator iterator = source.getServer().getPlayerList().getPlayers().iterator();
@@ -232,7 +233,7 @@ public class EntitySelector {
while (iterator.hasNext()) {
ServerPlayer entityplayer2 = (ServerPlayer) iterator.next();
- if (predicate.test(entityplayer2)) {
+ if (predicate.test(entityplayer2) && canSee(source, entityplayer2)) { // Purpur
((List) object).add(entityplayer2);
if (((List) object).size() >= i) {
return (List) object;
@@ -299,4 +300,10 @@ public class EntitySelector {
public static Component joinNames(List<? extends Entity> entities) {
return ComponentUtils.formatList(entities, Entity::getDisplayName);
}
+
+ // Purpur start
+ private boolean canSee(CommandSourceStack sender, ServerPlayer target) {
+ return !org.purpurmc.purpur.PurpurConfig.hideHiddenPlayersFromEntitySelector || !(sender.getEntity() instanceof ServerPlayer player) || player.getBukkitEntity().canSee(target.getBukkitEntity());
+ }
+ // Purpur end
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index 40e06f4d0547b391497944475f3ea30c4d8ff76c..82e79211ec48578dad18e590ab1f9b58ae024c7c 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -248,6 +248,7 @@ public class PurpurConfig {
public static String commandTPSBarTextColorLow = "<gradient:#ff5555:#aa0000><text></gradient>";
public static int commandTPSBarTickInterval = 20;
public static boolean commandGamemodeRequiresPermission = false;
+ public static boolean hideHiddenPlayersFromEntitySelector = false;
private static void commandSettings() {
commandTPSBarTitle = getString("settings.command.tpsbar.title", commandTPSBarTitle);
commandTPSBarProgressOverlay = BossBar.Overlay.valueOf(getString("settings.command.tpsbar.overlay", commandTPSBarProgressOverlay.name()));
@@ -260,6 +261,7 @@ public class PurpurConfig {
commandTPSBarTextColorLow = getString("settings.command.tpsbar.text-color.low", commandTPSBarTextColorLow);
commandTPSBarTickInterval = getInt("settings.command.tpsbar.tick-interval", commandTPSBarTickInterval);
commandGamemodeRequiresPermission = getBoolean("settings.command.gamemode.requires-specific-permission", commandGamemodeRequiresPermission);
+ hideHiddenPlayersFromEntitySelector = getBoolean("settings.command.hide-hidden-players-from-entity-selector", hideHiddenPlayersFromEntitySelector);
}
public static int barrelRows = 3;

View File

@@ -1,42 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Thu, 29 Apr 2021 20:28:18 -0400
Subject: [PATCH] Config for health to impact Creeper explosion radius
diff --git a/src/main/java/net/minecraft/world/entity/monster/Creeper.java b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
index 902191001a7302872ff661564fb6389457abaa9c..1769c1d31bb68904be426e1069266cec809cf31a 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
@@ -374,9 +374,10 @@ public class Creeper extends Monster implements PowerableMob {
if (!this.level().isClientSide) {
float f = this.isPowered() ? 2.0F : 1.0F;
+ float multiplier = this.level().purpurConfig.creeperHealthRadius ? this.getHealth() / this.getMaxHealth() : 1; // Purpur
// CraftBukkit start
- ExplosionPrimeEvent event = CraftEventFactory.callExplosionPrimeEvent(this, this.explosionRadius * f, false);
+ ExplosionPrimeEvent event = CraftEventFactory.callExplosionPrimeEvent(this, (this.explosionRadius * f) * multiplier, false); // Purpur
if (!event.isCancelled()) {
// CraftBukkit end
this.dead = true;
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index e9075362020d3dec49b3fbcbbe80a00264d3c6fd..898e82aac8f2636a95e6987f967d6c57c0e412da 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -939,6 +939,7 @@ public class PurpurWorldConfig {
public boolean creeperBypassMobGriefing = false;
public boolean creeperTakeDamageFromWater = false;
public boolean creeperExplodeWhenKilled = false;
+ public boolean creeperHealthRadius = false;
private void creeperSettings() {
creeperRidable = getBoolean("mobs.creeper.ridable", creeperRidable);
creeperRidableInWater = getBoolean("mobs.creeper.ridable-in-water", creeperRidableInWater);
@@ -955,6 +956,7 @@ public class PurpurWorldConfig {
creeperBypassMobGriefing = getBoolean("mobs.creeper.bypass-mob-griefing", creeperBypassMobGriefing);
creeperTakeDamageFromWater = getBoolean("mobs.creeper.takes-damage-from-water", creeperTakeDamageFromWater);
creeperExplodeWhenKilled = getBoolean("mobs.creeper.explode-when-killed", creeperExplodeWhenKilled);
+ creeperHealthRadius = getBoolean("mobs.creeper.health-impacts-explosion", creeperHealthRadius);
}
public boolean dolphinRidable = false;

View File

@@ -1,145 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Thu, 13 May 2021 21:22:51 -0500
Subject: [PATCH] Iron golem calm anger options
diff --git a/src/main/java/net/minecraft/world/entity/animal/IronGolem.java b/src/main/java/net/minecraft/world/entity/animal/IronGolem.java
index 0cf985cac3279c0cb6255f02b76a5012027cae99..446a2795aa8f2ddf472f8b379534978fca285f3d 100644
--- a/src/main/java/net/minecraft/world/entity/animal/IronGolem.java
+++ b/src/main/java/net/minecraft/world/entity/animal/IronGolem.java
@@ -93,6 +93,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
@Override
protected void registerGoals() {
if (level().purpurConfig.ironGolemCanSwim) this.goalSelector.addGoal(0, new net.minecraft.world.entity.ai.goal.FloatGoal(this)); // Purpur
+ if (this.level().purpurConfig.ironGolemPoppyCalm) this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.ReceiveFlower(this)); // Purpur
this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur
this.goalSelector.addGoal(1, new MeleeAttackGoal(this, 1.0D, true));
this.goalSelector.addGoal(2, new MoveTowardsTargetGoal(this, 0.9D, 32.0F));
@@ -316,6 +317,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
this.playSound(SoundEvents.IRON_GOLEM_REPAIR, 1.0F, f1);
itemstack.consume(1, player);
+ if (this.level().purpurConfig.ironGolemHealCalm && isAngry() && getHealth() == getMaxHealth()) stopBeingAngry(); // Purpur
return InteractionResult.sidedSuccess(this.level().isClientSide);
}
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 898e82aac8f2636a95e6987f967d6c57c0e412da..f7a854144d447f6464473ee437c36d1e16984cab 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1429,6 +1429,8 @@ public class PurpurWorldConfig {
public double ironGolemMaxHealth = 100.0D;
public double ironGolemScale = 1.0D;
public boolean ironGolemTakeDamageFromWater = false;
+ public boolean ironGolemPoppyCalm = false;
+ public boolean ironGolemHealCalm = false;
private void ironGolemSettings() {
ironGolemRidable = getBoolean("mobs.iron_golem.ridable", ironGolemRidable);
ironGolemRidableInWater = getBoolean("mobs.iron_golem.ridable-in-water", ironGolemRidableInWater);
@@ -1442,6 +1444,8 @@ public class PurpurWorldConfig {
ironGolemMaxHealth = getDouble("mobs.iron_golem.attributes.max_health", ironGolemMaxHealth);
ironGolemScale = Mth.clamp(getDouble("mobs.iron_golem.attributes.scale", ironGolemScale), 0.0625D, 16.0D);
ironGolemTakeDamageFromWater = getBoolean("mobs.iron_golem.takes-damage-from-water", ironGolemTakeDamageFromWater);
+ ironGolemPoppyCalm = getBoolean("mobs.iron_golem.poppy-calms-anger", ironGolemPoppyCalm);
+ ironGolemHealCalm = getBoolean("mobs.iron_golem.healing-calms-anger", ironGolemHealCalm);
}
public boolean llamaRidable = false;
diff --git a/src/main/java/org/purpurmc/purpur/entity/ai/ReceiveFlower.java b/src/main/java/org/purpurmc/purpur/entity/ai/ReceiveFlower.java
new file mode 100644
index 0000000000000000000000000000000000000000..9660716f4162a4441c6e1b0baddef8f5086566c5
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/entity/ai/ReceiveFlower.java
@@ -0,0 +1,91 @@
+package org.purpurmc.purpur.entity.ai;
+
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.InteractionHand;
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.entity.ai.goal.Goal;
+import net.minecraft.world.entity.animal.IronGolem;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.level.block.Blocks;
+
+import java.util.EnumSet;
+import java.util.UUID;
+
+public class ReceiveFlower extends Goal {
+ private final IronGolem irongolem;
+ private ServerPlayer target;
+ private int cooldown;
+
+ public ReceiveFlower(IronGolem entity) {
+ this.irongolem = entity;
+ setFlags(EnumSet.of(Flag.MOVE, Flag.LOOK));
+ }
+
+ @Override
+ public boolean canUse() {
+ if (this.irongolem.getOfferFlowerTick() > 0) {
+ return false;
+ }
+ if (!this.irongolem.isAngry()) {
+ return false;
+ }
+ UUID uuid = this.irongolem.getPersistentAngerTarget();
+ if (uuid == null) {
+ return false;
+ }
+ Entity target = ((ServerLevel) this.irongolem.level()).getEntity(uuid);
+ if (!(target instanceof ServerPlayer player)) {
+ return false;
+ }
+ InteractionHand hand = getPoppyHand(player);
+ if (hand == null) {
+ return false;
+ }
+ removeFlower(player, hand);
+ this.target = player;
+ return true;
+ }
+
+ @Override
+ public boolean canContinueToUse() {
+ return this.cooldown > 0;
+ }
+
+ @Override
+ public void start() {
+ this.cooldown = 100;
+ this.irongolem.stopBeingAngry();
+ this.irongolem.offerFlower(true);
+ }
+
+ @Override
+ public void stop() {
+ this.irongolem.offerFlower(false);
+ this.target = null;
+ }
+
+ @Override
+ public void tick() {
+ this.irongolem.getLookControl().setLookAt(this.target, 30.0F, 30.0F);
+ --this.cooldown;
+ }
+
+ private InteractionHand getPoppyHand(ServerPlayer player) {
+ if (isPoppy(player.getMainHandItem())) {
+ return InteractionHand.MAIN_HAND;
+ }
+ if (isPoppy(player.getOffhandItem())) {
+ return InteractionHand.OFF_HAND;
+ }
+ return null;
+ }
+
+ private void removeFlower(ServerPlayer player, InteractionHand hand) {
+ player.setItemInHand(hand, ItemStack.EMPTY);
+ }
+
+ private boolean isPoppy(ItemStack item) {
+ return item.getItem() == Blocks.POPPY.asItem();
+ }
+}

View File

@@ -1,71 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Thu, 13 May 2021 22:17:50 -0500
Subject: [PATCH] Breedable parrots
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 884fc114ef70d49fd0d64fcea46fb277950962a1..4fa32a6406e3158369064d39160e485010484886 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Parrot.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Parrot.java
@@ -222,6 +222,7 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder<Parrot
protected void registerGoals() {
//this.goalSelector.addGoal(0, new TamableAnimal.TamableAnimalPanicGoal(1.25D)); // Purpur - move down
this.goalSelector.addGoal(0, new FloatGoal(this));
+ if (this.level().purpurConfig.parrotBreedable) this.goalSelector.addGoal(1, new net.minecraft.world.entity.ai.goal.BreedGoal(this, 1.0D)); // Purpur
this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur
this.goalSelector.addGoal(1, new TamableAnimal.TamableAnimalPanicGoal(1.25D)); // Purpur
this.goalSelector.addGoal(1, new LookAtPlayerGoal(this, Player.class, 8.0F));
@@ -330,6 +331,7 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder<Parrot
}
}
+ if (this.level().purpurConfig.parrotBreedable) return super.mobInteract(player, hand); // Purpur
return InteractionResult.sidedSuccess(this.level().isClientSide);
} else if (!itemstack.is(ItemTags.PARROT_POISONOUS_FOOD)) {
if (!this.isFlying() && this.isTame() && this.isOwnedBy(player)) {
@@ -354,7 +356,7 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder<Parrot
@Override
public boolean isFood(ItemStack stack) {
- return false;
+ return this.level().purpurConfig.parrotBreedable && stack.is(ItemTags.PARROT_FOOD); // Purpur
}
public static boolean checkParrotSpawnRules(EntityType<Parrot> type, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, RandomSource random) {
@@ -366,13 +368,13 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder<Parrot
@Override
public boolean canMate(Animal other) {
- return false;
+ return super.canMate(other); // Purpur
}
@Nullable
@Override
public AgeableMob getBreedOffspring(ServerLevel world, AgeableMob entity) {
- return null;
+ return world.purpurConfig.parrotBreedable ? EntityType.PARROT.create(world) : null; // Purpur
}
@Nullable
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index f7a854144d447f6464473ee437c36d1e16984cab..79130d2f36feb0c402f58aee1f7c0eff07b47b36 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1607,6 +1607,7 @@ public class PurpurWorldConfig {
public double parrotMaxHealth = 6.0D;
public double parrotScale = 1.0D;
public boolean parrotTakeDamageFromWater = false;
+ public boolean parrotBreedable = false;
private void parrotSettings() {
parrotRidable = getBoolean("mobs.parrot.ridable", parrotRidable);
parrotRidableInWater = getBoolean("mobs.parrot.ridable-in-water", parrotRidableInWater);
@@ -1620,6 +1621,7 @@ public class PurpurWorldConfig {
parrotMaxHealth = getDouble("mobs.parrot.attributes.max_health", parrotMaxHealth);
parrotScale = Mth.clamp(getDouble("mobs.parrot.attributes.scale", parrotScale), 0.0625D, 16.0D);
parrotTakeDamageFromWater = getBoolean("mobs.parrot.takes-damage-from-water", parrotTakeDamageFromWater);
+ parrotBreedable = getBoolean("mobs.parrot.can-breed", parrotBreedable);
}
public boolean phantomRidable = false;

View File

@@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Callum Seabrook <callum.seabrook@prevarinite.com>
Date: Fri, 14 May 2021 21:22:57 +0100
Subject: [PATCH] Configurable powered rail boost modifier
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
index d7bcfca8c79cc172bb7e4aaeee76ff393d1d2bea..8b1c00062a5272d1020bc85491d8627c4d5f46cb 100644
--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
@@ -683,7 +683,7 @@ public abstract class AbstractMinecart extends VehicleEntity {
if (d18 > 0.01D) {
double d20 = 0.06D;
- this.setDeltaMovement(vec3d4.add(vec3d4.x / d18 * 0.06D, 0.0D, vec3d4.z / d18 * 0.06D));
+ this.setDeltaMovement(vec3d4.add(vec3d4.x / d18 * this.level().purpurConfig.poweredRailBoostModifier, 0.0D, vec3d4.z / d18 * this.level().purpurConfig.poweredRailBoostModifier)); // Purpur
} else {
Vec3 vec3d5 = this.getDeltaMovement();
double d21 = vec3d5.x;
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 79130d2f36feb0c402f58aee1f7c0eff07b47b36..7d59c418f583d7247868595a2b00c2328c351e30 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -268,6 +268,7 @@ public class PurpurWorldConfig {
public boolean minecartControllableFallDamage = true;
public double minecartControllableBaseSpeed = 0.1D;
public Map<Block, Double> minecartControllableBlockSpeeds = new HashMap<>();
+ public double poweredRailBoostModifier = 0.06;
private void minecartSettings() {
if (PurpurConfig.version < 12) {
boolean oldBool = getBoolean("gameplay-mechanics.controllable-minecarts.place-anywhere", minecartPlaceAnywhere);
@@ -320,6 +321,7 @@ public class PurpurWorldConfig {
set("gameplay-mechanics.minecart.controllable.block-speed.grass_block", 0.3D);
set("gameplay-mechanics.minecart.controllable.block-speed.stone", 0.5D);
}
+ poweredRailBoostModifier = getDouble("gameplay-mechanics.minecart.powered-rail.boost-modifier", poweredRailBoostModifier);
}
public boolean catSpawning;

View File

@@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: DoctaEnkoda <bierquejason@gmail.com>
Date: Mon, 17 May 2021 02:40:13 +0200
Subject: [PATCH] Add config change multiplier critical damage value
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 33c1b2b387e7412a001841d1bcbb3966c188c1a3..40cf2eb78b02adc15e44189021005f147e00185c 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -1348,7 +1348,7 @@ public abstract class Player extends LivingEntity {
flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper - Toggleable player crits
if (flag2) {
damagesource = damagesource.critical(true); // Paper start - critical damage API
- f *= 1.5F;
+ f *= this.level().purpurConfig.playerCriticalDamageMultiplier; // Purpur
}
float f3 = f + f1;
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 7d59c418f583d7247868595a2b00c2328c351e30..ca337c301190ecebdbae2e353785352c178bca96 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -365,6 +365,7 @@ public class PurpurWorldConfig {
public boolean creativeOnePunch = false;
public boolean playerSleepNearMonsters = false;
public boolean playersSkipNight = true;
+ public double playerCriticalDamageMultiplier = 1.5D;
private void playerSettings() {
if (PurpurConfig.version < 19) {
boolean oldVal = getBoolean("gameplay-mechanics.player.idle-timeout.mods-target", idleTimeoutTargetPlayer);
@@ -384,6 +385,7 @@ public class PurpurWorldConfig {
creativeOnePunch = getBoolean("gameplay-mechanics.player.one-punch-in-creative", creativeOnePunch);
playerSleepNearMonsters = getBoolean("gameplay-mechanics.player.sleep-ignore-nearby-mobs", playerSleepNearMonsters);
playersSkipNight = getBoolean("gameplay-mechanics.player.can-skip-night", playersSkipNight);
+ playerCriticalDamageMultiplier = getDouble("gameplay-mechanics.player.critical-damage-multiplier", playerCriticalDamageMultiplier);
}
public boolean silkTouchEnabled = 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: Mon, 17 May 2021 04:46:23 -0500
Subject: [PATCH] Option to disable dragon egg teleporting
diff --git a/src/main/java/net/minecraft/world/level/block/DragonEggBlock.java b/src/main/java/net/minecraft/world/level/block/DragonEggBlock.java
index fbe15cdd5b9bca2ab4b1e871abbbdbff49ade8a4..23d113842bf774bdc74e0dffcc97b642bc8684f1 100644
--- a/src/main/java/net/minecraft/world/level/block/DragonEggBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/DragonEggBlock.java
@@ -48,8 +48,8 @@ public class DragonEggBlock extends FallingBlock {
}
private void teleport(BlockState state, Level world, BlockPos pos) {
+ if (!world.purpurConfig.dragonEggTeleport) return; // Purpur
WorldBorder worldborder = world.getWorldBorder();
-
for (int i = 0; i < 1000; ++i) {
BlockPos blockposition1 = pos.offset(world.random.nextInt(16) - world.random.nextInt(16), world.random.nextInt(8) - world.random.nextInt(8), world.random.nextInt(16) - world.random.nextInt(16));
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index ca337c301190ecebdbae2e353785352c178bca96..e52308a81158014fadbc486604ae54a232d2a4b0 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -497,6 +497,11 @@ public class PurpurWorldConfig {
});
}
+ public boolean dragonEggTeleport = true;
+ private void dragonEggSettings() {
+ dragonEggTeleport = getBoolean("blocks.dragon_egg.teleport", dragonEggTeleport);
+ }
+
public boolean baselessEndCrystalExplode = true;
public double baselessEndCrystalExplosionPower = 6.0D;
public boolean baselessEndCrystalExplosionFire = false;

View File

@@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ben Kerllenevich <ben@omega24.dev>
Date: Wed, 19 May 2021 15:33:43 -0400
Subject: [PATCH] Config for unverified username message
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
index 40638b439966619e9c70a18a32abd95b2178fe9f..19d3423644a6a394743c09eb6935bb7633a329a2 100644
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
@@ -322,7 +322,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
ServerLoginPacketListenerImpl.LOGGER.warn("Failed to verify username but will let them in anyway!");
ServerLoginPacketListenerImpl.this.startClientVerification(ServerLoginPacketListenerImpl.this.createOfflineProfile(s1)); // Spigot
} else {
- ServerLoginPacketListenerImpl.this.disconnect(Component.translatable("multiplayer.disconnect.unverified_username"));
+ ServerLoginPacketListenerImpl.this.disconnect(org.purpurmc.purpur.PurpurConfig.unverifiedUsername.equals("default") ? Component.translatable("multiplayer.disconnect.unverified_username") : io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.unverifiedUsername))); // Purpur
ServerLoginPacketListenerImpl.LOGGER.error("Username '{}' tried to join with an invalid session", s1);
}
} catch (AuthenticationUnavailableException authenticationunavailableexception) {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index 82e79211ec48578dad18e590ab1f9b58ae024c7c..35d86953ea87c5977acf1c83c2071bc622996510 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -186,6 +186,7 @@ public class PurpurConfig {
public static String pingCommandOutput = "<green>%s's ping is %sms";
public static String tpsbarCommandOutput = "<green>Tpsbar toggled <onoff> for <target>";
public static String dontRunWithScissors = "<red><italic>Don't run with scissors!";
+ public static String unverifiedUsername = "default";
private static void messages() {
cannotRideMob = getString("settings.messages.cannot-ride-mob", cannotRideMob);
afkBroadcastAway = getString("settings.messages.afk-broadcast-away", afkBroadcastAway);
@@ -198,6 +199,7 @@ public class PurpurConfig {
pingCommandOutput = getString("settings.messages.ping-command-output", pingCommandOutput);
tpsbarCommandOutput = getString("settings.messages.tpsbar-command-output", tpsbarCommandOutput);
dontRunWithScissors = getString("settings.messages.dont-run-with-scissors", dontRunWithScissors);
+ unverifiedUsername = getString("settings.messages.unverified-username", unverifiedUsername);
}
public static String deathMsgRunWithScissors = "<player> slipped and fell on their shears";

View File

@@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 12emin34 <macanovic.emin@gmail.com>
Date: Fri, 21 May 2021 16:58:45 +0200
Subject: [PATCH] Make anvil cumulative cost configurable
diff --git a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
index 29e54876c22739f45565cd91bcbd76612e8bfad1..bd146be65c558dcd388359081e2625c4f5fbdc79 100644
--- a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
+++ b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
@@ -400,7 +400,7 @@ public class AnvilMenu extends ItemCombinerMenu {
}
public static int calculateIncreasedRepairCost(int cost) {
- return (int) Math.min((long) cost * 2L + 1L, 2147483647L);
+ return org.purpurmc.purpur.PurpurConfig.anvilCumulativeCost ? (int) Math.min((long) cost * 2L + 1L, 2147483647L) : 0; // Purpur - Make anvil cumulative cost configurable
}
public boolean setItemName(String newItemName) {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index a106b462b3739ecb19db991faffc348f60ff03df..ebbaa21dbaff140818fad10accd05721451b37cb 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -271,6 +271,7 @@ public class PurpurConfig {
public static boolean enderChestPermissionRows = false;
public static boolean cryingObsidianValidForPortalFrame = false;
public static int beeInsideBeeHive = 3;
+ public static boolean anvilCumulativeCost = true;
private static void blockSettings() {
if (version < 3) {
boolean oldValue = getBoolean("settings.barrel.packed-barrels", true);
@@ -303,6 +304,7 @@ public class PurpurConfig {
enderChestPermissionRows = getBoolean("settings.blocks.ender_chest.use-permissions-for-rows", enderChestPermissionRows);
cryingObsidianValidForPortalFrame = getBoolean("settings.blocks.crying_obsidian.valid-for-portal-frame", cryingObsidianValidForPortalFrame);
beeInsideBeeHive = getInt("settings.blocks.beehive.max-bees-inside", beeInsideBeeHive);
+ anvilCumulativeCost = getBoolean("settings.blocks.anvil.cumulative-cost", anvilCumulativeCost);
}
public static boolean allowInapplicableEnchants = false;

View File

@@ -1,54 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: DoctaEnkoda <bierquejason@gmail.com>
Date: Thu, 27 May 2021 06:46:30 +0200
Subject: [PATCH] Bee can work when raining or at night
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 e7f85150fb7dcee5ba0d7bc3830a0544e18e9817..55fb4555dacfb6c34ff491b88cfed2b6e2ab3a6f 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Bee.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java
@@ -406,7 +406,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
boolean wantsToEnterHive() {
if (this.stayOutOfHiveCountdown <= 0 && !this.beePollinateGoal.isPollinating() && !this.hasStung() && this.getTarget() == null) {
- boolean flag = this.isTiredOfLookingForNectar() || this.level().isRaining() || this.level().isNight() || this.hasNectar();
+ boolean flag = this.isTiredOfLookingForNectar() || (this.level().isRaining() && !this.level().purpurConfig.beeCanWorkInRain) || (this.level().isNight() && !this.level().purpurConfig.beeCanWorkAtNight) || this.hasNectar(); // Purpur
return flag && !this.isHiveNearFire();
} else {
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
index fb84af3b1709101fa572d11a1c27970a316f2eab..5e982bab268746a05b97f5b9f71422548ea12983 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
@@ -212,7 +212,7 @@ public class BeehiveBlockEntity extends BlockEntity {
}
private static boolean releaseOccupant(Level world, BlockPos blockposition, BlockState iblockdata, BeehiveBlockEntity.Occupant tileentitybeehive_c, @Nullable List<Entity> list, BeehiveBlockEntity.BeeReleaseStatus tileentitybeehive_releasestatus, @Nullable BlockPos blockposition1, boolean force) {
- if (!force && (world.isNight() || world.isRaining()) && tileentitybeehive_releasestatus != BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY) {
+ if (!force && ((world.isNight() && !world.purpurConfig.beeCanWorkAtNight) || (world.isRaining() && !world.purpurConfig.beeCanWorkInRain)) && tileentitybeehive_releasestatus != BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY) { // Purpur
// CraftBukkit end
return false;
} else {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index e52308a81158014fadbc486604ae54a232d2a4b0..722a3a1f222536995a3da0a4ad1f85db590a61c0 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -748,6 +748,8 @@ public class PurpurWorldConfig {
public double beeScale = 1.0D;
public int beeBreedingTicks = 6000;
public boolean beeTakeDamageFromWater = false;
+ public boolean beeCanWorkAtNight = false;
+ public boolean beeCanWorkInRain = false;
private void beeSettings() {
beeRidable = getBoolean("mobs.bee.ridable", beeRidable);
beeRidableInWater = getBoolean("mobs.bee.ridable-in-water", beeRidableInWater);
@@ -762,6 +764,8 @@ public class PurpurWorldConfig {
beeScale = Mth.clamp(getDouble("mobs.bee.attributes.scale", beeScale), 0.0625D, 16.0D);
beeBreedingTicks = getInt("mobs.bee.breeding-delay-ticks", beeBreedingTicks);
beeTakeDamageFromWater = getBoolean("mobs.bee.takes-damage-from-water", beeTakeDamageFromWater);
+ beeCanWorkAtNight = getBoolean("mobs.bee.can-work-at-night", beeCanWorkAtNight);
+ beeCanWorkInRain = getBoolean("mobs.bee.can-work-in-rain", beeCanWorkInRain);
}
public boolean blazeRidable = false;

View File

@@ -1,397 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ben Kerllenevich <ben@omega24.dev>
Date: Tue, 25 May 2021 16:31:09 -0400
Subject: [PATCH] API for any mob to burn daylight
Co-authored by: Encode42 <me@encode42.dev>
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 657980c6c82b6a50ee9874f4aeb483b40dc24247..338c2afa277178b3d4d667142799f015c7b97cd0 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -559,6 +559,22 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
// Purpur end
+ // Purpur start - copied from Mob - API for any mob to burn daylight
+ public boolean isSunBurnTick() {
+ if (this.level().isDay() && !this.level().isClientSide) {
+ float f = this.getLightLevelDependentMagicValue();
+ BlockPos blockposition = BlockPos.containing(this.getX(), this.getEyeY(), this.getZ());
+ boolean flag = this.isInWaterRainOrBubble() || this.isInPowderSnow || this.wasInPowderSnow;
+
+ if (f > 0.5F && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && !flag && this.level().canSeeSky(blockposition)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ // Purpur end - copied from Mob - API for any mob to burn daylight
+
public Entity(EntityType<?> type, Level world) {
this.id = Entity.ENTITY_COUNTER.incrementAndGet();
this.passengers = ImmutableList.of();
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index b0d9f432eb9ebaf88196de4f1329ef530b422ca0..c8e5162e3494f221ebbf538d7416c8508358546d 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -285,6 +285,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
public org.bukkit.craftbukkit.entity.CraftLivingEntity getBukkitLivingEntity() { return (org.bukkit.craftbukkit.entity.CraftLivingEntity) super.getBukkitEntity(); } // Paper
public boolean silentDeath = false; // Paper - mark entity as dying silently for cancellable death event
public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API
+ protected boolean shouldBurnInDay = false; public boolean shouldBurnInDay() { return this.shouldBurnInDay; } public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; } // Purpur - API for any mob to burn daylight
@Override
public float getBukkitYaw() {
@@ -816,6 +817,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
dataresult.resultOrPartial(logger::error).ifPresent((nbtbase) -> {
nbt.put("Brain", nbtbase);
});
+ nbt.putBoolean("Purpur.ShouldBurnInDay", this.shouldBurnInDay); // Purpur - API for any mob to burn daylight
}
@Override
@@ -904,6 +906,11 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.brain = this.makeBrain(new Dynamic(NbtOps.INSTANCE, nbt.get("Brain")));
}
+ // Purpur start - API for any mob to burn daylight
+ if (nbt.contains("Purpur.ShouldBurnInDay")) {
+ this.shouldBurnInDay = nbt.getBoolean("Purpur.ShouldBurnInDay");
+ }
+ // Purpur end - API for any mob to burn daylight
}
// CraftBukkit start
@@ -3661,6 +3668,34 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.hurt(this.damageSources().drown(), 1.0F);
}
+ // Purpur start - copied from Zombie - API for any mob to burn daylight
+ if (this.isAlive()) {
+ boolean flag = this.shouldBurnInDay() && this.isSunBurnTick(); // Paper - shouldBurnInDay API // Purpur - use shouldBurnInDay() method to handle Phantoms properly - API for any mob to burn daylight
+
+ if (flag) {
+ ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD);
+
+ if (!itemstack.isEmpty()) {
+ if (itemstack.isDamageableItem()) {
+ Item item = itemstack.getItem();
+
+ itemstack.setDamageValue(itemstack.getDamageValue() + this.random.nextInt(2));
+ if (itemstack.getDamageValue() >= itemstack.getMaxDamage()) {
+ this.onEquippedItemBroken(item, EquipmentSlot.HEAD);
+ this.setItemSlot(EquipmentSlot.HEAD, ItemStack.EMPTY);
+ }
+ }
+
+ flag = false;
+ }
+
+ if (flag) {
+ if (getRider() == null || !this.isControllable()) // Purpur - ignore mobs which are uncontrollable or without rider - API for any mob to burn daylight
+ this.igniteForSeconds(8.0F);
+ }
+ }
+ }
+ // Purpur end - copied from Zombie - API for any mob to burn daylight
}
public boolean isSensitiveToWater() {
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
index 70ace6f2a42c0d4181cb22a08dd923bd77c08295..518968c03e4e7ae99c2e40f6164c89ad27bad697 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
@@ -1788,17 +1788,8 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
protected void playAttackSound() {}
public boolean isSunBurnTick() {
- if (this.level().isDay() && !this.level().isClientSide) {
- float f = this.getLightLevelDependentMagicValue();
- BlockPos blockposition = BlockPos.containing(this.getX(), this.getEyeY(), this.getZ());
- boolean flag = this.isInWaterRainOrBubble() || this.isInPowderSnow || this.wasInPowderSnow;
-
- if (f > 0.5F && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && !flag && this.level().canSeeSky(blockposition)) {
- return true;
- }
- }
-
- return false;
+ // Purpur - implemented in Entity - API for any mob to burn daylight
+ return super.isSunBurnTick();
}
@Override
diff --git a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
index 5c1aa5859ac411098054be9f52bac0860ee667a5..1d06c612eaba8b595fa3d094577f700989d1e224 100644
--- a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
+++ b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
@@ -66,6 +66,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
protected AbstractSkeleton(EntityType<? extends AbstractSkeleton> type, Level world) {
super(type, world);
this.reassessWeaponGoal();
+ this.setShouldBurnInDay(true); // Purpur - API for any mob to burn daylight
}
@Override
@@ -96,37 +97,14 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
abstract SoundEvent getStepSound();
// Paper start - shouldBurnInDay API
- private boolean shouldBurnInDay = true;
+ //private boolean shouldBurnInDay = true; // Purpur - moved to LivingEntity; keep methods for ABI compatibility - API for any mob to burn daylight
public boolean shouldBurnInDay() { return shouldBurnInDay; }
public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; }
// Paper end - shouldBurnInDay API
@Override
public void aiStep() {
- boolean flag = shouldBurnInDay && this.isSunBurnTick(); // Paper - shouldBurnInDay API
-
- if (flag) {
- ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD);
-
- if (!itemstack.isEmpty()) {
- if (itemstack.isDamageableItem()) {
- Item item = itemstack.getItem();
-
- itemstack.setDamageValue(itemstack.getDamageValue() + this.random.nextInt(2));
- if (itemstack.getDamageValue() >= itemstack.getMaxDamage()) {
- this.onEquippedItemBroken(item, EquipmentSlot.HEAD);
- this.setItemSlot(EquipmentSlot.HEAD, ItemStack.EMPTY);
- }
- }
-
- flag = false;
- }
-
- if (flag) {
- this.igniteForSeconds(8.0F);
- }
- }
-
+ // Purpur - implemented in LivingEntity - API for any mob to burn daylight
super.aiStep();
}
@@ -241,7 +219,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
super.readAdditionalSaveData(nbt);
this.reassessWeaponGoal();
// Paper start - shouldBurnInDay API
- if (nbt.contains("Paper.ShouldBurnInDay")) {
+ if (false && nbt.contains("Paper.ShouldBurnInDay")) { // Purpur - implemented in LivingEntity - API for any mob to burn daylight
this.shouldBurnInDay = nbt.getBoolean("Paper.ShouldBurnInDay");
}
// Paper end - shouldBurnInDay API
@@ -251,7 +229,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
@Override
public void addAdditionalSaveData(CompoundTag nbt) {
super.addAdditionalSaveData(nbt);
- nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay);
+ //nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Purpur - implemented in LivingEntity - API for any mob to burn daylight
}
// Paper end - shouldBurnInDay API
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 cb96bd5769159e6c25968673ea07cd6d107cff46..cbfb5bf945b747328746d21395e66d523c268468 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Husk.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Husk.java
@@ -20,6 +20,7 @@ public class Husk extends Zombie {
public Husk(EntityType<? extends Husk> type, Level world) {
super(type, world);
+ this.setShouldBurnInDay(false); // Purpur - API for any mob to burn daylight
}
// Purpur start
@@ -75,7 +76,7 @@ public class Husk extends Zombie {
@Override
public boolean isSunSensitive() {
- return false;
+ return this.shouldBurnInDay; // Purpur - moved to LivingEntity; keep methods for ABI compatibility - API for any mob to burn daylight
}
@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 554e01cf4fb3b15549c8c381274014c4735e08c6..f6b2e0797554baa3bc74e886e22d5bac67c424f6 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
@@ -59,6 +59,7 @@ public class Phantom extends FlyingMob implements Enemy {
this.xpReward = 5;
this.moveControl = new Phantom.PhantomMoveControl(this);
this.lookControl = new Phantom.PhantomLookControl(this, this);
+ this.setShouldBurnInDay(true); // Purpur - API for any mob to burn daylight
}
// Purpur start
@@ -247,15 +248,7 @@ public class Phantom extends FlyingMob implements Enemy {
@Override
public void aiStep() {
- // 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);
- }
-
+ // Purpur - implemented in LivingEntity; moved down to shouldBurnInDay() - API for any mob to burn daylight
super.aiStep();
}
@@ -283,7 +276,7 @@ public class Phantom extends FlyingMob implements Enemy {
if (nbt.hasUUID("Paper.SpawningEntity")) {
this.spawningEntity = nbt.getUUID("Paper.SpawningEntity");
}
- if (nbt.contains("Paper.ShouldBurnInDay")) {
+ if (false && nbt.contains("Paper.ShouldBurnInDay")) { // Purpur - implemented in LivingEntity - API for any mob to burn daylight
this.shouldBurnInDay = nbt.getBoolean("Paper.ShouldBurnInDay");
}
// Paper end
@@ -300,7 +293,7 @@ public class Phantom extends FlyingMob implements Enemy {
if (this.spawningEntity != null) {
nbt.putUUID("Paper.SpawningEntity", this.spawningEntity);
}
- nbt.putBoolean("Paper.ShouldBurnInDay", shouldBurnInDay);
+ //nbt.putBoolean("Paper.ShouldBurnInDay", shouldBurnInDay); // Purpur - implemented in LivingEntity - API for any mob to burn daylight
// Paper end
}
@@ -356,8 +349,14 @@ public class Phantom extends FlyingMob implements Enemy {
return this.spawningEntity;
}
public void setSpawningEntity(java.util.UUID entity) { this.spawningEntity = entity; }
- private boolean shouldBurnInDay = true;
- public boolean shouldBurnInDay() { return shouldBurnInDay; }
+ //private boolean shouldBurnInDay = true; // Purpur - moved to LivingEntity; keep methods for ABI compatibility - API for any mob to burn daylight
+ // Purpur start - API for any mob to burn daylight
+ public boolean shouldBurnInDay() {
+ boolean burnFromDaylight = this.shouldBurnInDay && this.level().purpurConfig.phantomBurnInDaylight;
+ boolean burnFromLightSource = this.level().purpurConfig.phantomBurnInLight > 0 && this.level().getMaxLocalRawBrightness(blockPosition()) >= this.level().purpurConfig.phantomBurnInLight;
+ return burnFromDaylight || burnFromLightSource;
+ }
+ // Purpur end - API for any mob to burn daylight
public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; }
// Paper end
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 990daa4f12ed7fb9a1ab40443c7f68bca4534626..4e7b67e5d6b26d1d0523dfed7f0d029b363fb0ef 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
@@ -97,11 +97,12 @@ public class Zombie extends Monster {
private int inWaterTime;
public int conversionTime;
// private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field // Paper - remove anti tick skipping measures / wall time
- private boolean shouldBurnInDay = true; // Paper - Add more Zombie API
+ //private boolean shouldBurnInDay = true; // Paper - Add more Zombie API // Purpur - implemented in LivingEntity - API for any mob to burn daylight
public Zombie(EntityType<? extends Zombie> type, Level world) {
super(type, world);
this.breakDoorGoal = new BreakDoorGoal(this, com.google.common.base.Predicates.in(world.paperConfig().entities.behavior.doorBreakingDifficulty.getOrDefault(type, world.paperConfig().entities.behavior.doorBreakingDifficulty.get(EntityType.ZOMBIE)))); // Paper - Configurable door breaking difficulty
+ this.setShouldBurnInDay(true); // Purpur - API for any mob to burn daylight
}
public Zombie(Level world) {
@@ -295,32 +296,7 @@ public class Zombie extends Monster {
@Override
public void aiStep() {
- if (this.isAlive()) {
- boolean flag = this.isSunSensitive() && this.isSunBurnTick();
-
- if (flag) {
- ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD);
-
- if (!itemstack.isEmpty()) {
- if (itemstack.isDamageableItem()) {
- Item item = itemstack.getItem();
-
- itemstack.setDamageValue(itemstack.getDamageValue() + this.random.nextInt(2));
- if (itemstack.getDamageValue() >= itemstack.getMaxDamage()) {
- this.onEquippedItemBroken(item, EquipmentSlot.HEAD);
- this.setItemSlot(EquipmentSlot.HEAD, ItemStack.EMPTY);
- }
- }
-
- flag = false;
- }
-
- if (flag) {
- this.igniteForSeconds(8.0F);
- }
- }
- }
-
+ // Purpur - implemented in LivingEntity - API for any mob to burn daylight
super.aiStep();
}
@@ -358,6 +334,7 @@ public class Zombie extends Monster {
}
+ public boolean shouldBurnInDay() { return this.isSunSensitive(); } // Purpur - for ABI compatibility - API for any mob to burn daylight
public boolean isSunSensitive() {
return this.shouldBurnInDay; // Paper - Add more Zombie API
}
@@ -486,7 +463,7 @@ public class Zombie extends Monster {
nbt.putBoolean("CanBreakDoors", this.canBreakDoors());
nbt.putInt("InWaterTime", this.isInWater() ? this.inWaterTime : -1);
nbt.putInt("DrownedConversionTime", this.isUnderWaterConverting() ? this.conversionTime : -1);
- nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API
+ //nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API // Purpur - implemented in LivingEntity - API for any mob to burn daylight
}
@Override
@@ -499,7 +476,7 @@ public class Zombie extends Monster {
this.startUnderWaterConversion(nbt.getInt("DrownedConversionTime"));
}
// Paper start - Add more Zombie API
- if (nbt.contains("Paper.ShouldBurnInDay")) {
+ if (false && nbt.contains("Paper.ShouldBurnInDay")) { // Purpur - implemented in LivingEntity - API for any mob to burn daylight
this.shouldBurnInDay = nbt.getBoolean("Paper.ShouldBurnInDay");
}
// Paper end - Add more Zombie API
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index af3ab1eb9af64605203e7bb671ff08a38be9e6a6..7b7a58039eb1a288262228444712c84d6e2aef24 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -86,6 +86,13 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
this.entityType = CraftEntityType.minecraftToBukkit(entity.getType());
}
+ // Purpur start - API for any mob to burn daylight
+ @Override
+ public boolean isInDaylight() {
+ return getHandle().isSunBurnTick();
+ }
+ // Purpur end - API for any mob to burn daylight
+
public static <T extends Entity> CraftEntity getEntity(CraftServer server, T entity) {
Preconditions.checkArgument(entity != null, "Unknown entity");
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
index 4750df7354ccb5afd0910efe0415f3a2eb19a546..0a3da3d35cd6b41003692d968b77384e7460ca97 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
@@ -1192,4 +1192,16 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
return this.getHandle().canUseSlot(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot));
}
// Paper end - Expose canUseSlot
+
+ // Purpur start - API for any mob to burn daylight
+ @Override
+ public boolean shouldBurnInDay() {
+ return this.getHandle().shouldBurnInDay();
+ }
+
+ @Override
+ public void setShouldBurnInDay(final boolean shouldBurnInDay) {
+ this.getHandle().setShouldBurnInDay(shouldBurnInDay);
+ }
+ // Purpur end - API for any mob to burn daylight
}

View File

@@ -1,99 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: DoctaEnkoda <bierquejason@gmail.com>
Date: Sat, 23 Sep 2023 03:59:15 -0700
Subject: [PATCH] Config MobEffect by world
diff --git a/src/main/java/net/minecraft/world/effect/HungerMobEffect.java b/src/main/java/net/minecraft/world/effect/HungerMobEffect.java
index a476b56ed98d0a1afc6a396ce29424df78f24ada..5119ff3414fbd9a1ae0a8db0fd15bd3c57c8e148 100644
--- a/src/main/java/net/minecraft/world/effect/HungerMobEffect.java
+++ b/src/main/java/net/minecraft/world/effect/HungerMobEffect.java
@@ -12,7 +12,7 @@ class HungerMobEffect extends MobEffect {
@Override
public boolean applyEffectTick(LivingEntity entity, int amplifier) {
if (entity instanceof Player entityhuman) {
- entityhuman.causeFoodExhaustion(0.005F * (float) (amplifier + 1), org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.HUNGER_EFFECT); // CraftBukkit - EntityExhaustionEvent
+ entityhuman.causeFoodExhaustion(entity.level().purpurConfig.humanHungerExhaustionAmount * (float) (amplifier + 1), org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.HUNGER_EFFECT); // CraftBukkit - EntityExhaustionEvent // Purpur
}
return true;
diff --git a/src/main/java/net/minecraft/world/effect/PoisonMobEffect.java b/src/main/java/net/minecraft/world/effect/PoisonMobEffect.java
index 3e7a703632251e0a5234259e3702b58b332e5ef0..f2cc43fbccb5d2ba012b350268065c2cfe014faf 100644
--- a/src/main/java/net/minecraft/world/effect/PoisonMobEffect.java
+++ b/src/main/java/net/minecraft/world/effect/PoisonMobEffect.java
@@ -10,8 +10,8 @@ class PoisonMobEffect extends MobEffect {
@Override
public boolean applyEffectTick(LivingEntity entity, int amplifier) {
- if (entity.getHealth() > 1.0F) {
- entity.hurt(entity.damageSources().poison(), 1.0F); // CraftBukkit - DamageSource.MAGIC -> CraftEventFactory.POISON
+ if (entity.getHealth() > entity.level().purpurConfig.entityMinimalHealthPoison) { // Purpur
+ entity.hurt(entity.damageSources().poison(), entity.level().purpurConfig.entityPoisonDegenerationAmount); // CraftBukkit - DamageSource.MAGIC -> CraftEventFactory.POISON // Purpur
}
return true;
diff --git a/src/main/java/net/minecraft/world/effect/RegenerationMobEffect.java b/src/main/java/net/minecraft/world/effect/RegenerationMobEffect.java
index 4dba3e813e054951cbfbe0b323c1f5d973469cc0..426f61d55b9692cf085368df4e4df6f6997aa420 100644
--- a/src/main/java/net/minecraft/world/effect/RegenerationMobEffect.java
+++ b/src/main/java/net/minecraft/world/effect/RegenerationMobEffect.java
@@ -11,7 +11,7 @@ class RegenerationMobEffect extends MobEffect {
@Override
public boolean applyEffectTick(LivingEntity entity, int amplifier) {
if (entity.getHealth() < entity.getMaxHealth()) {
- entity.heal(1.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.MAGIC_REGEN); // CraftBukkit
+ entity.heal(entity.level().purpurConfig.entityHealthRegenAmount, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.MAGIC_REGEN); // CraftBukkit // Purpur
}
return true;
diff --git a/src/main/java/net/minecraft/world/effect/SaturationMobEffect.java b/src/main/java/net/minecraft/world/effect/SaturationMobEffect.java
index 7b415dca88f50dc472fe4be96e5ef0996f117913..2bb872f29350d15db46b32c686aef78fc1b6fa29 100644
--- a/src/main/java/net/minecraft/world/effect/SaturationMobEffect.java
+++ b/src/main/java/net/minecraft/world/effect/SaturationMobEffect.java
@@ -20,7 +20,7 @@ class SaturationMobEffect extends InstantenousMobEffect {
int oldFoodLevel = entityhuman.getFoodData().foodLevel;
org.bukkit.event.entity.FoodLevelChangeEvent event = CraftEventFactory.callFoodLevelChangeEvent(entityhuman, amplifier + 1 + oldFoodLevel);
if (!event.isCancelled()) {
- entityhuman.getFoodData().eat(event.getFoodLevel() - oldFoodLevel, 1.0F);
+ entityhuman.getFoodData().eat(event.getFoodLevel() - oldFoodLevel, entity.level().purpurConfig.humanSaturationRegenAmount); // Purpur
}
((CraftPlayer) entityhuman.getBukkitEntity()).sendHealthUpdate();
diff --git a/src/main/java/net/minecraft/world/effect/WitherMobEffect.java b/src/main/java/net/minecraft/world/effect/WitherMobEffect.java
index f43bf280999ff3860cc702def50cc62b131eb1bd..66d9e99a351f5fc6cf58be3bee4397d92c932d64 100644
--- a/src/main/java/net/minecraft/world/effect/WitherMobEffect.java
+++ b/src/main/java/net/minecraft/world/effect/WitherMobEffect.java
@@ -9,7 +9,7 @@ class WitherMobEffect extends MobEffect {
@Override
public boolean applyEffectTick(LivingEntity entity, int amplifier) {
- entity.hurt(entity.damageSources().wither(), 1.0F);
+ entity.hurt(entity.damageSources().wither(), entity.level().purpurConfig.entityWitherDegenerationAmount); // Purpur
return true;
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 722a3a1f222536995a3da0a4ad1f85db590a61c0..68d6c2504990f2664518a589f916f41bc54f61bb 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -324,6 +324,21 @@ public class PurpurWorldConfig {
poweredRailBoostModifier = getDouble("gameplay-mechanics.minecart.powered-rail.boost-modifier", poweredRailBoostModifier);
}
+ public float entityHealthRegenAmount = 1.0F;
+ public float entityMinimalHealthPoison = 1.0F;
+ public float entityPoisonDegenerationAmount = 1.0F;
+ public float entityWitherDegenerationAmount = 1.0F;
+ public float humanHungerExhaustionAmount = 0.005F;
+ public float humanSaturationRegenAmount = 1.0F;
+ private void mobEffectSettings() {
+ entityHealthRegenAmount = (float) getDouble("gameplay-mechanics.mob-effects.health-regen-amount", entityHealthRegenAmount);
+ entityMinimalHealthPoison = (float) getDouble("gameplay-mechanics.mob-effects.minimal-health-poison-amount", entityMinimalHealthPoison);
+ entityPoisonDegenerationAmount = (float) getDouble("gameplay-mechanics.mob-effects.poison-degeneration-amount", entityPoisonDegenerationAmount);
+ entityWitherDegenerationAmount = (float) getDouble("gameplay-mechanics.mob-effects.wither-degeneration-amount", entityWitherDegenerationAmount);
+ humanHungerExhaustionAmount = (float) getDouble("gameplay-mechanics.mob-effects.hunger-exhaustion-amount", humanHungerExhaustionAmount);
+ humanSaturationRegenAmount = (float) getDouble("gameplay-mechanics.mob-effects.saturation-regen-amount", humanSaturationRegenAmount);
+ }
+
public boolean catSpawning;
public boolean patrolSpawning;
public boolean phantomSpawning;

View File

@@ -1,49 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: DoctaEnkoda <bierquejason@gmail.com>
Date: Wed, 2 Jun 2021 02:45:47 +0200
Subject: [PATCH] Beacon Activation Range Configurable
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
index 814e70f558d7a6186233da0ff86c94c95d390e09..d1fb77d83d48183a9a37dbeec7bb0fda623d7e9b 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
@@ -92,6 +92,16 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
public double getEffectRange() {
if (this.effectRange < 0) {
+ // Purpur Start
+ if (this.level != null) {
+ switch (this.levels) {
+ case 1: return this.level.purpurConfig.beaconLevelOne;
+ case 2: return this.level.purpurConfig.beaconLevelTwo;
+ case 3: return this.level.purpurConfig.beaconLevelThree;
+ case 4: return this.level.purpurConfig.beaconLevelFour;
+ }
+ }
+ // Purpur End
return this.levels * 10 + 10;
} else {
return effectRange;
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 68d6c2504990f2664518a589f916f41bc54f61bb..2a3bd1593d440b2bece131ce15321fe0a4b92553 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -464,6 +464,17 @@ public class PurpurWorldConfig {
anvilColorsUseMiniMessage = getBoolean("blocks.anvil.use-mini-message", anvilColorsUseMiniMessage);
}
+ public int beaconLevelOne = 20;
+ public int beaconLevelTwo = 30;
+ public int beaconLevelThree = 40;
+ public int beaconLevelFour = 50;
+ private void beaconSettings() {
+ beaconLevelOne = getInt("blocks.beacon.effect-range.level-1", beaconLevelOne);
+ beaconLevelTwo = getInt("blocks.beacon.effect-range.level-2", beaconLevelTwo);
+ beaconLevelThree = getInt("blocks.beacon.effect-range.level-3", beaconLevelThree);
+ beaconLevelFour = getInt("blocks.beacon.effect-range.level-4", beaconLevelFour);
+ }
+
public boolean bedExplode = true;
public double bedExplosionPower = 5.0D;
public boolean bedExplosionFire = true;

View File

@@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 12emin34 <macanovic.emin@gmail.com>
Date: Wed, 23 Jun 2021 13:36:20 +0200
Subject: [PATCH] Make lightning rod range configurable
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 40a5107d37e908d13bd0307fc41d9a6e3faf1217..277a0b6f38b1ce00fd06066b43ac634f80ab441a 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -1021,7 +1021,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
return holder.is(PoiTypes.LIGHTNING_ROD);
}, (blockposition1) -> {
return blockposition1.getY() == this.getHeight(Heightmap.Types.WORLD_SURFACE, blockposition1.getX(), blockposition1.getZ()) - 1;
- }, pos, 128, PoiManager.Occupancy.ANY);
+ }, pos, org.purpurmc.purpur.PurpurConfig.lightningRodRange, PoiManager.Occupancy.ANY);
return optional.map((blockposition1) -> {
return blockposition1.above(1);
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index ebbaa21dbaff140818fad10accd05721451b37cb..e654169f6a290aa52a4e0f647dc7ec6698489729 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -272,6 +272,7 @@ public class PurpurConfig {
public static boolean cryingObsidianValidForPortalFrame = false;
public static int beeInsideBeeHive = 3;
public static boolean anvilCumulativeCost = true;
+ public static int lightningRodRange = 128;
private static void blockSettings() {
if (version < 3) {
boolean oldValue = getBoolean("settings.barrel.packed-barrels", true);
@@ -305,6 +306,7 @@ public class PurpurConfig {
cryingObsidianValidForPortalFrame = getBoolean("settings.blocks.crying_obsidian.valid-for-portal-frame", cryingObsidianValidForPortalFrame);
beeInsideBeeHive = getInt("settings.blocks.beehive.max-bees-inside", beeInsideBeeHive);
anvilCumulativeCost = getBoolean("settings.blocks.anvil.cumulative-cost", anvilCumulativeCost);
+ lightningRodRange = getInt("settings.blocks.lightning_rod.range", lightningRodRange);
}
public static boolean allowInapplicableEnchants = false;

View File

@@ -1,78 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 24 Jun 2021 21:19:30 -0500
Subject: [PATCH] Burp delay, burp after eating food fills hunger bar
completely
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 40cf2eb78b02adc15e44189021005f147e00185c..1552312aa9740c74533821594da7da705a6f5f70 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -198,6 +198,7 @@ public abstract class Player extends LivingEntity {
public boolean affectsSpawning = true; // Paper - Affects Spawning API
public net.kyori.adventure.util.TriState flyingFallDamage = net.kyori.adventure.util.TriState.NOT_SET; // Paper - flying fall damage
public int sixRowEnderchestSlotCount = -1; // Purpur
+ public int burpDelay = 0; // Purpur
// CraftBukkit start
public boolean fauxSleeping;
@@ -273,6 +274,12 @@ public abstract class Player extends LivingEntity {
@Override
public void tick() {
+ // Purpur start
+ if (this.burpDelay > 0 && --this.burpDelay == 0) {
+ this.level().playSound(null, getX(), getY(), getZ(), SoundEvents.PLAYER_BURP, SoundSource.PLAYERS, 1.0F, this.level().random.nextFloat() * 0.1F + 0.9F);
+ }
+ // Purpur end
+
this.noPhysics = this.isSpectator();
if (this.isSpectator()) {
this.setOnGround(false);
@@ -2376,7 +2383,7 @@ public abstract class Player extends LivingEntity {
public ItemStack eat(Level world, ItemStack stack, FoodProperties foodComponent) {
this.getFoodData().eat(stack, foodComponent); // CraftBukkit
this.awardStat(Stats.ITEM_USED.get(stack.getItem()));
- world.playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_BURP, SoundSource.PLAYERS, 0.5F, world.random.nextFloat() * 0.1F + 0.9F);
+ // world.playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_BURP, SoundSource.PLAYERS, 0.5F, world.random.nextFloat() * 0.1F + 0.9F); // Purpur - moved to tick()
if (this instanceof ServerPlayer) {
CriteriaTriggers.CONSUME_ITEM.trigger((ServerPlayer) this, stack);
}
diff --git a/src/main/java/net/minecraft/world/food/FoodData.java b/src/main/java/net/minecraft/world/food/FoodData.java
index bd3f78e6453cfe18aa3da38176b04d734d83bb4b..b702b7270fae8fafc39588fbc39b4e0014809047 100644
--- a/src/main/java/net/minecraft/world/food/FoodData.java
+++ b/src/main/java/net/minecraft/world/food/FoodData.java
@@ -34,8 +34,10 @@ public class FoodData {
// CraftBukkit end
private void add(int nutrition, float saturation) {
+ int oldValue = this.foodLevel; // Purpur
this.foodLevel = Mth.clamp(nutrition + this.foodLevel, 0, 20);
this.saturationLevel = Mth.clamp(saturation + this.saturationLevel, 0.0F, (float) this.foodLevel);
+ if (this.entityhuman.level().purpurConfig.playerBurpWhenFull && this.foodLevel == 20 && oldValue < 20) this.entityhuman.burpDelay = this.entityhuman.level().purpurConfig.playerBurpDelay; // Purpur
}
public void eat(int food, float saturationModifier) {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 2a3bd1593d440b2bece131ce15321fe0a4b92553..a5bea4b6d19d84bbab2adda8c7ba3e5f65b817c0 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -381,6 +381,8 @@ public class PurpurWorldConfig {
public boolean playerSleepNearMonsters = false;
public boolean playersSkipNight = true;
public double playerCriticalDamageMultiplier = 1.5D;
+ public int playerBurpDelay = 10;
+ public boolean playerBurpWhenFull = false;
private void playerSettings() {
if (PurpurConfig.version < 19) {
boolean oldVal = getBoolean("gameplay-mechanics.player.idle-timeout.mods-target", idleTimeoutTargetPlayer);
@@ -401,6 +403,8 @@ public class PurpurWorldConfig {
playerSleepNearMonsters = getBoolean("gameplay-mechanics.player.sleep-ignore-nearby-mobs", playerSleepNearMonsters);
playersSkipNight = getBoolean("gameplay-mechanics.player.can-skip-night", playersSkipNight);
playerCriticalDamageMultiplier = getDouble("gameplay-mechanics.player.critical-damage-multiplier", playerCriticalDamageMultiplier);
+ playerBurpDelay = getInt("gameplay-mechanics.player.burp-delay", playerBurpDelay);
+ playerBurpWhenFull = getBoolean("gameplay-mechanics.player.burp-when-full", playerBurpWhenFull);
}
public boolean silkTouchEnabled = false;

View File

@@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: DoctaEnkoda <bierquejason@gmail.com>
Date: Thu, 24 Jun 2021 02:28:32 +0200
Subject: [PATCH] Allow player join full server by permission
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 338bf471d9214c77653eb69510b722b552e60172..c55f721a611dc215bcbf3f74f752b3bebfbe9ea4 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -748,7 +748,7 @@ public abstract class PlayerList {
event.disallow(PlayerLoginEvent.Result.KICK_BANNED, io.papermc.paper.adventure.PaperAdventure.asAdventure(ichatmutablecomponent)); // Paper - Adventure
} else {
// return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile) ? IChatBaseComponent.translatable("multiplayer.disconnect.server_full") : null;
- if (this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile)) {
+ if (this.players.size() >= this.maxPlayers && !(player.hasPermission("purpur.joinfullserver") || this.canBypassPlayerLimit(gameprofile))) { // Purpur
event.disallow(PlayerLoginEvent.Result.KICK_FULL, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.serverFullMessage)); // Spigot // Paper - Adventure
}
}

View File

@@ -1,43 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 7 Dec 2023 14:53:48 -0800
Subject: [PATCH] Add portal permission bypass
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 1552312aa9740c74533821594da7da705a6f5f70..09e1faae9c22c1062e3de5257c82b2d156e65b4f 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -199,6 +199,7 @@ public abstract class Player extends LivingEntity {
public net.kyori.adventure.util.TriState flyingFallDamage = net.kyori.adventure.util.TriState.NOT_SET; // Paper - flying fall damage
public int sixRowEnderchestSlotCount = -1; // Purpur
public int burpDelay = 0; // Purpur
+ public boolean canPortalInstant = false; // Purpur
// CraftBukkit start
public boolean fauxSleeping;
diff --git a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
index 971dd866fe5d6fcef573cb52582ccb7faf01b2f1..d579132d1afd5c2edb9356c5601584bca2357f8f 100644
--- a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
@@ -129,7 +129,7 @@ public class NetherPortalBlock extends Block implements Portal {
@Override
public int getPortalTransitionTime(ServerLevel world, Entity entity) {
if (entity instanceof Player entityhuman) {
- return Math.max(1, world.getGameRules().getInt(entityhuman.getAbilities().invulnerable ? GameRules.RULE_PLAYERS_NETHER_PORTAL_CREATIVE_DELAY : GameRules.RULE_PLAYERS_NETHER_PORTAL_DEFAULT_DELAY));
+ return Math.max(1, entityhuman.canPortalInstant ? 1 : world.getGameRules().getInt(entityhuman.getAbilities().invulnerable ? GameRules.RULE_PLAYERS_NETHER_PORTAL_CREATIVE_DELAY : GameRules.RULE_PLAYERS_NETHER_PORTAL_DEFAULT_DELAY)); // Purpur
} else {
return 0;
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
index 7dcfb45c24d7743956be514c7d554e06aac77b3e..46856d2b7e24c5d223b7b1627ccb451749b183e7 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
@@ -273,6 +273,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
@Override
public void recalculatePermissions() {
this.perm.recalculatePermissions();
+ getHandle().canPortalInstant = hasPermission("purpur.portal.instant"); // Purpur
}
@Override

View File

@@ -1,97 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Fri, 25 Jun 2021 19:48:21 -0500
Subject: [PATCH] Shulker spawn from bullet options
(0 - 1) / 5.0 = -0.2 (can never happen because self is included in count)
(1 - 1) / 5.0 = 0.0 1.0 - 0.0 = 1.0 100% (just self)
(2 - 1) / 5.0 = 0.2 1.0 - 0.2 = 0.8 80% (1 other shulker)
(3 - 1) / 5.0 = 0.4 1.0 - 0.4 = 0.6 60% (2 other shulkers)
(4 - 1) / 5.0 = 0.6 1.0 - 0.6 = 0.4 40% (3 other shulkers)
(5 - 1) / 5.0 = 0.8 1.0 - 0.8 = 0.2 20% (4 other shulkers)
(6 - 1) / 5.0 = 1.0 1.0 - 1.0 = 0.0 0% (5 other shulkers)
(7 - 1) / 5.0 = 1.2 1.0 - 1.2 = -0.2 0% (6 other shulkers)
diff --git a/src/main/java/net/minecraft/world/entity/monster/Shulker.java b/src/main/java/net/minecraft/world/entity/monster/Shulker.java
index bd4f2297b2267ab99c0419417f37898dd943480b..6f1deb4d26c851ca99fbadf1eb5b7847eadbf25b 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Shulker.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Shulker.java
@@ -511,12 +511,21 @@ public class Shulker extends AbstractGolem implements VariantHolder<Optional<Dye
Vec3 vec3d = this.position();
AABB axisalignedbb = this.getBoundingBox();
- if (!this.isClosed() && this.teleportSomewhere()) {
- int i = this.level().getEntities((EntityTypeTest) EntityType.SHULKER, axisalignedbb.inflate(8.0D), Entity::isAlive).size();
- float f = (float) (i - 1) / 5.0F;
-
- if (this.level().random.nextFloat() >= f) {
+ if ((!this.level().purpurConfig.shulkerSpawnFromBulletRequireOpenLid || !this.isClosed()) && this.teleportSomewhere()) {
+ // Purpur start
+ float chance = this.level().purpurConfig.shulkerSpawnFromBulletBaseChance;
+ if (!this.level().purpurConfig.shulkerSpawnFromBulletNearbyEquation.isBlank()) {
+ int nearby = this.level().getEntities((EntityTypeTest) EntityType.SHULKER, axisalignedbb.inflate(this.level().purpurConfig.shulkerSpawnFromBulletNearbyRange), Entity::isAlive).size();
+ try {
+ chance -= ((Number) scriptEngine.eval("let nearby = " + nearby + "; " + this.level().purpurConfig.shulkerSpawnFromBulletNearbyEquation)).floatValue();
+ } catch (javax.script.ScriptException e) {
+ e.printStackTrace();
+ chance -= (nearby - 1) / 5.0F;
+ }
+ }
+ if (this.level().random.nextFloat() <= chance) {
Shulker entityshulker = (Shulker) EntityType.SHULKER.create(this.level());
+ // Purpur end
if (entityshulker != null) {
entityshulker.setVariant(this.getVariant());
@@ -628,7 +637,7 @@ public class Shulker extends AbstractGolem implements VariantHolder<Optional<Dye
@Override
public Optional<DyeColor> getVariant() {
- return Optional.ofNullable(this.getColor());
+ return Optional.ofNullable(this.level().purpurConfig.shulkerSpawnFromBulletRandomColor ? DyeColor.random(this.level().random) : this.getColor()); // Purpur
}
@Nullable
diff --git a/src/main/java/net/minecraft/world/item/DyeColor.java b/src/main/java/net/minecraft/world/item/DyeColor.java
index 0d04a0107bd1a8a2b9aeb4be55025cd554e8fb79..a050d76233e179a1456b83ccc02bb9a55d1cec84 100644
--- a/src/main/java/net/minecraft/world/item/DyeColor.java
+++ b/src/main/java/net/minecraft/world/item/DyeColor.java
@@ -103,4 +103,10 @@ public enum DyeColor implements StringRepresentable {
public String getSerializedName() {
return this.name;
}
+
+ // Purpur start
+ public static DyeColor random(net.minecraft.util.RandomSource random) {
+ return values()[random.nextInt(values().length)];
+ }
+ // Purpur end
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index a5bea4b6d19d84bbab2adda8c7ba3e5f65b817c0..92cd2be5ce7d0a064cfa7f12802d4ffbd7e060d7 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1980,6 +1980,11 @@ public class PurpurWorldConfig {
public double shulkerMaxHealth = 30.0D;
public double shulkerScale = 1.0D;
public boolean shulkerTakeDamageFromWater = false;
+ public float shulkerSpawnFromBulletBaseChance = 1.0F;
+ public boolean shulkerSpawnFromBulletRequireOpenLid = true;
+ public double shulkerSpawnFromBulletNearbyRange = 8.0D;
+ public String shulkerSpawnFromBulletNearbyEquation = "(nearby - 1) / 5.0";
+ public boolean shulkerSpawnFromBulletRandomColor = false;
private void shulkerSettings() {
shulkerRidable = getBoolean("mobs.shulker.ridable", shulkerRidable);
shulkerRidableInWater = getBoolean("mobs.shulker.ridable-in-water", shulkerRidableInWater);
@@ -1992,6 +1997,11 @@ public class PurpurWorldConfig {
shulkerMaxHealth = getDouble("mobs.shulker.attributes.max_health", shulkerMaxHealth);
shulkerScale = Mth.clamp(getDouble("mobs.shulker.attributes.scale", shulkerScale), 0.0625D, Shulker.MAX_SCALE);
shulkerTakeDamageFromWater = getBoolean("mobs.shulker.takes-damage-from-water", shulkerTakeDamageFromWater);
+ shulkerSpawnFromBulletBaseChance = (float) getDouble("mobs.shulker.spawn-from-bullet.base-chance", shulkerSpawnFromBulletBaseChance);
+ shulkerSpawnFromBulletRequireOpenLid = getBoolean("mobs.shulker.spawn-from-bullet.require-open-lid", shulkerSpawnFromBulletRequireOpenLid);
+ shulkerSpawnFromBulletNearbyRange = getDouble("mobs.shulker.spawn-from-bullet.nearby-range", shulkerSpawnFromBulletNearbyRange);
+ shulkerSpawnFromBulletNearbyEquation = getString("mobs.shulker.spawn-from-bullet.nearby-equation", shulkerSpawnFromBulletNearbyEquation);
+ shulkerSpawnFromBulletRandomColor = getBoolean("mobs.shulker.spawn-from-bullet.random-color", shulkerSpawnFromBulletRandomColor);
}
public boolean silverfishRidable = 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: Mon, 28 Jun 2021 14:07:35 -0500
Subject: [PATCH] Eating glow berries adds glow effect
diff --git a/src/main/java/net/minecraft/world/item/Items.java b/src/main/java/net/minecraft/world/item/Items.java
index 4eef61323ba54f513e6f251ef7c804b2c91ff477..6b2235281dca67a80cb651e9f8e9bf2556979276 100644
--- a/src/main/java/net/minecraft/world/item/Items.java
+++ b/src/main/java/net/minecraft/world/item/Items.java
@@ -1919,7 +1919,7 @@ public class Items {
"sweet_berries", new ItemNameBlockItem(Blocks.SWEET_BERRY_BUSH, new Item.Properties().food(Foods.SWEET_BERRIES))
);
public static final Item GLOW_BERRIES = registerItem(
- "glow_berries", new ItemNameBlockItem(Blocks.CAVE_VINES, new Item.Properties().food(Foods.GLOW_BERRIES))
+ "glow_berries", new org.purpurmc.purpur.item.GlowBerryItem(Blocks.CAVE_VINES, new Item.Properties().food(Foods.GLOW_BERRIES)) // Purpur
);
public static final Item CAMPFIRE = registerBlock(Blocks.CAMPFIRE, settings -> settings.component(DataComponents.CONTAINER, ItemContainerContents.EMPTY));
public static final Item SOUL_CAMPFIRE = registerBlock(
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 92cd2be5ce7d0a064cfa7f12802d4ffbd7e060d7..d82bba5a4c729c69882354d9e3ca65b36a40c1b3 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -213,6 +213,7 @@ public class PurpurWorldConfig {
public int enderPearlCooldown = 20;
public int enderPearlCooldownCreative = 20;
public float enderPearlEndermiteChance = 0.05F;
+ public int glowBerriesEatGlowDuration = 0;
private void itemSettings() {
itemImmuneToCactus.clear();
getList("gameplay-mechanics.item.immune.cactus", new ArrayList<>()).forEach(key -> {
@@ -258,6 +259,7 @@ public class PurpurWorldConfig {
enderPearlCooldown = getInt("gameplay-mechanics.item.ender-pearl.cooldown", enderPearlCooldown);
enderPearlCooldownCreative = getInt("gameplay-mechanics.item.ender-pearl.creative-cooldown", enderPearlCooldownCreative);
enderPearlEndermiteChance = (float) getDouble("gameplay-mechanics.item.ender-pearl.endermite-spawn-chance", enderPearlEndermiteChance);
+ glowBerriesEatGlowDuration = getInt("gameplay-mechanics.item.glow_berries.eat-glow-duration", glowBerriesEatGlowDuration);
}
public double minecartMaxSpeed = 0.4D;
diff --git a/src/main/java/org/purpurmc/purpur/item/GlowBerryItem.java b/src/main/java/org/purpurmc/purpur/item/GlowBerryItem.java
new file mode 100644
index 0000000000000000000000000000000000000000..7f526883495b3222746de3d0442e9e4fb5107036
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/item/GlowBerryItem.java
@@ -0,0 +1,26 @@
+package org.purpurmc.purpur.item;
+
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.effect.MobEffectInstance;
+import net.minecraft.world.effect.MobEffects;
+import net.minecraft.world.entity.LivingEntity;
+import net.minecraft.world.item.ItemNameBlockItem;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.level.Level;
+import net.minecraft.world.level.block.Block;
+import org.bukkit.event.entity.EntityPotionEffectEvent;
+
+public class GlowBerryItem extends ItemNameBlockItem {
+ public GlowBerryItem(Block block, Properties settings) {
+ super(block, settings);
+ }
+
+ @Override
+ public ItemStack finishUsingItem(ItemStack stack, Level world, LivingEntity user) {
+ ItemStack result = super.finishUsingItem(stack, world, user);
+ if (world.purpurConfig.glowBerriesEatGlowDuration > 0 && user instanceof ServerPlayer player) {
+ player.addEffect(new MobEffectInstance(MobEffects.GLOWING, world.purpurConfig.glowBerriesEatGlowDuration), EntityPotionEffectEvent.Cause.FOOD);
+ }
+ return result;
+ }
+}

View File

@@ -1,47 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 12emin34 <macanovic.emin@gmail.com>
Date: Fri, 25 Jun 2021 13:56:15 +0200
Subject: [PATCH] Option to make drowned break doors
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 370f1b76c002f7cecf596767db717da51b2990f8..994dee36ce3aad3a0ef6a06bcaf555bdd434a0cd 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Drowned.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Drowned.java
@@ -126,6 +126,7 @@ public class Drowned extends Zombie implements RangedAttackMob {
this.goalSelector.addGoal(2, new Drowned.DrownedAttackGoal(this, 1.0D, false));
this.goalSelector.addGoal(5, new Drowned.DrownedGoToBeachGoal(this, 1.0D));
this.goalSelector.addGoal(6, new Drowned.DrownedSwimUpGoal(this, 1.0D, this.level().getSeaLevel()));
+ if (level().purpurConfig.drownedBreakDoors) this.goalSelector.addGoal(6, new net.minecraft.world.entity.ai.goal.MoveThroughVillageGoal(this, 1.0D, true, 4, this::canBreakDoors));
this.goalSelector.addGoal(7, new RandomStrollGoal(this, 1.0D));
this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[]{Drowned.class})).setAlertOthers(ZombifiedPiglin.class));
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, this::okTarget));
@@ -175,7 +176,7 @@ public class Drowned extends Zombie implements RangedAttackMob {
@Override
public boolean supportsBreakDoorGoal() {
- return false;
+ return level().purpurConfig.drownedBreakDoors ? true : false;
}
@Override
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index d82bba5a4c729c69882354d9e3ca65b36a40c1b3..0444b0787d1a8aeef564dc927a85431e56b6ccd2 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1068,6 +1068,7 @@ public class PurpurWorldConfig {
public double drownedJockeyChance = 0.05D;
public boolean drownedJockeyTryExistingChickens = true;
public boolean drownedTakeDamageFromWater = false;
+ public boolean drownedBreakDoors = false;
private void drownedSettings() {
drownedRidable = getBoolean("mobs.drowned.ridable", drownedRidable);
drownedRidableInWater = getBoolean("mobs.drowned.ridable-in-water", drownedRidableInWater);
@@ -1084,6 +1085,7 @@ public class PurpurWorldConfig {
drownedJockeyChance = getDouble("mobs.drowned.jockey.chance", drownedJockeyChance);
drownedJockeyTryExistingChickens = getBoolean("mobs.drowned.jockey.try-existing-chickens", drownedJockeyTryExistingChickens);
drownedTakeDamageFromWater = getBoolean("mobs.drowned.takes-damage-from-water", drownedTakeDamageFromWater);
+ drownedBreakDoors = getBoolean("mobs.drowned.can-break-doors", drownedBreakDoors);
}
public boolean elderGuardianRidable = false;

View File

@@ -1,33 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Tue, 29 Jun 2021 23:44:36 -0400
Subject: [PATCH] Configurable hunger starvation damage
diff --git a/src/main/java/net/minecraft/world/food/FoodData.java b/src/main/java/net/minecraft/world/food/FoodData.java
index b702b7270fae8fafc39588fbc39b4e0014809047..842a908051bdf6c5f0ef8ce3ac84a7ce210500b5 100644
--- a/src/main/java/net/minecraft/world/food/FoodData.java
+++ b/src/main/java/net/minecraft/world/food/FoodData.java
@@ -107,7 +107,7 @@ public class FoodData {
++this.tickTimer;
if (this.tickTimer >= this.starvationRate) { // CraftBukkit - add regen rate manipulation
if (player.getHealth() > 10.0F || enumdifficulty == Difficulty.HARD || player.getHealth() > 1.0F && enumdifficulty == Difficulty.NORMAL) {
- player.hurt(player.damageSources().starve(), 1.0F);
+ player.hurt(player.damageSources().starve(), player.level().purpurConfig.hungerStarvationDamage); // Purpur
}
this.tickTimer = 0;
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 0444b0787d1a8aeef564dc927a85431e56b6ccd2..39630c8b603970e9b3b34028d0cc75bda18de053 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -2688,4 +2688,9 @@ public class PurpurWorldConfig {
zombifiedPiglinCountAsPlayerKillWhenAngry = getBoolean("mobs.zombified_piglin.count-as-player-kill-when-angry", zombifiedPiglinCountAsPlayerKillWhenAngry);
zombifiedPiglinTakeDamageFromWater = getBoolean("mobs.zombified_piglin.takes-damage-from-water", zombifiedPiglinTakeDamageFromWater);
}
+
+ public float hungerStarvationDamage = 1.0F;
+ private void hungerSettings() {
+ hungerStarvationDamage = (float) getDouble("hunger.starvation-damage", hungerStarvationDamage);
+ }
}

View File

@@ -1,22 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Mon, 28 Jun 2021 13:33:12 -0500
Subject: [PATCH] Enhance SysoutCatcher
diff --git a/src/main/java/io/papermc/paper/logging/SysoutCatcher.java b/src/main/java/io/papermc/paper/logging/SysoutCatcher.java
index a8e813ca89b033f061e695288b3383bdcf128531..1ab65af9359d19530bba7f985a604d2a430ee234 100644
--- a/src/main/java/io/papermc/paper/logging/SysoutCatcher.java
+++ b/src/main/java/io/papermc/paper/logging/SysoutCatcher.java
@@ -54,9 +54,9 @@ public final class SysoutCatcher {
final JavaPlugin plugin = JavaPlugin.getProvidingPlugin(clazz);
// Instead of just printing the message, send it to the plugin's logger
- plugin.getLogger().log(this.level, this.prefix + line);
+ plugin.getLogger().log(this.level, /*this.prefix +*/ line); // Purpur - prefix not needed
- if (SysoutCatcher.SUPPRESS_NAGS) {
+ if (true || SysoutCatcher.SUPPRESS_NAGS) { // Purpur - nagging is annoying
return;
}
if (SysoutCatcher.NAG_INTERVAL > 0 || SysoutCatcher.NAG_TIMEOUT > 0) {

View File

@@ -1,143 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 1 Jul 2021 15:48:02 -0500
Subject: [PATCH] Add uptime command
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
index 286f141255984dddbc3252304d6c11b0647cbbf4..af5246b966f2322febb804a85e167ff580d2ab25 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
@@ -253,6 +253,7 @@ public class Commands {
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
+ org.purpurmc.purpur.command.UptimeCommand.register(this.dispatcher); // Purpur
org.purpurmc.purpur.command.TPSBarCommand.register(this.dispatcher); // Purpur
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index b14bfa10927c1e0e93f1c3515947077f11eb3ece..7e7f66ab202e5ac3bd8f91ed0ab1db51c2679101 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -304,6 +304,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public OptionSet options;
public org.bukkit.command.ConsoleCommandSender console;
public static int currentTick; // Paper - improve tick loop
+ public static final long startTimeMillis = System.currentTimeMillis();
public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
public int autosavePeriod;
// Paper - don't store the vanilla dispatcher
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index 3ec02424c0c9a9210cbcbd5f2a0c388d344f1019..a914c844c0d4f1e80c40c2798f5e24364778fde9 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -186,6 +186,7 @@ public class PurpurConfig {
public static String pingCommandOutput = "<green>%s's ping is %sms";
public static String tpsbarCommandOutput = "<green>Tpsbar toggled <onoff> for <target>";
public static String dontRunWithScissors = "<red><italic>Don't run with scissors!";
+ public static String uptimeCommandOutput = "<green>Server uptime is <uptime>";
public static String unverifiedUsername = "default";
private static void messages() {
cannotRideMob = getString("settings.messages.cannot-ride-mob", cannotRideMob);
@@ -199,6 +200,7 @@ public class PurpurConfig {
pingCommandOutput = getString("settings.messages.ping-command-output", pingCommandOutput);
tpsbarCommandOutput = getString("settings.messages.tpsbar-command-output", tpsbarCommandOutput);
dontRunWithScissors = getString("settings.messages.dont-run-with-scissors", dontRunWithScissors);
+ uptimeCommandOutput = getString("settings.messages.uptime-command-output", uptimeCommandOutput);
unverifiedUsername = getString("settings.messages.unverified-username", unverifiedUsername);
}
@@ -251,6 +253,15 @@ public class PurpurConfig {
public static int commandTPSBarTickInterval = 20;
public static boolean commandGamemodeRequiresPermission = false;
public static boolean hideHiddenPlayersFromEntitySelector = false;
+ public static String uptimeFormat = "<days><hours><minutes><seconds>";
+ public static String uptimeDay = "%02d day, ";
+ public static String uptimeDays = "%02d days, ";
+ public static String uptimeHour = "%02d hour, ";
+ public static String uptimeHours = "%02d hours, ";
+ public static String uptimeMinute = "%02d minute, and ";
+ public static String uptimeMinutes = "%02d minutes, and ";
+ public static String uptimeSecond = "%02d second";
+ public static String uptimeSeconds = "%02d seconds";
private static void commandSettings() {
commandTPSBarTitle = getString("settings.command.tpsbar.title", commandTPSBarTitle);
commandTPSBarProgressOverlay = BossBar.Overlay.valueOf(getString("settings.command.tpsbar.overlay", commandTPSBarProgressOverlay.name()));
@@ -264,6 +275,15 @@ public class PurpurConfig {
commandTPSBarTickInterval = getInt("settings.command.tpsbar.tick-interval", commandTPSBarTickInterval);
commandGamemodeRequiresPermission = getBoolean("settings.command.gamemode.requires-specific-permission", commandGamemodeRequiresPermission);
hideHiddenPlayersFromEntitySelector = getBoolean("settings.command.hide-hidden-players-from-entity-selector", hideHiddenPlayersFromEntitySelector);
+ uptimeFormat = getString("settings.command.uptime.format", uptimeFormat);
+ uptimeDay = getString("settings.command.uptime.day", uptimeDay);
+ uptimeDays = getString("settings.command.uptime.days", uptimeDays);
+ uptimeHour = getString("settings.command.uptime.hour", uptimeHour);
+ uptimeHours = getString("settings.command.uptime.hours", uptimeHours);
+ uptimeMinute = getString("settings.command.uptime.minute", uptimeMinute);
+ uptimeMinutes = getString("settings.command.uptime.minutes", uptimeMinutes);
+ uptimeSecond = getString("settings.command.uptime.second", uptimeSecond);
+ uptimeSeconds = getString("settings.command.uptime.seconds", uptimeSeconds);
}
public static int barrelRows = 3;
diff --git a/src/main/java/org/purpurmc/purpur/command/UptimeCommand.java b/src/main/java/org/purpurmc/purpur/command/UptimeCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..4bb475099bcf8f05d5f1474e7fbf29c57c2c40cd
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/command/UptimeCommand.java
@@ -0,0 +1,55 @@
+package org.purpurmc.purpur.command;
+
+import com.mojang.brigadier.CommandDispatcher;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.minimessage.MiniMessage;
+import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
+import net.minecraft.commands.CommandSourceStack;
+import net.minecraft.commands.Commands;
+import net.minecraft.server.MinecraftServer;
+import org.purpurmc.purpur.PurpurConfig;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
+
+public class UptimeCommand {
+ public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
+ dispatcher.register(Commands.literal("uptime")
+ .requires((listener) -> listener.hasPermission(2, "bukkit.command.uptime"))
+ .executes((context) -> execute(context.getSource()))
+ );
+ }
+
+ private static int execute(CommandSourceStack sender) {
+ Data data = new Data();
+
+ data.format = PurpurConfig.uptimeFormat;
+ data.hide = true;
+ data.millis = System.currentTimeMillis() - MinecraftServer.startTimeMillis;
+
+ process(data, "<days>", PurpurConfig.uptimeDay, PurpurConfig.uptimeDays, TimeUnit.DAYS, TimeUnit.MILLISECONDS::toDays);
+ process(data, "<hours>", PurpurConfig.uptimeHour, PurpurConfig.uptimeHours, TimeUnit.HOURS, TimeUnit.MILLISECONDS::toHours);
+ process(data, "<minutes>", PurpurConfig.uptimeMinute, PurpurConfig.uptimeMinutes, TimeUnit.MINUTES, TimeUnit.MILLISECONDS::toMinutes);
+ data.hide = false; // never hide seconds
+ process(data, "<seconds>", PurpurConfig.uptimeSecond, PurpurConfig.uptimeSeconds, TimeUnit.SECONDS, TimeUnit.MILLISECONDS::toSeconds);
+
+ Component output = MiniMessage.miniMessage().deserialize(PurpurConfig.uptimeCommandOutput, Placeholder.unparsed("uptime", data.format));
+ sender.sendSuccess(output, false);
+ return 1;
+ }
+
+ private static void process(Data data, String replace, String singular, String plural, TimeUnit unit, Function<Long, Long> func) {
+ if (data.format.contains(replace)) {
+ long val = func.apply(data.millis);
+ if (data.hide) data.hide = val == 0;
+ if (!data.hide) data.millis -= unit.toMillis(val);
+ data.format = data.format.replace(replace, data.hide ? "" : String.format(val == 1 ? singular : plural, val));
+ }
+ }
+
+ private static class Data {
+ String format;
+ boolean hide;
+ long millis;
+ }
+}

View File

@@ -1,601 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Fri, 2 Jul 2021 20:54:29 -0500
Subject: [PATCH] Tool actionable options
diff --git a/src/main/java/net/minecraft/world/item/AxeItem.java b/src/main/java/net/minecraft/world/item/AxeItem.java
index f005ea92449cf5e249ff64f4791c3bc6b8635528..ade1a0dac14bb3adc26bb103fc0ce9629fe973c6 100644
--- a/src/main/java/net/minecraft/world/item/AxeItem.java
+++ b/src/main/java/net/minecraft/world/item/AxeItem.java
@@ -60,13 +60,15 @@ public class AxeItem extends DiggerItem {
if (playerHasShieldUseIntent(context)) {
return InteractionResult.PASS;
} else {
- Optional<BlockState> optional = this.evaluateNewBlockState(level, blockPos, player, level.getBlockState(blockPos));
+ Optional<org.purpurmc.purpur.tool.Actionable> optional = this.evaluateActionable(level, blockPos, player, level.getBlockState(blockPos)); // Purpur
if (optional.isEmpty()) {
return InteractionResult.PASS;
} else {
+ org.purpurmc.purpur.tool.Actionable actionable = optional.get(); // Purpur
+ BlockState state = actionable.into().withPropertiesOf(level.getBlockState(blockPos)); // Purpur
ItemStack itemStack = context.getItemInHand();
// Paper start - EntityChangeBlockEvent
- if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, blockPos, optional.get())) {
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, blockPos, state)) { // Purpur
return InteractionResult.PASS;
}
// Paper end
@@ -74,13 +76,20 @@ public class AxeItem extends DiggerItem {
CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger((ServerPlayer)player, blockPos, itemStack);
}
- level.setBlock(blockPos, optional.get(), 11);
- level.gameEvent(GameEvent.BLOCK_CHANGE, blockPos, GameEvent.Context.of(player, optional.get()));
+ // Purpur start
+ level.setBlock(blockPos, state, 11);
+ actionable.drops().forEach((drop, chance) -> {
+ if (level.random.nextDouble() < chance) {
+ Block.popResourceFromFace(level, blockPos, context.getClickedFace(), new ItemStack(drop));
+ }
+ });
+ level.gameEvent(GameEvent.BLOCK_CHANGE, blockPos, GameEvent.Context.of(player, state));
+ // Purpur end
if (player != null) {
itemStack.hurtAndBreak(1, player, LivingEntity.getSlotForHand(context.getHand()));
}
- return InteractionResult.sidedSuccess(level.isClientSide);
+ return InteractionResult.SUCCESS; // Purpur - force arm swing
}
}
}
@@ -90,22 +99,24 @@ public class AxeItem extends DiggerItem {
return context.getHand().equals(InteractionHand.MAIN_HAND) && player.getOffhandItem().is(Items.SHIELD) && !player.isSecondaryUseActive();
}
- private Optional<BlockState> evaluateNewBlockState(Level world, BlockPos pos, @Nullable Player player, BlockState state) {
- Optional<BlockState> optional = this.getStripped(state);
+ private Optional<org.purpurmc.purpur.tool.Actionable> evaluateActionable(Level world, BlockPos pos, @Nullable Player player, BlockState state) { // Purpur
+ Optional<org.purpurmc.purpur.tool.Actionable> optional = Optional.ofNullable(world.purpurConfig.axeStrippables.get(state.getBlock())); // Purpur
if (optional.isPresent()) {
- world.playSound(player, pos, SoundEvents.AXE_STRIP, SoundSource.BLOCKS, 1.0F, 1.0F);
+ world.playSound(STRIPPABLES.containsKey(state.getBlock()) ? player : null, pos, SoundEvents.AXE_STRIP, SoundSource.BLOCKS, 1.0F, 1.0F); // Purpur - force sound
return optional;
} else {
- Optional<BlockState> optional2 = WeatheringCopper.getPrevious(state);
+ Optional<org.purpurmc.purpur.tool.Actionable> optional2 = Optional.ofNullable(world.purpurConfig.axeWeatherables.get(state.getBlock())); // Purpur
if (optional2.isPresent()) {
- world.playSound(player, pos, SoundEvents.AXE_SCRAPE, SoundSource.BLOCKS, 1.0F, 1.0F);
+ world.playSound(WeatheringCopper.getPrevious(state).isPresent() ? player : null, pos, SoundEvents.AXE_SCRAPE, SoundSource.BLOCKS, 1.0F, 1.0F); // Purpur - force sound
world.levelEvent(player, 3005, pos, 0);
return optional2;
} else {
- Optional<BlockState> optional3 = Optional.ofNullable(HoneycombItem.WAX_OFF_BY_BLOCK.get().get(state.getBlock()))
- .map(block -> block.withPropertiesOf(state));
+ // Purpur start
+ Optional<org.purpurmc.purpur.tool.Actionable> optional3 = Optional.ofNullable(world.purpurConfig.axeWaxables.get(state.getBlock()));
+ // .map(block -> block.withPropertiesOf(state));
+ // Purpur end
if (optional3.isPresent()) {
- world.playSound(player, pos, SoundEvents.AXE_WAX_OFF, SoundSource.BLOCKS, 1.0F, 1.0F);
+ world.playSound(HoneycombItem.WAX_OFF_BY_BLOCK.get().containsKey(state.getBlock()) ? player : null, pos, SoundEvents.AXE_WAX_OFF, SoundSource.BLOCKS, 1.0F, 1.0F); // Purpur - force sound
world.levelEvent(player, 3004, pos, 0);
return optional3;
} else {
diff --git a/src/main/java/net/minecraft/world/item/HoeItem.java b/src/main/java/net/minecraft/world/item/HoeItem.java
index 06497b5141e611cc7a1b6030a7b9c54b5c4eda06..28df1b3230762e52b5458ac93a85c9a5d41eb6a6 100644
--- a/src/main/java/net/minecraft/world/item/HoeItem.java
+++ b/src/main/java/net/minecraft/world/item/HoeItem.java
@@ -46,15 +46,23 @@ public class HoeItem extends DiggerItem {
public InteractionResult useOn(UseOnContext context) {
Level level = context.getLevel();
BlockPos blockPos = context.getClickedPos();
- Pair<Predicate<UseOnContext>, Consumer<UseOnContext>> pair = TILLABLES.get(level.getBlockState(blockPos).getBlock());
- if (pair == null) {
- return InteractionResult.PASS;
- } else {
- Predicate<UseOnContext> predicate = pair.getFirst();
- Consumer<UseOnContext> consumer = pair.getSecond();
+ // Purpur start
+ Block clickedBlock = level.getBlockState(blockPos).getBlock();
+ var tillable = level.purpurConfig.hoeTillables.get(clickedBlock);
+ if (tillable == null) { return InteractionResult.PASS; } else {
+ Predicate<UseOnContext> predicate = tillable.condition().predicate();
+ Consumer<UseOnContext> consumer = (ctx) -> {
+ level.setBlock(blockPos, tillable.into().defaultBlockState(), 11);
+ tillable.drops().forEach((drop, chance) -> {
+ if (level.random.nextDouble() < chance) {
+ Block.popResourceFromFace(level, blockPos, ctx.getClickedFace(), new ItemStack(drop));
+ }
+ });
+ };
+ // Purpur end
if (predicate.test(context)) {
Player player = context.getPlayer();
- level.playSound(player, blockPos, SoundEvents.HOE_TILL, SoundSource.BLOCKS, 1.0F, 1.0F);
+ if (!TILLABLES.containsKey(clickedBlock)) level.playSound(null, blockPos, SoundEvents.HOE_TILL, SoundSource.BLOCKS, 1.0F, 1.0F); // Purpur - force sound
if (!level.isClientSide) {
consumer.accept(context);
if (player != null) {
@@ -62,7 +70,7 @@ public class HoeItem extends DiggerItem {
}
}
- return InteractionResult.sidedSuccess(level.isClientSide);
+ return InteractionResult.SUCCESS; // Purpur - force arm swing
} else {
return InteractionResult.PASS;
}
diff --git a/src/main/java/net/minecraft/world/item/ShovelItem.java b/src/main/java/net/minecraft/world/item/ShovelItem.java
index 24f6a158e4759aac3be8da4cf5e0d40bd295355b..6b7dbb570f8a698c87c6bce992d84d87b55176e6 100644
--- a/src/main/java/net/minecraft/world/item/ShovelItem.java
+++ b/src/main/java/net/minecraft/world/item/ShovelItem.java
@@ -47,9 +47,12 @@ public class ShovelItem extends DiggerItem {
BlockState blockState2 = FLATTENABLES.get(blockState.getBlock());
BlockState blockState3 = null;
Runnable afterAction = null; // Paper
- if (blockState2 != null && level.getBlockState(blockPos.above()).isAir()) {
- afterAction = () -> level.playSound(player, blockPos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F); // Paper
- blockState3 = blockState2;
+ // Purpur start
+ var flattenable = level.purpurConfig.shovelFlattenables.get(blockState.getBlock());
+ if (flattenable != null && level.getBlockState(blockPos.above()).isAir()) {
+ afterAction = () -> {if (!FLATTENABLES.containsKey(blockState.getBlock())) level.playSound(null, blockPos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F);}; // Paper
+ blockState3 = flattenable.into().defaultBlockState();
+ // Purpur end
} else if (blockState.getBlock() instanceof CampfireBlock && blockState.getValue(CampfireBlock.LIT)) {
afterAction = () -> { // Paper
if (!level.isClientSide()) {
@@ -76,7 +79,7 @@ public class ShovelItem extends DiggerItem {
}
}
- return InteractionResult.sidedSuccess(level.isClientSide);
+ return InteractionResult.SUCCESS; // Purpur - force arm swing
} else {
return InteractionResult.PASS;
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 39630c8b603970e9b3b34028d0cc75bda18de053..95b5106772a6701ecb0e60206871c139f215e487 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -463,6 +463,280 @@ public class PurpurWorldConfig {
snowballDamage = getInt("gameplay-mechanics.projectile-damage.snowball", snowballDamage);
}
+ public Map<Block, Strippable> axeStrippables = new HashMap<>();
+ public Map<Block, Waxable> axeWaxables = new HashMap<>();
+ public Map<Block, Weatherable> axeWeatherables = new HashMap<>();
+ public Map<Block, Tillable> hoeTillables = new HashMap<>();
+ public Map<Block, Flattenable> shovelFlattenables = new HashMap<>();
+ private void toolSettings() {
+ axeStrippables.clear();
+ axeWaxables.clear();
+ axeWeatherables.clear();
+ hoeTillables.clear();
+ shovelFlattenables.clear();
+ if (PurpurConfig.version < 18) {
+ ConfigurationSection section = PurpurConfig.config.getConfigurationSection("world-settings." + worldName + ".tools.hoe.tilling");
+ if (section != null) {
+ PurpurConfig.config.set("world-settings." + worldName + ".tools.hoe.tillables", section);
+ PurpurConfig.config.set("world-settings." + worldName + ".tools.hoe.tilling", null);
+ }
+ section = PurpurConfig.config.getConfigurationSection("world-settings.default.tools.hoe.tilling");
+ if (section != null) {
+ PurpurConfig.config.set("world-settings.default.tools.hoe.tillables", section);
+ PurpurConfig.config.set("world-settings.default.tools.hoe.tilling", null);
+ }
+ }
+ if (PurpurConfig.version < 29) {
+ PurpurConfig.config.set("world-settings.default.tools.axe.strippables.minecraft:mangrove_log", Map.of("into", "minecraft:stripped_mangrove_log", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.strippables.minecraft:mangrove_wood", Map.of("into", "minecraft:stripped_mangrove_wood", "drops", new HashMap<String, Double>()));
+ }
+ if (PurpurConfig.version < 32) {
+ PurpurConfig.config.set("world-settings.default.tools.axe.strippables.minecraft:cherry_log", Map.of("into", "minecraft:stripped_cherry_log", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.strippables.minecraft:cherry_wood", Map.of("into", "minecraft:stripped_cherry_wood", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.strippables.minecraft:bamboo_block", Map.of("into", "minecraft:stripped_bamboo_block", "drops", new HashMap<String, Double>()));
+ }
+ if (PurpurConfig.version < 33) {
+ getList("gameplay-mechanics.shovel-turns-block-to-grass-path", new ArrayList<String>(){{
+ add("minecraft:coarse_dirt");
+ add("minecraft:dirt");
+ add("minecraft:grass_block");
+ add("minecraft:mycelium");
+ add("minecraft:podzol");
+ add("minecraft:rooted_dirt");
+ }}).forEach(key -> {
+ PurpurConfig.config.set("world-settings.default.tools.shovel.flattenables." + key.toString(), Map.of("into", "minecraft:dirt_path", "drops", new HashMap<String, Double>()));
+ });
+ set("gameplay-mechanics.shovel-turns-block-to-grass-path", null);
+ }
+ if (PurpurConfig.version < 34) {
+ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_chiseled_copper", Map.of("into", "minecraft:chiseled_copper", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_exposed_chiseled_copper", Map.of("into", "minecraft:exposed_chiseled_copper", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_weathered_chiseled_copper", Map.of("into", "minecraft:weathered_chiseled_copper", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_oxidized_chiseled_copper", Map.of("into", "minecraft:oxidized_chiseled_copper", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_copper_door", Map.of("into", "minecraft:copper_door", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_exposed_copper_door", Map.of("into", "minecraft:exposed_copper_door", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_weathered_copper_door", Map.of("into", "minecraft:weathered_copper_door", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_oxidized_copper_door", Map.of("into", "minecraft:oxidized_copper_door", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_copper_trapdoor", Map.of("into", "minecraft:copper_trapdoor", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_exposed_copper_trapdoor", Map.of("into", "minecraft:exposed_copper_trapdoor", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_weathered_copper_trapdoor", Map.of("into", "minecraft:weathered_copper_trapdoor", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_oxidized_copper_trapdoor", Map.of("into", "minecraft:oxidized_copper_trapdoor", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_copper_grate", Map.of("into", "minecraft:copper_grate", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_exposed_copper_grate", Map.of("into", "minecraft:exposed_copper_grate", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_weathered_copper_grate", Map.of("into", "minecraft:weathered_copper_grate", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_oxidized_copper_grate", Map.of("into", "minecraft:oxidized_copper_grate", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_copper_bulb", Map.of("into", "minecraft:copper_bulb", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_exposed_copper_bulb", Map.of("into", "minecraft:exposed_copper_bulb", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_weathered_copper_bulb", Map.of("into", "minecraft:weathered_copper_bulb", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.waxables.minecraft:waxed_oxidized_copper_bulb", Map.of("into", "minecraft:oxidized_copper_bulb", "drops", new HashMap<String, Double>()));
+
+ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:exposed_chiseled_copper", Map.of("into", "minecraft:chiseled_copper", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:weathered_chiseled_copper", Map.of("into", "minecraft:exposed_chiseled_copper", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:oxidized_chiseled_copper", Map.of("into", "minecraft:weathered_chiseled_copper", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:oxidized_cut_copper_stairs", Map.of("into", "minecraft:weathered_cut_copper_stairs", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:exposed_copper_door", Map.of("into", "minecraft:copper_door", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:weathered_copper_door", Map.of("into", "minecraft:exposed_copper_door", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:oxidized_copper_door", Map.of("into", "minecraft:weathered_copper_door", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:exposed_copper_trapdoor", Map.of("into", "minecraft:copper_trapdoor", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:weathered_copper_trapdoor", Map.of("into", "minecraft:exposed_copper_trapdoor", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:oxidized_copper_trapdoor", Map.of("into", "minecraft:weathered_copper_trapdoor", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:exposed_copper_grate", Map.of("into", "minecraft:copper_grate", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:weathered_copper_grate", Map.of("into", "minecraft:exposed_copper_grate", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:oxidized_copper_grate", Map.of("into", "minecraft:weathered_copper_grate", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:exposed_copper_bulb", Map.of("into", "minecraft:copper_bulb", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:weathered_copper_bulb", Map.of("into", "minecraft:exposed_copper_bulb", "drops", new HashMap<String, Double>()));
+ PurpurConfig.config.set("world-settings.default.tools.axe.weatherables.minecraft:oxidized_copper_bulb", Map.of("into", "minecraft:weathered_copper_bulb", "drops", new HashMap<String, Double>()));
+ }
+ getMap("tools.axe.strippables", Map.ofEntries(
+ Map.entry("minecraft:oak_wood", Map.of("into", "minecraft:stripped_oak_wood", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:oak_log", Map.of("into", "minecraft:stripped_oak_log", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:dark_oak_wood", Map.of("into", "minecraft:stripped_dark_oak_wood", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:dark_oak_log", Map.of("into", "minecraft:stripped_dark_oak_log", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:acacia_wood", Map.of("into", "minecraft:stripped_acacia_wood", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:acacia_log", Map.of("into", "minecraft:stripped_acacia_log", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:birch_wood", Map.of("into", "minecraft:stripped_birch_wood", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:birch_log", Map.of("into", "minecraft:stripped_birch_log", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:jungle_wood", Map.of("into", "minecraft:stripped_jungle_wood", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:jungle_log", Map.of("into", "minecraft:stripped_jungle_log", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:spruce_wood", Map.of("into", "minecraft:stripped_spruce_wood", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:spruce_log", Map.of("into", "minecraft:stripped_spruce_log", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:mangrove_wood", Map.of("into", "minecraft:stripped_mangrove_wood", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:mangrove_log", Map.of("into", "minecraft:stripped_mangrove_log", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:cherry_log", Map.of("into", "minecraft:stripped_cherry_log", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:cherry_wood", Map.of("into", "minecraft:stripped_cherry_wood", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:bamboo_block", Map.of("into", "minecraft:stripped_bamboo_block", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:warped_stem", Map.of("into", "minecraft:stripped_warped_stem", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:warped_hyphae", Map.of("into", "minecraft:stripped_warped_hyphae", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:crimson_stem", Map.of("into", "minecraft:stripped_crimson_stem", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:crimson_hyphae", Map.of("into", "minecraft:stripped_crimson_hyphae", "drops", new HashMap<String, Double>())))
+ ).forEach((blockId, obj) -> {
+ Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(blockId));
+ if (block == Blocks.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.axe.strippables`: " + blockId); return; }
+ if (!(obj instanceof Map<?, ?> map)) { PurpurConfig.log(Level.SEVERE, "Invalid yaml for `tools.axe.strippables." + blockId + "`"); return; }
+ String intoId = (String) map.get("into");
+ Block into = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(intoId));
+ if (into == Blocks.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.axe.strippables." + blockId + ".into`: " + intoId); return; }
+ Object dropsObj = map.get("drops");
+ if (!(dropsObj instanceof Map<?, ?> dropsMap)) { PurpurConfig.log(Level.SEVERE, "Invalid yaml for `tools.axe.strippables." + blockId + ".drops`"); return; }
+ Map<Item, Double> drops = new HashMap<>();
+ dropsMap.forEach((itemId, chance) -> {
+ Item item = BuiltInRegistries.ITEM.get(ResourceLocation.parse(itemId.toString()));
+ if (item == Items.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid item for `tools.axe.strippables." + blockId + ".drops`: " + itemId); return; }
+ drops.put(item, (double) chance);
+ });
+ axeStrippables.put(block, new Strippable(into, drops));
+ });
+ getMap("tools.axe.waxables", Map.ofEntries(
+ Map.entry("minecraft:waxed_copper_block", Map.of("into", "minecraft:copper_block", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_exposed_copper", Map.of("into", "minecraft:exposed_copper", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_weathered_copper", Map.of("into", "minecraft:weathered_copper", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_oxidized_copper", Map.of("into", "minecraft:oxidized_copper", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_cut_copper", Map.of("into", "minecraft:cut_copper", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_exposed_cut_copper", Map.of("into", "minecraft:exposed_cut_copper", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_weathered_cut_copper", Map.of("into", "minecraft:weathered_cut_copper", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_oxidized_cut_copper", Map.of("into", "minecraft:oxidized_cut_copper", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_cut_copper_slab", Map.of("into", "minecraft:cut_copper_slab", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_exposed_cut_copper_slab", Map.of("into", "minecraft:exposed_cut_copper_slab", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_weathered_cut_copper_slab", Map.of("into", "minecraft:weathered_cut_copper_slab", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_oxidized_cut_copper_slab", Map.of("into", "minecraft:oxidized_cut_copper_slab", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_cut_copper_stairs", Map.of("into", "minecraft:cut_copper_stairs", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_exposed_cut_copper_stairs", Map.of("into", "minecraft:exposed_cut_copper_stairs", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_weathered_cut_copper_stairs", Map.of("into", "minecraft:weathered_cut_copper_stairs", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_oxidized_cut_copper_stairs", Map.of("into", "minecraft:oxidized_cut_copper_stairs", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_chiseled_copper", Map.of("into", "minecraft:chiseled_copper", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_exposed_chiseled_copper", Map.of("into", "minecraft:exposed_chiseled_copper", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_weathered_chiseled_copper", Map.of("into", "minecraft:weathered_chiseled_copper", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_oxidized_chiseled_copper", Map.of("into", "minecraft:oxidized_chiseled_copper", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_copper_door", Map.of("into", "minecraft:copper_door", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_exposed_copper_door", Map.of("into", "minecraft:exposed_copper_door", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_weathered_copper_door", Map.of("into", "minecraft:weathered_copper_door", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_oxidized_copper_door", Map.of("into", "minecraft:oxidized_copper_door", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_copper_trapdoor", Map.of("into", "minecraft:copper_trapdoor", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_exposed_copper_trapdoor", Map.of("into", "minecraft:exposed_copper_trapdoor", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_weathered_copper_trapdoor", Map.of("into", "minecraft:weathered_copper_trapdoor", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_oxidized_copper_trapdoor", Map.of("into", "minecraft:oxidized_copper_trapdoor", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_copper_grate", Map.of("into", "minecraft:copper_grate", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_exposed_copper_grate", Map.of("into", "minecraft:exposed_copper_grate", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_weathered_copper_grate", Map.of("into", "minecraft:weathered_copper_grate", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_oxidized_copper_grate", Map.of("into", "minecraft:oxidized_copper_grate", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_copper_bulb", Map.of("into", "minecraft:copper_bulb", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_exposed_copper_bulb", Map.of("into", "minecraft:exposed_copper_bulb", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_weathered_copper_bulb", Map.of("into", "minecraft:weathered_copper_bulb", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:waxed_oxidized_copper_bulb", Map.of("into", "minecraft:oxidized_copper_bulb", "drops", new HashMap<String, Double>())))
+ ).forEach((blockId, obj) -> {
+ Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(blockId));
+ if (block == Blocks.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.axe.waxables`: " + blockId); return; }
+ if (!(obj instanceof Map<?, ?> map)) { PurpurConfig.log(Level.SEVERE, "Invalid yaml for `tools.axe.waxables." + blockId + "`"); return; }
+ String intoId = (String) map.get("into");
+ Block into = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(intoId));
+ if (into == Blocks.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.axe.waxables." + blockId + ".into`: " + intoId); return; }
+ Object dropsObj = map.get("drops");
+ if (!(dropsObj instanceof Map<?, ?> dropsMap)) { PurpurConfig.log(Level.SEVERE, "Invalid yaml for `tools.axe.waxables." + blockId + ".drops`"); return; }
+ Map<Item, Double> drops = new HashMap<>();
+ dropsMap.forEach((itemId, chance) -> {
+ Item item = BuiltInRegistries.ITEM.get(ResourceLocation.parse(itemId.toString()));
+ if (item == Items.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid item for `tools.axe.waxables." + blockId + ".drops`: " + itemId); return; }
+ drops.put(item, (double) chance);
+ });
+ axeWaxables.put(block, new Waxable(into, drops));
+ });
+ getMap("tools.axe.weatherables", Map.ofEntries(
+ Map.entry("minecraft:exposed_copper", Map.of("into", "minecraft:copper_block", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:weathered_copper", Map.of("into", "minecraft:exposed_copper", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:oxidized_copper", Map.of("into", "minecraft:weathered_copper", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:exposed_cut_copper", Map.of("into", "minecraft:cut_copper", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:weathered_cut_copper", Map.of("into", "minecraft:exposed_cut_copper", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:oxidized_cut_copper", Map.of("into", "minecraft:weathered_cut_copper", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:exposed_chiseled_copper", Map.of("into", "minecraft:chiseled_copper", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:weathered_chiseled_copper", Map.of("into", "minecraft:exposed_chiseled_copper", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:oxidized_chiseled_copper", Map.of("into", "minecraft:weathered_chiseled_copper", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:exposed_cut_copper_slab", Map.of("into", "minecraft:cut_copper_slab", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:weathered_cut_copper_slab", Map.of("into", "minecraft:exposed_cut_copper_slab", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:oxidized_cut_copper_slab", Map.of("into", "minecraft:weathered_cut_copper_slab", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:exposed_cut_copper_stairs", Map.of("into", "minecraft:cut_copper_stairs", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:weathered_cut_copper_stairs", Map.of("into", "minecraft:exposed_cut_copper_stairs", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:oxidized_cut_copper_stairs", Map.of("into", "minecraft:weathered_cut_copper_stairs", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:exposed_copper_door", Map.of("into", "minecraft:copper_door", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:weathered_copper_door", Map.of("into", "minecraft:exposed_copper_door", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:oxidized_copper_door", Map.of("into", "minecraft:weathered_copper_door", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:exposed_copper_trapdoor", Map.of("into", "minecraft:copper_trapdoor", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:weathered_copper_trapdoor", Map.of("into", "minecraft:exposed_copper_trapdoor", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:oxidized_copper_trapdoor", Map.of("into", "minecraft:weathered_copper_trapdoor", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:exposed_copper_grate", Map.of("into", "minecraft:copper_grate", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:weathered_copper_grate", Map.of("into", "minecraft:exposed_copper_grate", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:oxidized_copper_grate", Map.of("into", "minecraft:weathered_copper_grate", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:exposed_copper_bulb", Map.of("into", "minecraft:copper_bulb", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:weathered_copper_bulb", Map.of("into", "minecraft:exposed_copper_bulb", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:oxidized_copper_bulb", Map.of("into", "minecraft:weathered_copper_bulb", "drops", new HashMap<String, Double>())))
+ ).forEach((blockId, obj) -> {
+ Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(blockId));
+ if (block == Blocks.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.axe.weatherables`: " + blockId); return; }
+ if (!(obj instanceof Map<?, ?> map)) { PurpurConfig.log(Level.SEVERE, "Invalid yaml for `tools.axe.weatherables." + blockId + "`"); return; }
+ String intoId = (String) map.get("into");
+ Block into = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(intoId));
+ if (into == Blocks.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.axe.weatherables." + blockId + ".into`: " + intoId); return; }
+ Object dropsObj = map.get("drops");
+ if (!(dropsObj instanceof Map<?, ?> dropsMap)) { PurpurConfig.log(Level.SEVERE, "Invalid yaml for `tools.axe.weatherables." + blockId + ".drops`"); return; }
+ Map<Item, Double> drops = new HashMap<>();
+ dropsMap.forEach((itemId, chance) -> {
+ Item item = BuiltInRegistries.ITEM.get(ResourceLocation.parse(itemId.toString()));
+ if (item == Items.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid item for `tools.axe.weatherables." + blockId + ".drops`: " + itemId); return; }
+ drops.put(item, (double) chance);
+ });
+ axeWeatherables.put(block, new Weatherable(into, drops));
+ });
+ getMap("tools.hoe.tillables", Map.ofEntries(
+ Map.entry("minecraft:grass_block", Map.of("condition", "air_above", "into", "minecraft:farmland", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:dirt_path", Map.of("condition", "air_above", "into", "minecraft:farmland", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:dirt", Map.of("condition", "air_above", "into", "minecraft:farmland", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:coarse_dirt", Map.of("condition", "air_above", "into", "minecraft:dirt", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:rooted_dirt", Map.of("condition", "always", "into", "minecraft:dirt", "drops", Map.of("minecraft:hanging_roots", 1.0D))))
+ ).forEach((blockId, obj) -> {
+ Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(blockId));
+ if (block == Blocks.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.hoe.tillables`: " + blockId); return; }
+ if (!(obj instanceof Map<?, ?> map)) { PurpurConfig.log(Level.SEVERE, "Invalid yaml for `tools.hoe.tillables." + blockId + "`"); return; }
+ String conditionId = (String) map.get("condition");
+ Tillable.Condition condition = Tillable.Condition.get(conditionId);
+ if (condition == null) { PurpurConfig.log(Level.SEVERE, "Invalid condition for `tools.hoe.tillables." + blockId + ".condition`: " + conditionId); return; }
+ String intoId = (String) map.get("into");
+ Block into = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(intoId));
+ if (into == Blocks.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.hoe.tillables." + blockId + ".into`: " + intoId); return; }
+ Object dropsObj = map.get("drops");
+ if (!(dropsObj instanceof Map<?, ?> dropsMap)) { PurpurConfig.log(Level.SEVERE, "Invalid yaml for `tools.hoe.tillables." + blockId + ".drops`"); return; }
+ Map<Item, Double> drops = new HashMap<>();
+ dropsMap.forEach((itemId, chance) -> {
+ Item item = BuiltInRegistries.ITEM.get(ResourceLocation.parse(itemId.toString()));
+ if (item == Items.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid item for `tools.hoe.tillables." + blockId + ".drops`: " + itemId); return; }
+ drops.put(item, (double) chance);
+ });
+ hoeTillables.put(block, new Tillable(condition, into, drops));
+ });
+ getMap("tools.shovel.flattenables", Map.ofEntries(
+ Map.entry("minecraft:grass_block", Map.of("into", "minecraft:dirt_path", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:dirt", Map.of("into", "minecraft:dirt_path", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:podzol", Map.of("into", "minecraft:dirt_path", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:coarse_dirt", Map.of("into", "minecraft:dirt_path", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:mycelium", Map.of("into", "minecraft:dirt_path", "drops", new HashMap<String, Double>())),
+ Map.entry("minecraft:rooted_dirt", Map.of("into", "minecraft:dirt_path", "drops", new HashMap<String, Double>())))
+ ).forEach((blockId, obj) -> {
+ Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(blockId));
+ if (block == Blocks.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.shovel.flattenables`: " + blockId); return; }
+ if (!(obj instanceof Map<?, ?> map)) { PurpurConfig.log(Level.SEVERE, "Invalid yaml for `tools.shovel.flattenables." + blockId + "`"); return; }
+ String intoId = (String) map.get("into");
+ Block into = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(intoId));
+ if (into == Blocks.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid block for `tools.shovel.flattenables." + blockId + ".into`: " + intoId); return; }
+ Object dropsObj = map.get("drops");
+ if (!(dropsObj instanceof Map<?, ?> dropsMap)) { PurpurConfig.log(Level.SEVERE, "Invalid yaml for `tools.shovel.flattenables." + blockId + ".drops`"); return; }
+ Map<Item, Double> drops = new HashMap<>();
+ dropsMap.forEach((itemId, chance) -> {
+ Item item = BuiltInRegistries.ITEM.get(ResourceLocation.parse(itemId.toString()));
+ if (item == Items.AIR) { PurpurConfig.log(Level.SEVERE, "Invalid item for `tools.shovel.flattenables." + blockId + ".drops`: " + itemId); return; }
+ drops.put(item, (double) chance);
+ });
+ shovelFlattenables.put(block, new Flattenable(into, drops));
+ });
+ }
+
public boolean anvilAllowColors = false;
public boolean anvilColorsUseMiniMessage;
private void anvilSettings() {
diff --git a/src/main/java/org/purpurmc/purpur/tool/Actionable.java b/src/main/java/org/purpurmc/purpur/tool/Actionable.java
new file mode 100644
index 0000000000000000000000000000000000000000..e18c37f06730da9d3055d5215e813b1477c1e70e
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/tool/Actionable.java
@@ -0,0 +1,24 @@
+package org.purpurmc.purpur.tool;
+
+import net.minecraft.world.item.Item;
+import net.minecraft.world.level.block.Block;
+
+import java.util.Map;
+
+public abstract class Actionable {
+ private final Block into;
+ private final Map<Item, Double> drops;
+
+ public Actionable(Block into, Map<Item, Double> drops) {
+ this.into = into;
+ this.drops = drops;
+ }
+
+ public Block into() {
+ return into;
+ }
+
+ public Map<Item, Double> drops() {
+ return drops;
+ }
+}
diff --git a/src/main/java/org/purpurmc/purpur/tool/Flattenable.java b/src/main/java/org/purpurmc/purpur/tool/Flattenable.java
new file mode 100644
index 0000000000000000000000000000000000000000..345d4ee4ff0b78bd1050959711a4f5d16a5e8aee
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/tool/Flattenable.java
@@ -0,0 +1,12 @@
+package org.purpurmc.purpur.tool;
+
+import net.minecraft.world.item.Item;
+import net.minecraft.world.level.block.Block;
+
+import java.util.Map;
+
+public class Flattenable extends Actionable {
+ public Flattenable(Block into, Map<Item, Double> drops) {
+ super(into, drops);
+ }
+}
diff --git a/src/main/java/org/purpurmc/purpur/tool/Strippable.java b/src/main/java/org/purpurmc/purpur/tool/Strippable.java
new file mode 100644
index 0000000000000000000000000000000000000000..bf5402214f41af9c09bd6c5c4f45d330516d742e
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/tool/Strippable.java
@@ -0,0 +1,12 @@
+package org.purpurmc.purpur.tool;
+
+import net.minecraft.world.item.Item;
+import net.minecraft.world.level.block.Block;
+
+import java.util.Map;
+
+public class Strippable extends Actionable {
+ public Strippable(Block into, Map<Item, Double> drops) {
+ super(into, drops);
+ }
+}
diff --git a/src/main/java/org/purpurmc/purpur/tool/Tillable.java b/src/main/java/org/purpurmc/purpur/tool/Tillable.java
new file mode 100644
index 0000000000000000000000000000000000000000..715f6dd44480347eebced43c11bc364e05727498
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/tool/Tillable.java
@@ -0,0 +1,50 @@
+package org.purpurmc.purpur.tool;
+
+import net.minecraft.world.item.HoeItem;
+import net.minecraft.world.item.Item;
+import net.minecraft.world.item.context.UseOnContext;
+import net.minecraft.world.level.block.Block;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Predicate;
+
+public class Tillable extends Actionable {
+ private final Condition condition;
+
+ public Tillable(Condition condition, Block into, Map<Item, Double> drops) {
+ super(into, drops);
+ this.condition = condition;
+ }
+
+ public Condition condition() {
+ return condition;
+ }
+
+ public enum Condition {
+ AIR_ABOVE(HoeItem::onlyIfAirAbove),
+ ALWAYS((useOnContext) -> true);
+
+ private final Predicate<UseOnContext> predicate;
+
+ Condition(Predicate<UseOnContext> predicate) {
+ this.predicate = predicate;
+ }
+
+ public Predicate<UseOnContext> predicate() {
+ return predicate;
+ }
+
+ private static final Map<String, Condition> BY_NAME = new HashMap<>();
+
+ static {
+ for (Condition condition : values()) {
+ BY_NAME.put(condition.name(), condition);
+ }
+ }
+
+ public static Condition get(String name) {
+ return BY_NAME.get(name.toUpperCase(java.util.Locale.ROOT));
+ }
+ }
+}
diff --git a/src/main/java/org/purpurmc/purpur/tool/Waxable.java b/src/main/java/org/purpurmc/purpur/tool/Waxable.java
new file mode 100644
index 0000000000000000000000000000000000000000..64adb13b29b6757dcf227a55588da70ecabe083f
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/tool/Waxable.java
@@ -0,0 +1,12 @@
+package org.purpurmc.purpur.tool;
+
+import net.minecraft.world.item.Item;
+import net.minecraft.world.level.block.Block;
+
+import java.util.Map;
+
+public class Waxable extends Actionable {
+ public Waxable(Block into, Map<Item, Double> drops) {
+ super(into, drops);
+ }
+}
diff --git a/src/main/java/org/purpurmc/purpur/tool/Weatherable.java b/src/main/java/org/purpurmc/purpur/tool/Weatherable.java
new file mode 100644
index 0000000000000000000000000000000000000000..b7586f494528f30eb0da82420d3bcf5b83a1a902
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/tool/Weatherable.java
@@ -0,0 +1,12 @@
+package org.purpurmc.purpur.tool;
+
+import net.minecraft.world.item.Item;
+import net.minecraft.world.level.block.Block;
+
+import java.util.Map;
+
+public class Weatherable extends Actionable {
+ public Weatherable(Block into, Map<Item, Double> drops) {
+ super(into, drops);
+ }
+}

View File

@@ -1,49 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sat, 3 Jul 2021 18:40:32 -0500
Subject: [PATCH] Store placer on Block when placed
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
index 8c14f8c9f61baf1842e42b62bcd73717e82a29e1..24a7e1780ec55ea95195b5478eef66015cb21f72 100644
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
@@ -497,6 +497,7 @@ public final class ItemStack implements DataComponentHolder {
world.isBlockPlaceCancelled = true; // Paper - prevent calling cleanup logic when undoing a block place upon a cancelled BlockPlaceEvent
for (BlockState blockstate : blocks) {
blockstate.update(true, false);
+ ((CraftBlock) blockstate.getBlock()).getNMS().getBlock().forgetPlacer(); // Purpur
}
world.isBlockPlaceCancelled = false; // Paper - prevent calling cleanup logic when undoing a block place upon a cancelled BlockPlaceEvent
world.preventPoiUpdated = false;
@@ -529,6 +530,7 @@ public final class ItemStack implements DataComponentHolder {
if (!(block.getBlock() instanceof BaseEntityBlock)) { // Containers get placed automatically
block.onPlace(world, newblockposition, oldBlock, true, context);
}
+ block.getBlock().forgetPlacer(); // Purpur
world.notifyAndUpdatePhysics(newblockposition, null, oldBlock, block, world.getBlockState(newblockposition), updateFlag, 512); // send null chunk as chunk.k() returns false by this point
}
diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java
index 29947de9eb6887f2e61516523ff08d8b581b0f53..5dd4ccde6c4c421f697f629adb1adfadce7b8a42 100644
--- a/src/main/java/net/minecraft/world/level/block/Block.java
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
@@ -437,7 +437,17 @@ public class Block extends BlockBehaviour implements ItemLike {
} // Paper - fix drops not preventing stats/food exhaustion
}
- public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) {}
+ // Purpur start
+ @Nullable protected LivingEntity placer = null;
+
+ public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) {
+ this.placer = placer;
+ }
+
+ public void forgetPlacer() {
+ this.placer = null;
+ }
+ // Purpur end
public boolean isPossibleToRespawnInThis(BlockState state) {
return !state.isSolid() && !state.liquid();

View File

@@ -1,255 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sat, 3 Jul 2021 18:40:58 -0500
Subject: [PATCH] Summoner API
diff --git a/src/main/java/net/minecraft/world/entity/animal/IronGolem.java b/src/main/java/net/minecraft/world/entity/animal/IronGolem.java
index 446a2795aa8f2ddf472f8b379534978fca285f3d..a61d23568408f6441b6d728061f5d99861d2b76e 100644
--- a/src/main/java/net/minecraft/world/entity/animal/IronGolem.java
+++ b/src/main/java/net/minecraft/world/entity/animal/IronGolem.java
@@ -57,6 +57,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
private int remainingPersistentAngerTime;
@Nullable
private UUID persistentAngerTarget;
+ @Nullable private UUID summoner; // Purpur
public IronGolem(EntityType<? extends IronGolem> type, Level world) {
super(type, world);
@@ -90,6 +91,15 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
return this.level().purpurConfig.ironGolemTakeDamageFromWater;
}
+ @Nullable
+ public UUID getSummoner() {
+ return summoner;
+ }
+
+ public void setSummoner(@Nullable UUID summoner) {
+ this.summoner = summoner;
+ }
+
@Override
protected void registerGoals() {
if (level().purpurConfig.ironGolemCanSwim) this.goalSelector.addGoal(0, new net.minecraft.world.entity.ai.goal.FloatGoal(this)); // Purpur
@@ -167,6 +177,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
public void addAdditionalSaveData(CompoundTag nbt) {
super.addAdditionalSaveData(nbt);
nbt.putBoolean("PlayerCreated", this.isPlayerCreated());
+ if (getSummoner() != null) nbt.putUUID("Purpur.Summoner", getSummoner()); // Purpur
this.addPersistentAngerSaveData(nbt);
}
@@ -174,6 +185,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
public void readAdditionalSaveData(CompoundTag nbt) {
super.readAdditionalSaveData(nbt);
this.setPlayerCreated(nbt.getBoolean("PlayerCreated"));
+ if (nbt.contains("Purpur.Summoner")) setSummoner(nbt.getUUID("Purpur.Summoner")); // Purpur
this.readPersistentAngerSaveData(this.level(), nbt);
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
index 8966aa5e69cab5be770e2767e3e0f479426d8522..2a8d895b2ea78ec68e70bbf2e75ae6559b215868 100644
--- a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
+++ b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
@@ -47,6 +47,7 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
private static final EntityDataAccessor<Byte> DATA_PUMPKIN_ID = SynchedEntityData.defineId(SnowGolem.class, EntityDataSerializers.BYTE);
private static final byte PUMPKIN_FLAG = 16;
+ @Nullable private java.util.UUID summoner; // Purpur
public SnowGolem(EntityType<? extends SnowGolem> type, Level world) {
super(type, world);
@@ -75,6 +76,15 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
this.getAttribute(Attributes.SCALE).setBaseValue(this.level().purpurConfig.snowGolemScale);
}
+ @Nullable
+ public java.util.UUID getSummoner() {
+ return summoner;
+ }
+
+ public void setSummoner(@Nullable java.util.UUID summoner) {
+ this.summoner = summoner;
+ }
+
@Override
protected void registerGoals() {
this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur
@@ -102,6 +112,7 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
public void addAdditionalSaveData(CompoundTag nbt) {
super.addAdditionalSaveData(nbt);
nbt.putBoolean("Pumpkin", this.hasPumpkin());
+ if (getSummoner() != null) nbt.putUUID("Purpur.Summoner", getSummoner()); // Purpur
}
@Override
@@ -110,6 +121,7 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
if (nbt.contains("Pumpkin")) {
this.setPumpkin(nbt.getBoolean("Pumpkin"));
}
+ if (nbt.contains("Purpur.Summoner")) setSummoner(nbt.getUUID("Purpur.Summoner")); // Purpur
}
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 8809b88dec7beffa569de6832f5b458116b143cc..c0d5fc670ff428a4293e8965068f52449a5c8b47 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
@@ -88,6 +88,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
return !entityliving.getType().is(EntityTypeTags.WITHER_FRIENDS) && entityliving.attackable();
};
private static final TargetingConditions TARGETING_CONDITIONS = TargetingConditions.forCombat().range(20.0D).selector(WitherBoss.LIVING_ENTITY_SELECTOR);
+ @Nullable private java.util.UUID summoner; // Purpur
private int shootCooldown = 0; // Purpur
// Paper start
private boolean canPortal = false;
@@ -127,6 +128,15 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
return this.level().purpurConfig.witherTakeDamageFromWater;
}
+ @Nullable
+ public java.util.UUID getSummoner() {
+ return summoner;
+ }
+
+ public void setSummoner(@Nullable java.util.UUID summoner) {
+ this.summoner = summoner;
+ }
+
@Override
protected PathNavigation createNavigation(Level world) {
FlyingPathNavigation navigationflying = new FlyingPathNavigation(this, world);
@@ -262,6 +272,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
public void addAdditionalSaveData(CompoundTag nbt) {
super.addAdditionalSaveData(nbt);
nbt.putInt("Invul", this.getInvulnerableTicks());
+ if (getSummoner() != null) nbt.putUUID("Purpur.Summoner", getSummoner()); // Purpur
}
@Override
@@ -271,6 +282,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
if (this.hasCustomName()) {
this.bossEvent.setName(this.getDisplayName());
}
+ if (nbt.contains("Purpur.Summoner")) setSummoner(nbt.getUUID("Purpur.Summoner")); // Purpur
}
diff --git a/src/main/java/net/minecraft/world/level/block/CarvedPumpkinBlock.java b/src/main/java/net/minecraft/world/level/block/CarvedPumpkinBlock.java
index 655f51902e5d24643d41c4ec981743543c0890a5..e6a299eeda5d18274fa3b1fb542b217a074c1d83 100644
--- a/src/main/java/net/minecraft/world/level/block/CarvedPumpkinBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/CarvedPumpkinBlock.java
@@ -71,7 +71,7 @@ public class CarvedPumpkinBlock extends HorizontalDirectionalBlock {
SnowGolem entitysnowman = (SnowGolem) EntityType.SNOW_GOLEM.create(world);
if (entitysnowman != null) {
- CarvedPumpkinBlock.spawnGolemInWorld(world, shapedetector_shapedetectorcollection, entitysnowman, shapedetector_shapedetectorcollection.getBlock(0, 2, 0).getPos());
+ CarvedPumpkinBlock.spawnGolemInWorld(world, shapedetector_shapedetectorcollection, entitysnowman, shapedetector_shapedetectorcollection.getBlock(0, 2, 0).getPos(), this.placer); // Purpur
}
} else {
BlockPattern.BlockPatternMatch shapedetector_shapedetectorcollection1 = this.getOrCreateIronGolemFull().find(world, pos);
@@ -81,7 +81,7 @@ public class CarvedPumpkinBlock extends HorizontalDirectionalBlock {
if (entityirongolem != null) {
entityirongolem.setPlayerCreated(true);
- CarvedPumpkinBlock.spawnGolemInWorld(world, shapedetector_shapedetectorcollection1, entityirongolem, shapedetector_shapedetectorcollection1.getBlock(1, 2, 0).getPos());
+ CarvedPumpkinBlock.spawnGolemInWorld(world, shapedetector_shapedetectorcollection1, entityirongolem, shapedetector_shapedetectorcollection1.getBlock(1, 2, 0).getPos(), this.placer); // Purpur
}
}
}
@@ -89,6 +89,16 @@ public class CarvedPumpkinBlock extends HorizontalDirectionalBlock {
}
private static void spawnGolemInWorld(Level world, BlockPattern.BlockPatternMatch patternResult, Entity entity, BlockPos pos) {
+ // Purpur start
+ spawnGolemInWorld(world, patternResult, entity, pos, null);
+ }
+ private static void spawnGolemInWorld(Level world, BlockPattern.BlockPatternMatch patternResult, Entity entity, BlockPos pos, net.minecraft.world.entity.LivingEntity placer) {
+ if (entity instanceof SnowGolem snowGolem) {
+ snowGolem.setSummoner(placer == null ? null : placer.getUUID());
+ } else if (entity instanceof IronGolem ironGolem) {
+ ironGolem.setSummoner(placer == null ? null : placer.getUUID());
+ }
+ // Purpur end
// clearPatternBlocks(world, shapedetector_shapedetectorcollection); // CraftBukkit - moved down
entity.moveTo((double) pos.getX() + 0.5D, (double) pos.getY() + 0.05D, (double) pos.getZ() + 0.5D, 0.0F, 0.0F);
// CraftBukkit start
diff --git a/src/main/java/net/minecraft/world/level/block/WitherSkullBlock.java b/src/main/java/net/minecraft/world/level/block/WitherSkullBlock.java
index bbf59b2577812e74ffd45f694b83a42e043273c0..5cb06959aeaceeb98cfee34b1df804e6642f305f 100644
--- a/src/main/java/net/minecraft/world/level/block/WitherSkullBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/WitherSkullBlock.java
@@ -79,6 +79,7 @@ public class WitherSkullBlock extends SkullBlock {
entitywither.moveTo((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 0.55D, (double) blockposition1.getZ() + 0.5D, shapedetector_shapedetectorcollection.getForwards().getAxis() == Direction.Axis.X ? 0.0F : 90.0F, 0.0F);
entitywither.yBodyRot = shapedetector_shapedetectorcollection.getForwards().getAxis() == Direction.Axis.X ? 0.0F : 90.0F;
entitywither.makeInvulnerable();
+ entitywither.setSummoner(iblockdata.getBlock().placer == null ? null : iblockdata.getBlock().placer.getUUID()); // Purpur
// CraftBukkit start
if (!world.addFreshEntity(entitywither, SpawnReason.BUILD_WITHER)) {
return;
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java
index 63cae1a2e95d8da17c45c4404a8dd0ca6a413c39..966587c2788b5c93be83259ddc962a89cde7cbaa 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java
@@ -27,4 +27,17 @@ public class CraftIronGolem extends CraftGolem implements IronGolem {
public void setPlayerCreated(boolean playerCreated) {
this.getHandle().setPlayerCreated(playerCreated);
}
+
+ // Purpur start
+ @Override
+ @org.jetbrains.annotations.Nullable
+ public java.util.UUID getSummoner() {
+ return getHandle().getSummoner();
+ }
+
+ @Override
+ public void setSummoner(@org.jetbrains.annotations.Nullable java.util.UUID summoner) {
+ getHandle().setSummoner(summoner);
+ }
+ // Purpur end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
index 4ce2373ff71c3c1b8951646e057587a3ab09e145..4f7f6cf6ca24406570d2d29dc63dc89401119961 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
@@ -28,4 +28,17 @@ public class CraftSnowman extends CraftGolem implements Snowman, com.destroystok
public String toString() {
return "CraftSnowman";
}
+
+ // Purpur start
+ @Override
+ @org.jetbrains.annotations.Nullable
+ public java.util.UUID getSummoner() {
+ return getHandle().getSummoner();
+ }
+
+ @Override
+ public void setSummoner(@org.jetbrains.annotations.Nullable java.util.UUID summoner) {
+ getHandle().setSummoner(summoner);
+ }
+ // Purpur end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java
index 7881c6253c1d652c0c0d54a9a8accdf0a1ff0f3e..da6ccb2a38df76770821a1a2203e54e722f541ca 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java
@@ -99,4 +99,17 @@ public class CraftWither extends CraftMonster implements Wither, com.destroystok
this.getHandle().makeInvulnerable();
}
// Paper end
+
+ // Purpur start
+ @Override
+ @org.jetbrains.annotations.Nullable
+ public java.util.UUID getSummoner() {
+ return getHandle().getSummoner();
+ }
+
+ @Override
+ public void setSummoner(@org.jetbrains.annotations.Nullable java.util.UUID summoner) {
+ getHandle().setSummoner(summoner);
+ }
+ // Purpur end
}

View File

@@ -1,88 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sat, 3 Jul 2021 21:52:15 -0500
Subject: [PATCH] Customizable sleeping actionbar messages
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 277a0b6f38b1ce00fd06066b43ac634f80ab441a..c31fd59a311e3e131c8a5fee9f66619f1761ab06 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -1070,11 +1070,27 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
if (this.canSleepThroughNights()) {
if (!this.getServer().isSingleplayer() || this.getServer().isPublished()) {
int i = this.getGameRules().getInt(GameRules.RULE_PLAYERS_SLEEPING_PERCENTAGE);
- MutableComponent ichatmutablecomponent;
+ Component ichatmutablecomponent;
if (this.sleepStatus.areEnoughSleeping(i)) {
+ // Purpur start
+ if (org.purpurmc.purpur.PurpurConfig.sleepSkippingNight.isBlank()) {
+ return;
+ }
+ if (!org.purpurmc.purpur.PurpurConfig.sleepSkippingNight.equalsIgnoreCase("default")) {
+ ichatmutablecomponent = io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.sleepSkippingNight));
+ } else
ichatmutablecomponent = Component.translatable("sleep.skipping_night");
} else {
+ if (org.purpurmc.purpur.PurpurConfig.sleepingPlayersPercent.isBlank()) {
+ return;
+ }
+ if (!org.purpurmc.purpur.PurpurConfig.sleepingPlayersPercent.equalsIgnoreCase("default")) {
+ ichatmutablecomponent = io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.sleepingPlayersPercent,
+ net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.parsed("count", Integer.toString(this.sleepStatus.amountSleeping())),
+ net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.parsed("total", Integer.toString(this.sleepStatus.sleepersNeeded(i)))));
+ } else
+ // Purpur end
ichatmutablecomponent = Component.translatable("sleep.players_sleeping", this.sleepStatus.amountSleeping(), this.sleepStatus.sleepersNeeded(i));
}
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index e081734828f7991ffc33233843779fd65f9ea9d7..d1d1ceabdf6b0bd254fefd64e2504f0865e0c9b2 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -1570,7 +1570,19 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
});
if (!this.serverLevel().canSleepThroughNights()) {
- this.displayClientMessage(Component.translatable("sleep.not_possible"), true);
+ // Purpur start
+ Component clientMessage;
+ if (org.purpurmc.purpur.PurpurConfig.sleepNotPossible.isBlank()) {
+ clientMessage = null;
+ } else if (!org.purpurmc.purpur.PurpurConfig.sleepNotPossible.equalsIgnoreCase("default")) {
+ clientMessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.sleepNotPossible));
+ } else {
+ clientMessage = Component.translatable("sleep.not_possible");
+ }
+ if (clientMessage != null) {
+ this.displayClientMessage(clientMessage, true);
+ }
+ // Purpur end
}
((ServerLevel) this.level()).updateSleepingPlayerList();
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index a914c844c0d4f1e80c40c2798f5e24364778fde9..dabc82f2309f12e684350c430096121927f47b3c 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -188,6 +188,9 @@ public class PurpurConfig {
public static String dontRunWithScissors = "<red><italic>Don't run with scissors!";
public static String uptimeCommandOutput = "<green>Server uptime is <uptime>";
public static String unverifiedUsername = "default";
+ public static String sleepSkippingNight = "default";
+ public static String sleepingPlayersPercent = "default";
+ public static String sleepNotPossible = "default";
private static void messages() {
cannotRideMob = getString("settings.messages.cannot-ride-mob", cannotRideMob);
afkBroadcastAway = getString("settings.messages.afk-broadcast-away", afkBroadcastAway);
@@ -202,6 +205,9 @@ public class PurpurConfig {
dontRunWithScissors = getString("settings.messages.dont-run-with-scissors", dontRunWithScissors);
uptimeCommandOutput = getString("settings.messages.uptime-command-output", uptimeCommandOutput);
unverifiedUsername = getString("settings.messages.unverified-username", unverifiedUsername);
+ sleepSkippingNight = getString("settings.messages.sleep-skipping-night", sleepSkippingNight);
+ sleepingPlayersPercent = getString("settings.messages.sleeping-players-percent", sleepingPlayersPercent);
+ sleepNotPossible = getString("settings.messages.sleep-not-possible", sleepNotPossible);
}
public static String deathMsgRunWithScissors = "<player> slipped and fell on their shears";

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, 5 Jul 2021 20:23:08 -0500
Subject: [PATCH] option to disable shulker box items from dropping contents
when destroyed
diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java
index 3253361d91e2a2e68d354eaf3dd3e3cd486e191d..a255b76cc1e6cb926585110e5f09ded37da7be20 100644
--- a/src/main/java/net/minecraft/world/item/BlockItem.java
+++ b/src/main/java/net/minecraft/world/item/BlockItem.java
@@ -260,6 +260,7 @@ public class BlockItem extends Item {
ItemContainerContents itemcontainercontents = (ItemContainerContents) entity.getItem().set(DataComponents.CONTAINER, ItemContainerContents.EMPTY);
if (itemcontainercontents != null) {
+ if (entity.level().purpurConfig.shulkerBoxItemDropContentsWhenDestroyed && this.getBlock() instanceof ShulkerBoxBlock) // Purpur
ItemUtils.onContainerDestroyed(entity, itemcontainercontents.nonEmptyItemsCopy());
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 95b5106772a6701ecb0e60206871c139f215e487..6381828cc6cee1ec6c0a7951a36d22937dddf149 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -214,6 +214,7 @@ public class PurpurWorldConfig {
public int enderPearlCooldownCreative = 20;
public float enderPearlEndermiteChance = 0.05F;
public int glowBerriesEatGlowDuration = 0;
+ public boolean shulkerBoxItemDropContentsWhenDestroyed = true;
private void itemSettings() {
itemImmuneToCactus.clear();
getList("gameplay-mechanics.item.immune.cactus", new ArrayList<>()).forEach(key -> {
@@ -260,6 +261,7 @@ public class PurpurWorldConfig {
enderPearlCooldownCreative = getInt("gameplay-mechanics.item.ender-pearl.creative-cooldown", enderPearlCooldownCreative);
enderPearlEndermiteChance = (float) getDouble("gameplay-mechanics.item.ender-pearl.endermite-spawn-chance", enderPearlEndermiteChance);
glowBerriesEatGlowDuration = getInt("gameplay-mechanics.item.glow_berries.eat-glow-duration", glowBerriesEatGlowDuration);
+ shulkerBoxItemDropContentsWhenDestroyed = getBoolean("gameplay-mechanics.item.shulker_box.drop-contents-when-destroyed", shulkerBoxItemDropContentsWhenDestroyed);
}
public double minecartMaxSpeed = 0.4D;

View File

@@ -1,52 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Fri, 16 Jul 2021 22:47:29 -0500
Subject: [PATCH] Big dripleaf tilt delay
Makes the tilt delays configurable. There are only 3 types of tilts used by this setting. When an entity steps on a
big_dripleaf with no tilt it will immediately change to an UNSTABLE tilt. Each change after that is on a tick timer:
UNSTABLE: big_dripleaf with UNSTABLE tilt will change to PARTIAL tilt after 10 ticks
PARTIAL: big_dripleaf with PARTIAL tilt will change to FULL tilt after 10 ticks
UNSTABLE: big_dripleaf with FULL tilt will change back to no tilt after 100 ticks
diff --git a/src/main/java/net/minecraft/world/level/block/BigDripleafBlock.java b/src/main/java/net/minecraft/world/level/block/BigDripleafBlock.java
index 8240c32d676a88aa23dcd052ee0136767e54fb0d..372c4ab9d390d5afd98947f21c79aae06b15064d 100644
--- a/src/main/java/net/minecraft/world/level/block/BigDripleafBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/BigDripleafBlock.java
@@ -244,7 +244,7 @@ public class BigDripleafBlock extends HorizontalDirectionalBlock implements Bone
BigDripleafBlock.playTiltSound(world, blockposition, soundeffect);
}
- int i = BigDripleafBlock.DELAY_UNTIL_NEXT_TILT_STATE.getInt(tilt);
+ int i = world.purpurConfig.bigDripleafTiltDelay.getOrDefault(tilt, -1); // Purpur
if (i != -1) {
world.scheduleTick(blockposition, (Block) this, i);
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 6381828cc6cee1ec6c0a7951a36d22937dddf149..b95043a271b4e587b2dc6c56f5c82e601aaa842c 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -778,6 +778,22 @@ public class PurpurWorldConfig {
}
}
+ public Map<Tilt, Integer> bigDripleafTiltDelay = new HashMap<>();
+ private void bigDripleafSettings() {
+ bigDripleafTiltDelay.clear();
+ getMap("blocks.big_dripleaf.tilt-delay", Map.ofEntries(
+ Map.entry("UNSTABLE", 10),
+ Map.entry("PARTIAL", 10),
+ Map.entry("FULL", 100))
+ ).forEach((tilt, delay) -> {
+ try {
+ bigDripleafTiltDelay.put(Tilt.valueOf(tilt), (int) delay);
+ } catch (IllegalArgumentException e) {
+ PurpurConfig.log(Level.SEVERE, "Invalid big_dripleaf tilt key: " + tilt);
+ }
+ });
+ }
+
public boolean chestOpenWithBlockOnTop = false;
private void chestSettings() {
chestOpenWithBlockOnTop = getBoolean("blocks.chest.open-with-solid-block-on-top", chestOpenWithBlockOnTop);

View File

@@ -1,44 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sat, 17 Jul 2021 15:55:14 -0500
Subject: [PATCH] Player ridable in water option
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 09e1faae9c22c1062e3de5257c82b2d156e65b4f..05ed7bfd75a1e30d74b12a068303a786222a2649 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -2087,6 +2087,13 @@ public abstract class Player extends LivingEntity {
return slot != EquipmentSlot.BODY;
}
+ // Purpur start
+ @Override
+ public boolean dismountsUnderwater() {
+ return !level().purpurConfig.playerRidableInWater;
+ }
+ // Purpur end
+
public boolean setEntityOnShoulder(CompoundTag entityNbt) {
if (!this.isPassenger() && this.onGround() && !this.isInWater() && !this.isInPowderSnow) {
if (this.getShoulderEntityLeft().isEmpty()) {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index b95043a271b4e587b2dc6c56f5c82e601aaa842c..dae3ead8fc563e3ff714a8d6170549226f44561b 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -387,6 +387,7 @@ public class PurpurWorldConfig {
public double playerCriticalDamageMultiplier = 1.5D;
public int playerBurpDelay = 10;
public boolean playerBurpWhenFull = false;
+ public boolean playerRidableInWater = false;
private void playerSettings() {
if (PurpurConfig.version < 19) {
boolean oldVal = getBoolean("gameplay-mechanics.player.idle-timeout.mods-target", idleTimeoutTargetPlayer);
@@ -409,6 +410,7 @@ public class PurpurWorldConfig {
playerCriticalDamageMultiplier = getDouble("gameplay-mechanics.player.critical-damage-multiplier", playerCriticalDamageMultiplier);
playerBurpDelay = getInt("gameplay-mechanics.player.burp-delay", playerBurpDelay);
playerBurpWhenFull = getBoolean("gameplay-mechanics.player.burp-when-full", playerBurpWhenFull);
+ playerRidableInWater = getBoolean("gameplay-mechanics.player.ridable-in-water", playerRidableInWater);
}
public boolean silkTouchEnabled = false;

View File

@@ -1,38 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Mon, 19 Jul 2021 19:28:17 -0400
Subject: [PATCH] Config to disable Enderman teleport on projectile hit
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 65c7bf88071dda62034d71b6a83caedd49d0902a..ecd117f7e3b2136fcf49384819626fe7de952098 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
@@ -443,6 +443,7 @@ public class EnderMan extends Monster implements NeutralMob {
} else {
flag1 = flag && this.hurtWithCleanWater(source, (ThrownPotion) source.getDirectEntity(), amount);
+ if (!flag1 && this.level().purpurConfig.endermanIgnoreProjectiles) return super.hurt(source, amount); // Purpur
if (this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.INDIRECT)) { // Paper - EndermanEscapeEvent
for (int i = 0; i < 64; ++i) {
if (this.teleport()) {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index dae3ead8fc563e3ff714a8d6170549226f44561b..2af9b746d436eb8e0ad25f2e4bdca45908a28988 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1443,6 +1443,7 @@ public class PurpurWorldConfig {
public boolean endermanAggroEndermitesOnlyIfPlayerSpawned = false;
public boolean endermanIgnorePlayerDragonHead = false;
public boolean endermanDisableStareAggro = false;
+ public boolean endermanIgnoreProjectiles = false;
private void endermanSettings() {
endermanRidable = getBoolean("mobs.enderman.ridable", endermanRidable);
endermanRidableInWater = getBoolean("mobs.enderman.ridable-in-water", endermanRidableInWater);
@@ -1466,6 +1467,7 @@ public class PurpurWorldConfig {
endermanAggroEndermitesOnlyIfPlayerSpawned = getBoolean("mobs.enderman.aggressive-towards-endermites-only-spawned-by-player-thrown-ender-pearls", endermanAggroEndermitesOnlyIfPlayerSpawned);
endermanIgnorePlayerDragonHead = getBoolean("mobs.enderman.ignore-players-wearing-dragon-head", endermanIgnorePlayerDragonHead);
endermanDisableStareAggro = getBoolean("mobs.enderman.disable-player-stare-aggression", endermanDisableStareAggro);
+ endermanIgnoreProjectiles = getBoolean("mobs.enderman.ignore-projectiles", endermanIgnoreProjectiles);
}
public boolean endermiteRidable = false;

View File

@@ -1,248 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sat, 24 Jul 2021 00:07:31 -0500
Subject: [PATCH] Add compass command
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
index af5246b966f2322febb804a85e167ff580d2ab25..929835b74d539bb0af1bb99f23b50b79f457594e 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 {
org.purpurmc.purpur.command.PingCommand.register(this.dispatcher); // Purpur
org.purpurmc.purpur.command.UptimeCommand.register(this.dispatcher); // Purpur
org.purpurmc.purpur.command.TPSBarCommand.register(this.dispatcher); // Purpur
+ org.purpurmc.purpur.command.CompassCommand.register(this.dispatcher); // Purpur
}
if (environment.includeIntegrated) {
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index d1d1ceabdf6b0bd254fefd64e2504f0865e0c9b2..996bfac666762096fe322e54c2134bab0c08c950 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -304,6 +304,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event
public boolean purpurClient = false; // Purpur
private boolean tpsBar = false; // Purpur
+ private boolean compassBar = false; // Purpur
// Paper start - rewrite chunk system
private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader;
@@ -602,6 +603,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
}
if (nbt.contains("Purpur.TPSBar")) { this.tpsBar = nbt.getBoolean("Purpur.TPSBar"); } // Purpur
+ if (nbt.contains("Purpur.CompassBar")) { this.compassBar = nbt.getBoolean("Purpur.CompassBar"); } // Purpur
}
@Override
@@ -679,6 +681,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
}
nbt.putBoolean("Purpur.TPSBar", this.tpsBar); // Purpur
+ nbt.putBoolean("Purpur.CompassBar", this.compassBar); // Purpur
}
// CraftBukkit start - World fallback code, either respawn location or global spawn
@@ -3092,5 +3095,13 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
public void tpsBar(boolean tpsBar) {
this.tpsBar = tpsBar;
}
+
+ public boolean compassBar() {
+ return this.compassBar;
+ }
+
+ public void compassBar(boolean compassBar) {
+ this.compassBar = compassBar;
+ }
// Purpur end
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index dabc82f2309f12e684350c430096121927f47b3c..37b802a1de4ade72d53463819d7774436d68be51 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -257,6 +257,11 @@ public class PurpurConfig {
public static String commandTPSBarTextColorMedium = "<gradient:#ffff55:#ffaa00><text></gradient>";
public static String commandTPSBarTextColorLow = "<gradient:#ff5555:#aa0000><text></gradient>";
public static int commandTPSBarTickInterval = 20;
+ public static String commandCompassBarTitle = "S \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 SW \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 W \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 NW \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 N \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 NE \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 E \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 SE \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 S \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 SW \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 W \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 NW \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 N \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 NE \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 E \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 SE \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 \u25C8 \u00B7 ";
+ public static BossBar.Overlay commandCompassBarProgressOverlay = BossBar.Overlay.PROGRESS;
+ public static BossBar.Color commandCompassBarProgressColor = BossBar.Color.BLUE;
+ public static float commandCompassBarProgressPercent = 1.0F;
+ public static int commandCompassBarTickInterval = 5;
public static boolean commandGamemodeRequiresPermission = false;
public static boolean hideHiddenPlayersFromEntitySelector = false;
public static String uptimeFormat = "<days><hours><minutes><seconds>";
@@ -279,6 +284,13 @@ public class PurpurConfig {
commandTPSBarTextColorMedium = getString("settings.command.tpsbar.text-color.medium", commandTPSBarTextColorMedium);
commandTPSBarTextColorLow = getString("settings.command.tpsbar.text-color.low", commandTPSBarTextColorLow);
commandTPSBarTickInterval = getInt("settings.command.tpsbar.tick-interval", commandTPSBarTickInterval);
+
+ commandCompassBarTitle = getString("settings.command.compass.title", commandCompassBarTitle);
+ commandCompassBarProgressOverlay = BossBar.Overlay.valueOf(getString("settings.command.compass.overlay", commandCompassBarProgressOverlay.name()));
+ commandCompassBarProgressColor = BossBar.Color.valueOf(getString("settings.command.compass.progress-color", commandCompassBarProgressColor.name()));
+ commandCompassBarProgressPercent = (float) getDouble("settings.command.compass.percent", commandCompassBarProgressPercent);
+ commandCompassBarTickInterval = getInt("settings.command.compass.tick-interval", commandCompassBarTickInterval);
+
commandGamemodeRequiresPermission = getBoolean("settings.command.gamemode.requires-specific-permission", commandGamemodeRequiresPermission);
hideHiddenPlayersFromEntitySelector = getBoolean("settings.command.hide-hidden-players-from-entity-selector", hideHiddenPlayersFromEntitySelector);
uptimeFormat = getString("settings.command.uptime.format", uptimeFormat);
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 2af9b746d436eb8e0ad25f2e4bdca45908a28988..33276fd97eddeb0d2b47817d3f350ce2f615163b 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -215,6 +215,7 @@ public class PurpurWorldConfig {
public float enderPearlEndermiteChance = 0.05F;
public int glowBerriesEatGlowDuration = 0;
public boolean shulkerBoxItemDropContentsWhenDestroyed = true;
+ public boolean compassItemShowsBossBar = false;
private void itemSettings() {
itemImmuneToCactus.clear();
getList("gameplay-mechanics.item.immune.cactus", new ArrayList<>()).forEach(key -> {
@@ -262,6 +263,7 @@ public class PurpurWorldConfig {
enderPearlEndermiteChance = (float) getDouble("gameplay-mechanics.item.ender-pearl.endermite-spawn-chance", enderPearlEndermiteChance);
glowBerriesEatGlowDuration = getInt("gameplay-mechanics.item.glow_berries.eat-glow-duration", glowBerriesEatGlowDuration);
shulkerBoxItemDropContentsWhenDestroyed = getBoolean("gameplay-mechanics.item.shulker_box.drop-contents-when-destroyed", shulkerBoxItemDropContentsWhenDestroyed);
+ compassItemShowsBossBar = getBoolean("gameplay-mechanics.item.compass.holding-shows-bossbar", compassItemShowsBossBar);
}
public double minecartMaxSpeed = 0.4D;
diff --git a/src/main/java/org/purpurmc/purpur/command/CompassCommand.java b/src/main/java/org/purpurmc/purpur/command/CompassCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..79b8490832d2a0cc7846ddcb091cb6bcac74ea45
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/command/CompassCommand.java
@@ -0,0 +1,27 @@
+package org.purpurmc.purpur.command;
+
+import com.mojang.brigadier.CommandDispatcher;
+import net.minecraft.commands.CommandSourceStack;
+import net.minecraft.commands.Commands;
+import net.minecraft.server.level.ServerPlayer;
+import org.purpurmc.purpur.task.CompassTask;
+
+public class CompassCommand {
+ public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
+ dispatcher.register(Commands.literal("compass")
+ .requires(listener -> listener.hasPermission(2, "bukkit.command.compass"))
+ .executes(context -> {
+ ServerPlayer player = context.getSource().getPlayerOrException();
+ CompassTask task = CompassTask.instance();
+ if (player.compassBar()) {
+ task.removePlayer(player.getBukkitEntity());
+ player.compassBar(false);
+ } else {
+ task.addPlayer(player.getBukkitEntity());
+ player.compassBar(true);
+ }
+ return 1;
+ })
+ );
+ }
+}
diff --git a/src/main/java/org/purpurmc/purpur/task/BossBarTask.java b/src/main/java/org/purpurmc/purpur/task/BossBarTask.java
index 6796fd6a936212a6eb768d9cf0fa5e74132c89e8..65c1bac3daf781c66442350ba08c43b21d2f1637 100644
--- a/src/main/java/org/purpurmc/purpur/task/BossBarTask.java
+++ b/src/main/java/org/purpurmc/purpur/task/BossBarTask.java
@@ -90,10 +90,12 @@ public abstract class BossBarTask extends BukkitRunnable {
public static void startAll() {
TPSBarTask.instance().start();
+ CompassTask.instance().start();
}
public static void stopAll() {
TPSBarTask.instance().stop();
+ CompassTask.instance().stop();
}
public static void addToAll(ServerPlayer player) {
@@ -101,9 +103,13 @@ public abstract class BossBarTask extends BukkitRunnable {
if (player.tpsBar()) {
TPSBarTask.instance().addPlayer(bukkit);
}
+ if (player.compassBar()) {
+ CompassTask.instance().addPlayer(bukkit);
+ }
}
public static void removeFromAll(Player player) {
TPSBarTask.instance().removePlayer(player);
+ CompassTask.instance().removePlayer(player);
}
}
diff --git a/src/main/java/org/purpurmc/purpur/task/CompassTask.java b/src/main/java/org/purpurmc/purpur/task/CompassTask.java
new file mode 100644
index 0000000000000000000000000000000000000000..bece7eefc8ba8822b433835526251d2fb916c025
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/task/CompassTask.java
@@ -0,0 +1,68 @@
+package org.purpurmc.purpur.task;
+
+import net.kyori.adventure.bossbar.BossBar;
+import net.kyori.adventure.text.Component;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.world.item.Items;
+import org.bukkit.entity.Player;
+import org.purpurmc.purpur.PurpurConfig;
+
+public class CompassTask extends BossBarTask {
+ private static CompassTask instance;
+
+ private int tick = 0;
+
+ public static CompassTask instance() {
+ if (instance == null) {
+ instance = new CompassTask();
+ }
+ return instance;
+ }
+
+ @Override
+ public void run() {
+ if (++tick < PurpurConfig.commandCompassBarTickInterval) {
+ return;
+ }
+ tick = 0;
+
+ MinecraftServer.getServer().getAllLevels().forEach((level) -> {
+ if (level.purpurConfig.compassItemShowsBossBar) {
+ level.players().forEach(player -> {
+ if (!player.compassBar()) {
+ if (player.getMainHandItem().getItem() != Items.COMPASS && player.getOffhandItem().getItem() != Items.COMPASS) {
+ removePlayer(player.getBukkitEntity());
+ } else if (!hasPlayer(player.getUUID())) {
+ addPlayer(player.getBukkitEntity());
+ }
+ }
+ });
+ }
+ });
+
+ super.run();
+ }
+
+ @Override
+ BossBar createBossBar() {
+ return BossBar.bossBar(Component.text(""), PurpurConfig.commandCompassBarProgressPercent, PurpurConfig.commandCompassBarProgressColor, PurpurConfig.commandCompassBarProgressOverlay);
+ }
+
+ @Override
+ void updateBossBar(BossBar bossbar, Player player) {
+ float yaw = player.getLocation().getYaw();
+ int length = PurpurConfig.commandCompassBarTitle.length();
+ int pos = (int) ((normalize(yaw) * (length / 720F)) + (length / 2F));
+ bossbar.name(Component.text(PurpurConfig.commandCompassBarTitle.substring(pos - 25, pos + 25)));
+ }
+
+ private float normalize(float yaw) {
+ while (yaw < -180.0F) {
+ yaw += 360.0F;
+ }
+ while (yaw > 180.0F) {
+ yaw -= 360.0F;
+ }
+ return yaw;
+ }
+}

View File

@@ -1,36 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 12emin34 <macanovic.emin@gmail.com>
Date: Wed, 4 Aug 2021 11:44:26 +0200
Subject: [PATCH] Toggle for kinetic damage
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index c8e5162e3494f221ebbf538d7416c8508358546d..863bfe33d980f1988111669c6a6ae53bee9c4887 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -3064,6 +3064,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
if (f3 > 0.0F) {
this.playSound(this.getFallDamageSound((int) f3), 1.0F, 1.0F);
+ if (level().purpurConfig.elytraKineticDamage) // Purpur
this.hurt(this.damageSources().flyIntoWall(), f3);
}
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 33276fd97eddeb0d2b47817d3f350ce2f615163b..0dc2f0cb6d9300fd33fcb5813421cbfdebea3446 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -182,11 +182,13 @@ public class PurpurWorldConfig {
public double elytraDamageMultiplyBySpeed = 0;
public int elytraDamagePerFireworkBoost = 0;
public int elytraDamagePerTridentBoost = 0;
+ public boolean elytraKineticDamage = true;
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);
+ elytraKineticDamage = getBoolean("gameplay-mechanics.elytra.kinetic-damage", elytraKineticDamage);
}
public int entityLifeSpan = 0;

View File

@@ -1,35 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: DoctaEnkoda <bierquejason@gmail.com>
Date: Mon, 5 Jul 2021 06:00:17 +0200
Subject: [PATCH] Add Option for disable observer clocks
Allow to disable observer clocks: https://www.spigotmc.org/attachments/observerclock-gif.365936/
diff --git a/src/main/java/net/minecraft/world/level/block/ObserverBlock.java b/src/main/java/net/minecraft/world/level/block/ObserverBlock.java
index b38fbe5121f293f425d7673a6ce49b11d0ced0d9..2a74f42672b92393b52a61c27c5b8af77c8c6070 100644
--- a/src/main/java/net/minecraft/world/level/block/ObserverBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/ObserverBlock.java
@@ -71,6 +71,7 @@ public class ObserverBlock extends DirectionalBlock {
@Override
protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
if (state.getValue(ObserverBlock.FACING) == direction && !(Boolean) state.getValue(ObserverBlock.POWERED)) {
+ if (!world.getMinecraftWorld().purpurConfig.disableObserverClocks || !(neighborState.getBlock() instanceof ObserverBlock) || neighborState.getValue(ObserverBlock.FACING).getOpposite() != direction) // Purpur
this.startSignal(world, pos);
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 0dc2f0cb6d9300fd33fcb5813421cbfdebea3446..e1618abc6e277c581de90770b0ef4e5286025dc6 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -362,6 +362,11 @@ public class PurpurWorldConfig {
villageSiegeSpawning = getBoolean("gameplay-mechanics.mob-spawning.village-sieges", predicate);
}
+ public boolean disableObserverClocks = false;
+ private void observerSettings() {
+ disableObserverClocks = getBoolean("blocks.observer.disable-clock", disableObserverClocks);
+ }
+
public int playerNetheriteFireResistanceDuration = 0;
public int playerNetheriteFireResistanceAmplifier = 0;
public boolean playerNetheriteFireResistanceAmbient = false;

View File

@@ -1,41 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 12emin34 <macanovic.emin@gmail.com>
Date: Fri, 6 Aug 2021 22:30:10 +0200
Subject: [PATCH] Customizeable Zombie Villager curing times
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 3c4cff3f095cdf2dd74df7bf4bb8f3d5600b342d..9bb75b49ea2d0bd8aafbe537b65f86eb04f6cfe2 100644
--- a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java
+++ b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java
@@ -225,7 +225,7 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder {
if (this.hasEffect(MobEffects.WEAKNESS)) {
itemstack.consume(1, player);
if (!this.level().isClientSide) {
- this.startConverting(player.getUUID(), this.random.nextInt(2401) + 3600);
+ this.startConverting(player.getUUID(), this.random.nextInt(level().purpurConfig.zombieVillagerCuringTimeMax - level().purpurConfig.zombieVillagerCuringTimeMin + 1) + level().purpurConfig.zombieVillagerCuringTimeMin); // 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 e1618abc6e277c581de90770b0ef4e5286025dc6..eb1d3a1045c580e8da95fdcb0c9fbd3c345ca9eb 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -2946,6 +2946,8 @@ public class PurpurWorldConfig {
public double zombieVillagerJockeyChance = 0.05D;
public boolean zombieVillagerJockeyTryExistingChickens = true;
public boolean zombieVillagerTakeDamageFromWater = false;
+ public int zombieVillagerCuringTimeMin = 3600;
+ public int zombieVillagerCuringTimeMax = 6000;
private void zombieVillagerSettings() {
zombieVillagerRidable = getBoolean("mobs.zombie_villager.ridable", zombieVillagerRidable);
zombieVillagerRidableInWater = getBoolean("mobs.zombie_villager.ridable-in-water", zombieVillagerRidableInWater);
@@ -2962,6 +2964,8 @@ public class PurpurWorldConfig {
zombieVillagerJockeyChance = getDouble("mobs.zombie_villager.jockey.chance", zombieVillagerJockeyChance);
zombieVillagerJockeyTryExistingChickens = getBoolean("mobs.zombie_villager.jockey.try-existing-chickens", zombieVillagerJockeyTryExistingChickens);
zombieVillagerTakeDamageFromWater = getBoolean("mobs.zombie_villager.takes-damage-from-water", zombieVillagerTakeDamageFromWater);
+ zombieVillagerCuringTimeMin = getInt("mobs.zombie_villager.curing_time.min", zombieVillagerCuringTimeMin);
+ zombieVillagerCuringTimeMax = getInt("mobs.zombie_villager.curing_time.max", zombieVillagerCuringTimeMax);
}
public boolean zombifiedPiglinRidable = false;

View File

@@ -1,49 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 12emin34 <macanovic.emin@gmail.com>
Date: Sat, 7 Aug 2021 20:23:31 +0200
Subject: [PATCH] Option for sponges to work on lava and mud
Co-authored by: granny <granny@purpurmc.org>
diff --git a/src/main/java/net/minecraft/world/level/block/SpongeBlock.java b/src/main/java/net/minecraft/world/level/block/SpongeBlock.java
index a676ccfa6b02e8986df6f6a2e04cbb06b3edd0ff..6fe44572e34ad3e3a1851e73138bd8b778eb7849 100644
--- a/src/main/java/net/minecraft/world/level/block/SpongeBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/SpongeBlock.java
@@ -77,7 +77,7 @@ public class SpongeBlock extends Block {
FluidState fluid = blockList.getFluidState(blockposition1);
// CraftBukkit end
- if (!fluid.is(FluidTags.WATER)) {
+ if (!fluid.is(FluidTags.WATER) && (!world.purpurConfig.spongeAbsorbsLava || !fluid.is(FluidTags.LAVA)) && (!world.purpurConfig.spongeAbsorbsWaterFromMud || !iblockdata.is(Blocks.MUD))) { // Purpur
return false;
} else {
Block block = iblockdata.getBlock();
@@ -92,6 +92,10 @@ public class SpongeBlock extends Block {
if (iblockdata.getBlock() instanceof LiquidBlock) {
blockList.setBlock(blockposition1, Blocks.AIR.defaultBlockState(), 3); // CraftBukkit
+ // Purpur start
+ } else if (iblockdata.is(Blocks.MUD)) {
+ blockList.setBlock(blockposition1, Blocks.CLAY.defaultBlockState(), 3);
+ // Purpur end
} else {
if (!iblockdata.is(Blocks.KELP) && !iblockdata.is(Blocks.KELP_PLANT) && !iblockdata.is(Blocks.SEAGRASS) && !iblockdata.is(Blocks.TALL_SEAGRASS)) {
return false;
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index eb1d3a1045c580e8da95fdcb0c9fbd3c345ca9eb..ad26914101f87e81b6822860e15d011ad1db5daa 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -964,9 +964,13 @@ public class PurpurWorldConfig {
public int spongeAbsorptionArea = 65;
public int spongeAbsorptionRadius = 6;
+ public boolean spongeAbsorbsLava = false;
+ public boolean spongeAbsorbsWaterFromMud = false;
private void spongeSettings() {
spongeAbsorptionArea = getInt("blocks.sponge.absorption.area", spongeAbsorptionArea);
spongeAbsorptionRadius = getInt("blocks.sponge.absorption.radius", spongeAbsorptionRadius);
+ spongeAbsorbsLava = getBoolean("blocks.sponge.absorbs-lava", spongeAbsorbsLava);
+ spongeAbsorbsWaterFromMud = getBoolean("blocks.sponge.absorbs-water-from-mud", spongeAbsorbsWaterFromMud);
}
public boolean turtleEggsBreakFromExpOrbs = false;

View File

@@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 12emin34 <macanovic.emin@gmail.com>
Date: Sat, 7 Aug 2021 21:27:56 +0200
Subject: [PATCH] Toggle for Wither's spawn sound
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 c0d5fc670ff428a4293e8965068f52449a5c8b47..8d9154fc197e8604a5b07efe6b2aa76d7a122b0e 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
@@ -434,7 +434,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
}
// CraftBukkit end
- if (!this.isSilent()) {
+ if (!this.isSilent() && level().purpurConfig.witherPlaySpawnSound) {
// CraftBukkit start - Use relative location for far away sounds
// this.level().globalLevelEvent(1023, new BlockPosition(this), 0);
int viewDistance = ((ServerLevel) this.level()).getCraftServer().getViewDistance() * 16;
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index ad26914101f87e81b6822860e15d011ad1db5daa..4accff1edd89a299e6f8fc52be17e7680870220b 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -2781,6 +2781,7 @@ public class PurpurWorldConfig {
public boolean witherTakeDamageFromWater = false;
public boolean witherCanRideVehicles = false;
public float witherExplosionRadius = 1.0F;
+ public boolean witherPlaySpawnSound = true;
private void witherSettings() {
witherRidable = getBoolean("mobs.wither.ridable", witherRidable);
witherRidableInWater = getBoolean("mobs.wither.ridable-in-water", witherRidableInWater);
@@ -2803,6 +2804,7 @@ public class PurpurWorldConfig {
witherTakeDamageFromWater = getBoolean("mobs.wither.takes-damage-from-water", witherTakeDamageFromWater);
witherCanRideVehicles = getBoolean("mobs.wither.can-ride-vehicles", witherCanRideVehicles);
witherExplosionRadius = (float) getDouble("mobs.wither.explosion-radius", witherExplosionRadius);
+ witherPlaySpawnSound = getBoolean("mobs.wither.play-spawn-sound", witherPlaySpawnSound);
}
public boolean witherSkeletonRidable = false;

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 Aug 2021 03:37:56 -0500
Subject: [PATCH] Cactus breaks from solid neighbors config
diff --git a/src/main/java/net/minecraft/world/level/block/CactusBlock.java b/src/main/java/net/minecraft/world/level/block/CactusBlock.java
index ff4dda48116a2969704b355ff96407ba869b466e..9200d75b05ce535f7b7f5c1572cd8f6261c6955b 100644
--- a/src/main/java/net/minecraft/world/level/block/CactusBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/CactusBlock.java
@@ -114,7 +114,7 @@ public class CactusBlock extends Block {
enumdirection = (Direction) iterator.next();
iblockdata1 = world.getBlockState(pos.relative(enumdirection));
- } while (!iblockdata1.isSolid() && !world.getFluidState(pos.relative(enumdirection)).is(FluidTags.LAVA));
+ } while ((!world.getWorldBorder().world.purpurConfig.cactusBreaksFromSolidNeighbors || !iblockdata1.isSolid()) && !world.getFluidState(pos.relative(enumdirection)).is(FluidTags.LAVA)); // Purpur
return false;
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 4accff1edd89a299e6f8fc52be17e7680870220b..a0c3ebc4475f70320cf686c1bcc5d21efb46d551 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -805,6 +805,11 @@ public class PurpurWorldConfig {
});
}
+ public boolean cactusBreaksFromSolidNeighbors = true;
+ private void cactusSettings() {
+ cactusBreaksFromSolidNeighbors = getBoolean("blocks.cactus.breaks-from-solid-neighbors", cactusBreaksFromSolidNeighbors);
+ }
+
public boolean chestOpenWithBlockOnTop = false;
private void chestSettings() {
chestOpenWithBlockOnTop = getBoolean("blocks.chest.open-with-solid-block-on-top", chestOpenWithBlockOnTop);

View File

@@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Sun, 8 Aug 2021 16:59:21 -0400
Subject: [PATCH] Config to remove curse of binding with weakness
diff --git a/src/main/java/net/minecraft/world/inventory/ArmorSlot.java b/src/main/java/net/minecraft/world/inventory/ArmorSlot.java
index 6c0b6abb1698fac9bb902f695b725d4ab783ee90..091e3c3514fcb378b68098114106d09f04d8fb0d 100644
--- a/src/main/java/net/minecraft/world/inventory/ArmorSlot.java
+++ b/src/main/java/net/minecraft/world/inventory/ArmorSlot.java
@@ -45,7 +45,7 @@ class ArmorSlot extends Slot {
@Override
public boolean mayPickup(Player playerEntity) {
ItemStack itemStack = this.getItem();
- return (itemStack.isEmpty() || playerEntity.isCreative() || !EnchantmentHelper.has(itemStack, EnchantmentEffectComponents.PREVENT_ARMOR_CHANGE))
+ return (itemStack.isEmpty() || playerEntity.isCreative() || (!EnchantmentHelper.has(itemStack, EnchantmentEffectComponents.PREVENT_ARMOR_CHANGE) || playerEntity.level().purpurConfig.playerRemoveBindingWithWeakness && playerEntity.hasEffect(net.minecraft.world.effect.MobEffects.WEAKNESS)))
&& super.mayPickup(playerEntity);
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index a0c3ebc4475f70320cf686c1bcc5d21efb46d551..68140248e65a733768c4d6da79fde84a25836e70 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -397,6 +397,7 @@ public class PurpurWorldConfig {
public int playerBurpDelay = 10;
public boolean playerBurpWhenFull = false;
public boolean playerRidableInWater = false;
+ public boolean playerRemoveBindingWithWeakness = false;
private void playerSettings() {
if (PurpurConfig.version < 19) {
boolean oldVal = getBoolean("gameplay-mechanics.player.idle-timeout.mods-target", idleTimeoutTargetPlayer);
@@ -420,6 +421,7 @@ public class PurpurWorldConfig {
playerBurpDelay = getInt("gameplay-mechanics.player.burp-delay", playerBurpDelay);
playerBurpWhenFull = getBoolean("gameplay-mechanics.player.burp-when-full", playerBurpWhenFull);
playerRidableInWater = getBoolean("gameplay-mechanics.player.ridable-in-water", playerRidableInWater);
+ playerRemoveBindingWithWeakness = getBoolean("gameplay-mechanics.player.curse-of-binding.remove-with-weakness", playerRemoveBindingWithWeakness);
}
public boolean silkTouchEnabled = false;

View File

@@ -1,130 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Sun, 8 Aug 2021 18:14:31 -0400
Subject: [PATCH] Conduit behavior configuration
diff --git a/src/main/java/net/minecraft/world/level/block/entity/ConduitBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ConduitBlockEntity.java
index 73e532dc998e5701c1a73da846da3d3a79871b81..ff6fea842ca80c2ba51693fe62e5b74f9affdc19 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/ConduitBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/ConduitBlockEntity.java
@@ -168,7 +168,7 @@ public class ConduitBlockEntity extends BlockEntity {
if ((l > 1 || i1 > 1 || j1 > 1) && (i == 0 && (i1 == 2 || j1 == 2) || j == 0 && (l == 2 || j1 == 2) || k == 0 && (l == 2 || i1 == 2))) {
BlockPos blockposition2 = pos.offset(i, j, k);
BlockState iblockdata = world.getBlockState(blockposition2);
- Block[] ablock = ConduitBlockEntity.VALID_BLOCKS;
+ Block[] ablock = world.purpurConfig.conduitBlocks; // Purpur
int k1 = ablock.length;
for (int l1 = 0; l1 < k1; ++l1) {
@@ -188,13 +188,13 @@ public class ConduitBlockEntity extends BlockEntity {
private static void applyEffects(Level world, BlockPos pos, List<BlockPos> activatingBlocks) {
// CraftBukkit start
- ConduitBlockEntity.applyEffects(world, pos, ConduitBlockEntity.getRange(activatingBlocks));
+ ConduitBlockEntity.applyEffects(world, pos, ConduitBlockEntity.getRange(activatingBlocks, world)); // Purpur
}
- public static int getRange(List<BlockPos> list) {
+ public static int getRange(List<BlockPos> list, Level world) { // Purpur
// CraftBukkit end
int i = list.size();
- int j = i / 7 * 16;
+ int j = i / 7 * world.purpurConfig.conduitDistance; // Purpur
// CraftBukkit start
return j;
}
@@ -237,20 +237,20 @@ public class ConduitBlockEntity extends BlockEntity {
tileentityconduit.destroyTarget = ConduitBlockEntity.findDestroyTarget(world, blockposition, tileentityconduit.destroyTargetUUID);
tileentityconduit.destroyTargetUUID = null;
} else if (tileentityconduit.destroyTarget == null) {
- List<LivingEntity> list1 = world.getEntitiesOfClass(LivingEntity.class, ConduitBlockEntity.getDestroyRangeAABB(blockposition), (entityliving1) -> {
+ List<LivingEntity> list1 = world.getEntitiesOfClass(LivingEntity.class, ConduitBlockEntity.getDestroyRangeAABB(blockposition, world), (entityliving1) -> { // Purpur
return entityliving1 instanceof Enemy && entityliving1.isInWaterOrRain();
});
if (!list1.isEmpty()) {
tileentityconduit.destroyTarget = (LivingEntity) list1.get(world.random.nextInt(list1.size()));
}
- } else if (!tileentityconduit.destroyTarget.isAlive() || !blockposition.closerThan(tileentityconduit.destroyTarget.blockPosition(), 8.0D)) {
+ } else if (!tileentityconduit.destroyTarget.isAlive() || !blockposition.closerThan(tileentityconduit.destroyTarget.blockPosition(), world.purpurConfig.conduitDamageDistance)) { // Purpur
tileentityconduit.destroyTarget = null;
}
// CraftBukkit start
if (damageTarget && tileentityconduit.destroyTarget != null) {
- if (tileentityconduit.destroyTarget.hurt(world.damageSources().magic().directBlock(world, blockposition), 4.0F)) {
+ if (tileentityconduit.destroyTarget.hurt(world.damageSources().magic().directBlock(world, blockposition), world.purpurConfig.conduitDamageAmount)) { // Purpur
world.playSound(null, tileentityconduit.destroyTarget.getX(), tileentityconduit.destroyTarget.getY(), tileentityconduit.destroyTarget.getZ(), SoundEvents.CONDUIT_ATTACK_TARGET, SoundSource.BLOCKS, 1.0F, 1.0F);
}
// CraftBukkit end
@@ -275,16 +275,22 @@ public class ConduitBlockEntity extends BlockEntity {
}
public static AABB getDestroyRangeAABB(BlockPos pos) {
+ // Purpur start
+ return getDestroyRangeAABB(pos, null);
+ }
+
+ private static AABB getDestroyRangeAABB(BlockPos pos, Level level) {
+ // Purpur end
int i = pos.getX();
int j = pos.getY();
int k = pos.getZ();
- return (new AABB((double) i, (double) j, (double) k, (double) (i + 1), (double) (j + 1), (double) (k + 1))).inflate(8.0D);
+ return (new AABB((double) i, (double) j, (double) k, (double) (i + 1), (double) (j + 1), (double) (k + 1))).inflate(level == null ? 8.0D : level.purpurConfig.conduitDamageDistance); // Purpur
}
@Nullable
private static LivingEntity findDestroyTarget(Level world, BlockPos pos, UUID uuid) {
- List<LivingEntity> list = world.getEntitiesOfClass(LivingEntity.class, ConduitBlockEntity.getDestroyRangeAABB(pos), (entityliving) -> {
+ List<LivingEntity> list = world.getEntitiesOfClass(LivingEntity.class, ConduitBlockEntity.getDestroyRangeAABB(pos, world), (entityliving) -> { // Purpur
return entityliving.getUUID().equals(uuid);
});
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftConduit.java b/src/main/java/org/bukkit/craftbukkit/block/CraftConduit.java
index c1759aeb3e6ad0e4eb66cba3da1b120dd1dce812..1a91bc2e422db0eba65694ac046f1b362c6b0cd6 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftConduit.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftConduit.java
@@ -73,7 +73,7 @@ public class CraftConduit extends CraftBlockEntityState<ConduitBlockEntity> impl
public int getRange() {
this.ensureNoWorldGeneration();
ConduitBlockEntity conduit = (ConduitBlockEntity) this.getTileEntityFromWorld();
- return (conduit != null) ? ConduitBlockEntity.getRange(conduit.effectBlocks) : 0;
+ return (conduit != null) ? ConduitBlockEntity.getRange(conduit.effectBlocks, this.world.getHandle()) : 0; // Purpur
}
@Override
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 68140248e65a733768c4d6da79fde84a25836e70..9a157c1b29f216b596b52de974fa212033c0ce12 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -3015,4 +3015,27 @@ public class PurpurWorldConfig {
private void hungerSettings() {
hungerStarvationDamage = (float) getDouble("hunger.starvation-damage", hungerStarvationDamage);
}
+
+ public int conduitDistance = 16;
+ public double conduitDamageDistance = 8;
+ public float conduitDamageAmount = 4;
+ public Block[] conduitBlocks;
+ private void conduitSettings() {
+ conduitDistance = getInt("blocks.conduit.effect-distance", conduitDistance);
+ conduitDamageDistance = getDouble("blocks.conduit.mob-damage.distance", conduitDamageDistance);
+ conduitDamageAmount = (float) getDouble("blocks.conduit.mob-damage.damage-amount", conduitDamageAmount);
+ List<Block> conduitBlockList = new ArrayList<>();
+ getList("blocks.conduit.valid-ring-blocks", new ArrayList<String>(){{
+ add("minecraft:prismarine");
+ add("minecraft:prismarine_bricks");
+ add("minecraft:sea_lantern");
+ add("minecraft:dark_prismarine");
+ }}).forEach(key -> {
+ Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(key.toString()));
+ if (!block.defaultBlockState().isAir()) {
+ conduitBlockList.add(block);
+ }
+ });
+ conduitBlocks = conduitBlockList.toArray(Block[]::new);
+ }
}

View File

@@ -1,68 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Sun, 8 Aug 2021 18:38:44 -0400
Subject: [PATCH] Cauldron fill chances
diff --git a/src/main/java/net/minecraft/world/level/block/CauldronBlock.java b/src/main/java/net/minecraft/world/level/block/CauldronBlock.java
index c9968934f4ecaa8d81e545f279b3001c7b1ce545..03e4fce6f8226451365fc2831b5bf1e5e6091730 100644
--- a/src/main/java/net/minecraft/world/level/block/CauldronBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/CauldronBlock.java
@@ -37,7 +37,7 @@ public class CauldronBlock extends AbstractCauldronBlock {
}
protected static boolean shouldHandlePrecipitation(Level world, Biome.Precipitation precipitation) {
- return precipitation == Biome.Precipitation.RAIN ? world.getRandom().nextFloat() < 0.05F : (precipitation == Biome.Precipitation.SNOW ? world.getRandom().nextFloat() < 0.1F : false);
+ return precipitation == Biome.Precipitation.RAIN ? world.getRandom().nextFloat() < world.purpurConfig.cauldronRainChance : (precipitation == Biome.Precipitation.SNOW ? world.getRandom().nextFloat() < world.purpurConfig.cauldronPowderSnowChance : false); // Purpur
}
@Override
diff --git a/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java b/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java
index a2bd54dae4b0460d200f6d5300194a7ef5a28830..bf189a171530abfc9bba5db5a305feb391f2cbee 100644
--- a/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java
@@ -190,7 +190,7 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate
@VisibleForTesting
public static void maybeTransferFluid(BlockState state, ServerLevel world, BlockPos pos, float dripChance) {
- if (dripChance <= 0.17578125F || dripChance <= 0.05859375F) {
+ if (dripChance <= world.purpurConfig.cauldronDripstoneWaterFillChance || dripChance <= world.purpurConfig.cauldronDripstoneLavaFillChance) { // Purpur
if (PointedDripstoneBlock.isStalactiteStartPos(state, world, pos)) {
Optional<PointedDripstoneBlock.FluidInfo> optional = PointedDripstoneBlock.getFluidAboveStalactite(world, pos, state);
@@ -199,13 +199,13 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate
float f1;
if (fluidtype == Fluids.WATER) {
- f1 = 0.17578125F;
+ f1 = world.purpurConfig.cauldronDripstoneWaterFillChance; // Purpur
} else {
if (fluidtype != Fluids.LAVA) {
return;
}
- f1 = 0.05859375F;
+ f1 = world.purpurConfig.cauldronDripstoneLavaFillChance; // Purpur
}
if (dripChance < f1) {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 9a157c1b29f216b596b52de974fa212033c0ce12..69a4fb9e34ee36e8572456cead198432470874ff 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -3038,4 +3038,15 @@ public class PurpurWorldConfig {
});
conduitBlocks = conduitBlockList.toArray(Block[]::new);
}
+
+ public float cauldronRainChance = 0.05F;
+ public float cauldronPowderSnowChance = 0.1F;
+ public float cauldronDripstoneWaterFillChance = 0.17578125F;
+ public float cauldronDripstoneLavaFillChance = 0.05859375F;
+ private void cauldronSettings() {
+ cauldronRainChance = (float) getDouble("blocks.cauldron.fill-chances.rain", cauldronRainChance);
+ cauldronPowderSnowChance = (float) getDouble("blocks.cauldron.fill-chances.powder-snow", cauldronPowderSnowChance);
+ cauldronDripstoneWaterFillChance = (float) getDouble("blocks.cauldron.fill-chances.dripstone-water", cauldronDripstoneWaterFillChance);
+ cauldronDripstoneLavaFillChance = (float) getDouble("blocks.cauldron.fill-chances.dripstone-lava", cauldronDripstoneLavaFillChance);
+ }
}

View File

@@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Sun, 8 Aug 2021 22:50:23 -0400
Subject: [PATCH] Config to allow mobs to pathfind over rails
diff --git a/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java b/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java
index d5004290e40a1ff5e0fcfe75f8da34ae15962359..31ae0f466ae522d767907ec5066b26695f327b96 100644
--- a/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java
+++ b/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java
@@ -240,7 +240,7 @@ public class WalkNodeEvaluator extends NodeEvaluator {
if ((node == null || node.costMalus < 0.0F)
&& maxYStep > 0
&& (pathType != PathType.FENCE || this.canWalkOverFences())
- && pathType != PathType.UNPASSABLE_RAIL
+ && (this.mob.level().purpurConfig.mobsIgnoreRails || pathType != PathType.UNPASSABLE_RAIL) // Purpur
&& pathType != PathType.TRAPDOOR
&& pathType != PathType.POWDER_SNOW) {
node = this.tryJumpOn(x, y, z, maxYStep, prevFeetY, direction, nodeType, mutableBlockPos);
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 69a4fb9e34ee36e8572456cead198432470874ff..a08e091b918c29d2041d717ef3fe284ef9281d64 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -139,6 +139,7 @@ public class PurpurWorldConfig {
public double tridentLoyaltyVoidReturnHeight = 0.0D;
public int raidCooldownSeconds = 0;
public int animalBreedingCooldownSeconds = 0;
+ public boolean mobsIgnoreRails = false;
private void miscGameplayMechanicsSettings() {
useBetterMending = getBoolean("gameplay-mechanics.use-better-mending", useBetterMending);
alwaysTameInCreative = getBoolean("gameplay-mechanics.always-tame-in-creative", alwaysTameInCreative);
@@ -160,6 +161,7 @@ public class PurpurWorldConfig {
tridentLoyaltyVoidReturnHeight = getDouble("gameplay-mechanics.trident-loyalty-void-return-height", tridentLoyaltyVoidReturnHeight);
raidCooldownSeconds = getInt("gameplay-mechanics.raid-cooldown-seconds", raidCooldownSeconds);
animalBreedingCooldownSeconds = getInt("gameplay-mechanics.animal-breeding-cooldown-seconds", animalBreedingCooldownSeconds);
+ mobsIgnoreRails = getBoolean("gameplay-mechanics.mobs-ignore-rails", mobsIgnoreRails);
}
public int daytimeTicks = 12000;

View File

@@ -1,50 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sat, 21 Aug 2021 00:07:39 -0500
Subject: [PATCH] Shulker change color with dye
diff --git a/src/main/java/net/minecraft/world/entity/monster/Shulker.java b/src/main/java/net/minecraft/world/entity/monster/Shulker.java
index 6f1deb4d26c851ca99fbadf1eb5b7847eadbf25b..099d6ce14d9c2fa0af1e9bf96c09cd3d44bc4cc8 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Shulker.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Shulker.java
@@ -125,6 +125,19 @@ public class Shulker extends AbstractGolem implements VariantHolder<Optional<Dye
return this.level().purpurConfig.shulkerTakeDamageFromWater;
}
+ @Override
+ protected net.minecraft.world.InteractionResult mobInteract(Player player, net.minecraft.world.InteractionHand hand) {
+ net.minecraft.world.item.ItemStack itemstack = player.getItemInHand(hand);
+ if (player.level().purpurConfig.shulkerChangeColorWithDye && itemstack.getItem() instanceof net.minecraft.world.item.DyeItem dye && dye.getDyeColor() != this.getColor()) {
+ this.setVariant(Optional.of(dye.getDyeColor()));
+ if (!player.getAbilities().instabuild) {
+ itemstack.shrink(1);
+ }
+ return net.minecraft.world.InteractionResult.SUCCESS;
+ }
+ return super.mobInteract(player, hand);
+ }
+
@Override
protected void registerGoals() {
this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index a08e091b918c29d2041d717ef3fe284ef9281d64..369ea95c71d1313a49e75f06bff7aa095eb50e8b 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -2307,6 +2307,7 @@ public class PurpurWorldConfig {
public double shulkerSpawnFromBulletNearbyRange = 8.0D;
public String shulkerSpawnFromBulletNearbyEquation = "(nearby - 1) / 5.0";
public boolean shulkerSpawnFromBulletRandomColor = false;
+ public boolean shulkerChangeColorWithDye = false;
private void shulkerSettings() {
shulkerRidable = getBoolean("mobs.shulker.ridable", shulkerRidable);
shulkerRidableInWater = getBoolean("mobs.shulker.ridable-in-water", shulkerRidableInWater);
@@ -2324,6 +2325,7 @@ public class PurpurWorldConfig {
shulkerSpawnFromBulletNearbyRange = getDouble("mobs.shulker.spawn-from-bullet.nearby-range", shulkerSpawnFromBulletNearbyRange);
shulkerSpawnFromBulletNearbyEquation = getString("mobs.shulker.spawn-from-bullet.nearby-equation", shulkerSpawnFromBulletNearbyEquation);
shulkerSpawnFromBulletRandomColor = getBoolean("mobs.shulker.spawn-from-bullet.random-color", shulkerSpawnFromBulletRandomColor);
+ shulkerChangeColorWithDye = getBoolean("mobs.shulker.change-color-with-dye", shulkerChangeColorWithDye);
}
public boolean silverfishRidable = false;