mirror of
https://github.com/PurpurMC/Purpur.git
synced 2026-06-22 18:27:46 +02:00
Upstream Paper's upgrade to vineflower 12.0.0 (#1782)
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
|
||||
public CrashReport(final String title, final Throwable t) {
|
||||
this.title = title;
|
||||
@@ -129,7 +_,7 @@
|
||||
@@ -126,7 +_,7 @@
|
||||
}
|
||||
|
||||
public String getFriendlyReport(final ReportType reportType) {
|
||||
@@ -17,7 +17,7 @@
|
||||
}
|
||||
|
||||
public @Nullable Path getSaveFile() {
|
||||
@@ -159,7 +_,7 @@
|
||||
@@ -156,7 +_,7 @@
|
||||
}
|
||||
|
||||
public boolean saveToFile(final Path file, final ReportType reportType) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/commands/Commands.java
|
||||
+++ b/net/minecraft/commands/Commands.java
|
||||
@@ -268,11 +_,11 @@
|
||||
@@ -267,11 +_,11 @@
|
||||
JfrCommand.register(this.dispatcher);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
RaidCommand.register(this.dispatcher, context);
|
||||
DebugPathCommand.register(this.dispatcher);
|
||||
DebugMobSpawningCommand.register(this.dispatcher);
|
||||
@@ -300,6 +_,14 @@
|
||||
@@ -299,6 +_,14 @@
|
||||
StopCommand.register(this.dispatcher);
|
||||
TransferCommand.register(this.dispatcher);
|
||||
WhitelistCommand.register(this.dispatcher);
|
||||
@@ -29,7 +29,7 @@
|
||||
}
|
||||
|
||||
if (commandSelection.includeIntegrated) {
|
||||
@@ -522,6 +_,7 @@
|
||||
@@ -521,6 +_,7 @@
|
||||
private void runSync(ServerPlayer player, java.util.Collection<String> bukkit, RootCommandNode<CommandSourceStack> root) {
|
||||
// Paper end - Perf: Async command map building
|
||||
new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent<CommandSourceStack>(player.getBukkitEntity(), (RootCommandNode) root, true).callEvent(); // Paper - Brigadier API
|
||||
@@ -37,7 +37,7 @@
|
||||
org.bukkit.event.player.PlayerCommandSendEvent event = new org.bukkit.event.player.PlayerCommandSendEvent(player.getBukkitEntity(), new java.util.LinkedHashSet<>(bukkit));
|
||||
event.getPlayer().getServer().getPluginManager().callEvent(event);
|
||||
|
||||
@@ -532,6 +_,8 @@
|
||||
@@ -531,6 +_,8 @@
|
||||
}
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
@@ -1,38 +1,42 @@
|
||||
--- a/net/minecraft/commands/arguments/selector/EntitySelector.java
|
||||
+++ b/net/minecraft/commands/arguments/selector/EntitySelector.java
|
||||
@@ -206,26 +_,27 @@
|
||||
@@ -210,30 +_,31 @@
|
||||
this.checkPermissions(sender);
|
||||
if (this.playerName != null) {
|
||||
ServerPlayer result = sender.getServer().getPlayerList().getPlayerByName(this.playerName);
|
||||
- return result == null ? List.of() : List.of(result);
|
||||
+ return result == null || !canSee(sender, result) ? List.of() : List.of(result); // Purpur - Hide hidden players from entity selector
|
||||
} else if (this.entityUUID != null) {
|
||||
}
|
||||
|
||||
if (this.entityUUID != null) {
|
||||
ServerPlayer result = sender.getServer().getPlayerList().getPlayer(this.entityUUID);
|
||||
- return result == null ? List.of() : List.of(result);
|
||||
+ return result == null || !canSee(sender, result) ? List.of() : List.of(result); // Purpur - Hide hidden players from entity selector
|
||||
} else {
|
||||
Vec3 pos = this.position.apply(sender.getPosition());
|
||||
AABB absoluteAabb = this.getAbsoluteAabb(pos);
|
||||
Predicate<Entity> predicate = this.getPredicate(pos, absoluteAabb, null);
|
||||
if (this.currentEntity) {
|
||||
- return sender.getEntity() instanceof ServerPlayer player && predicate.test(player) ? List.of(player) : List.of();
|
||||
+ return sender.getEntity() instanceof ServerPlayer player && predicate.test(player) && canSee(sender, player) ? List.of(player) : List.of(); // Purpur - Hide hidden players from entity selector
|
||||
} else {
|
||||
int limit = this.getResultLimit();
|
||||
List<ServerPlayer> result;
|
||||
if (this.isWorldLimited()) {
|
||||
result = sender.getLevel().getPlayers(predicate, limit);
|
||||
+ result.removeIf(entityplayer3 -> !canSee(sender, entityplayer3)); // Purpur - Hide hidden players from entity selector
|
||||
} else {
|
||||
result = new ObjectArrayList<>();
|
||||
}
|
||||
|
||||
for (ServerPlayer player : sender.getServer().getPlayerList().getPlayers()) {
|
||||
- if (predicate.test(player)) {
|
||||
+ if (predicate.test(player) && canSee(sender, player)) { // Purpur - Hide hidden players from entity selector
|
||||
result.add(player);
|
||||
if (result.size() >= limit) {
|
||||
return result;
|
||||
@@ -283,4 +_,10 @@
|
||||
Vec3 pos = this.position.apply(sender.getPosition());
|
||||
AABB absoluteAabb = this.getAbsoluteAabb(pos);
|
||||
Predicate<Entity> predicate = this.getPredicate(pos, absoluteAabb, null);
|
||||
if (this.currentEntity) {
|
||||
- return sender.getEntity() instanceof ServerPlayer player && predicate.test(player) ? List.of(player) : List.of();
|
||||
+ return sender.getEntity() instanceof ServerPlayer player && predicate.test(player) && canSee(sender, player) ? List.of(player) : List.of(); // Purpur - Hide hidden players from entity selector
|
||||
}
|
||||
|
||||
int limit = this.getResultLimit();
|
||||
List<ServerPlayer> result;
|
||||
if (this.isWorldLimited()) {
|
||||
result = sender.getLevel().getPlayers(predicate, limit);
|
||||
+ result.removeIf(entityplayer3 -> !canSee(sender, entityplayer3)); // Purpur - Hide hidden players from entity selector
|
||||
} else {
|
||||
result = new ObjectArrayList<>();
|
||||
|
||||
for (ServerPlayer player : sender.getServer().getPlayerList().getPlayers()) {
|
||||
- if (predicate.test(player)) {
|
||||
+ if (predicate.test(player) && canSee(sender, player)) { // Purpur - Hide hidden players from entity selector
|
||||
result.add(player);
|
||||
if (result.size() >= limit) {
|
||||
return result;
|
||||
@@ -289,4 +_,10 @@
|
||||
public static Component joinNames(final List<? extends Entity> entities) {
|
||||
return ComponentUtils.formatList(entities, Entity::getDisplayName);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/core/dispenser/DispenseItemBehavior.java
|
||||
+++ b/net/minecraft/core/dispenser/DispenseItemBehavior.java
|
||||
@@ -691,5 +_,22 @@
|
||||
@@ -683,5 +_,22 @@
|
||||
DispenserBlock.registerBehavior(Items.TNT_MINECART, new MinecartDispenseItemBehavior(EntityType.TNT_MINECART));
|
||||
DispenserBlock.registerBehavior(Items.HOPPER_MINECART, new MinecartDispenseItemBehavior(EntityType.HOPPER_MINECART));
|
||||
DispenserBlock.registerBehavior(Items.COMMAND_BLOCK_MINECART, new MinecartDispenseItemBehavior(EntityType.COMMAND_BLOCK_MINECART));
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
--- a/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java
|
||||
+++ b/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java
|
||||
@@ -31,7 +_,7 @@
|
||||
return false;
|
||||
} else {
|
||||
LivingEntity target = entities.getFirst();
|
||||
- EquipmentSlot slot = target.getEquipmentSlotForItem(dispensed);
|
||||
+ EquipmentSlot slot = source.level().purpurConfig.dispenserApplyCursedArmor ? target.getEquipmentSlotForItem(dispensed) : target.getEquipmentSlotForDispenserItem(dispensed); if (slot == null) return false; // Purpur - Dispenser curse of binding protection
|
||||
ItemStack equip = dispensed.copyWithCount(1); // Paper - shrink below and single item in event
|
||||
// CraftBukkit start
|
||||
net.minecraft.world.level.Level world = source.level();
|
||||
@@ -32,7 +_,7 @@
|
||||
}
|
||||
|
||||
LivingEntity target = entities.getFirst();
|
||||
- EquipmentSlot slot = target.getEquipmentSlotForItem(dispensed);
|
||||
+ EquipmentSlot slot = source.level().purpurConfig.dispenserApplyCursedArmor ? target.getEquipmentSlotForItem(dispensed) : target.getEquipmentSlotForDispenserItem(dispensed); if (slot == null) return false; // Purpur - Dispenser curse of binding protection
|
||||
ItemStack equip = dispensed.copyWithCount(1); // Paper - shrink below and single item in event
|
||||
// CraftBukkit start
|
||||
net.minecraft.world.level.Level world = source.level();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/gametest/framework/GameTestHelper.java
|
||||
+++ b/net/minecraft/gametest/framework/GameTestHelper.java
|
||||
@@ -354,6 +_,8 @@
|
||||
@@ -352,6 +_,8 @@
|
||||
return gameType;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/network/Connection.java
|
||||
+++ b/net/minecraft/network/Connection.java
|
||||
@@ -554,11 +_,20 @@
|
||||
@@ -552,11 +_,20 @@
|
||||
private static final int MAX_PER_TICK = io.papermc.paper.configuration.GlobalConfiguration.get().misc.maxJoinsPerTick; // Paper - Buffer joins to world
|
||||
private static int joinAttemptsThisTick; // Paper - Buffer joins to world
|
||||
private static int currTick; // Paper - Buffer joins to world
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
--- a/net/minecraft/network/chat/SignedMessageChain.java
|
||||
+++ b/net/minecraft/network/chat/SignedMessageChain.java
|
||||
@@ -49,7 +_,7 @@
|
||||
SignedMessageLink link = SignedMessageChain.this.nextLink;
|
||||
if (link == null) {
|
||||
throw new SignedMessageChain.DecodeException(SignedMessageChain.DecodeException.CHAIN_BROKEN);
|
||||
- } else if (body.timeStamp().isBefore(SignedMessageChain.this.lastTimeStamp)) {
|
||||
+ } else if (org.purpurmc.purpur.PurpurConfig.kickForOutOfOrderChat && body.timeStamp().isBefore(SignedMessageChain.this.lastTimeStamp)) { // Purpur - Option to disable kick for out of order chat
|
||||
this.setChainBroken();
|
||||
throw new SignedMessageChain.DecodeException(SignedMessageChain.DecodeException.OUT_OF_ORDER_CHAT, org.bukkit.event.player.PlayerKickEvent.Cause.OUT_OF_ORDER_CHAT); // Paper - kick event causes
|
||||
} else {
|
||||
throw new SignedMessageChain.DecodeException(SignedMessageChain.DecodeException.CHAIN_BROKEN);
|
||||
}
|
||||
|
||||
- if (body.timeStamp().isBefore(SignedMessageChain.this.lastTimeStamp)) {
|
||||
+ if (org.purpurmc.purpur.PurpurConfig.kickForOutOfOrderChat && body.timeStamp().isBefore(SignedMessageChain.this.lastTimeStamp)) { // Purpur - Option to disable kick for out of order chat
|
||||
this.setChainBroken();
|
||||
throw new SignedMessageChain.DecodeException(SignedMessageChain.DecodeException.OUT_OF_ORDER_CHAT, org.bukkit.event.player.PlayerKickEvent.Cause.OUT_OF_ORDER_CHAT); // Paper - kick event causes
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
getTPS(this.tickTimes1m, interval),
|
||||
getTPS(this.tickTimes5m, interval),
|
||||
getTPS(this.tickTimes15m, interval)
|
||||
@@ -1057,6 +_,15 @@
|
||||
@@ -1047,6 +_,15 @@
|
||||
|
||||
LOGGER.info("Stopping server");
|
||||
Commands.COMMAND_SENDING_POOL.shutdownNow(); // Paper - Perf: Async command map building; Shutdown and don't bother finishing
|
||||
@@ -41,7 +41,7 @@
|
||||
// CraftBukkit start
|
||||
if (this.server != null) {
|
||||
this.server.spark.disable(); // Paper - spark
|
||||
@@ -1151,6 +_,8 @@
|
||||
@@ -1141,6 +_,8 @@
|
||||
this.safeShutdown(wait, false);
|
||||
}
|
||||
public void safeShutdown(final boolean wait, final boolean isRestarting) {
|
||||
@@ -50,7 +50,7 @@
|
||||
this.isRestarting = isRestarting;
|
||||
this.hasLoggedStop = true; // Paper - Debugging
|
||||
if (this.isDebugging()) io.papermc.paper.util.TraceUtil.dumpTraceForThread("Server stopped"); // Paper - Debugging
|
||||
@@ -1332,11 +_,21 @@
|
||||
@@ -1322,11 +_,21 @@
|
||||
}
|
||||
// Paper end - Add onboarding message for initial server start
|
||||
// Paper start - Improve outdated version checking
|
||||
@@ -73,7 +73,7 @@
|
||||
while (this.running) {
|
||||
final long tickStart = System.nanoTime(); // Paper - improve tick loop
|
||||
long thisTickNanos; // Paper - improve tick loop - diff on change, expect this to be tick interval
|
||||
@@ -1350,9 +_,11 @@
|
||||
@@ -1340,9 +_,11 @@
|
||||
final long ticksBehind = Math.max(1L, this.tickSchedule.getPeriodsAhead(thisTickNanos, tickStart));
|
||||
final long catchup = (long)Math.max(
|
||||
1,
|
||||
@@ -86,7 +86,7 @@
|
||||
// adjust ticksBehind so that it is not greater-than catchup
|
||||
if (ticksBehind - catchup > 0L) {
|
||||
final long difference = ticksBehind - catchup;
|
||||
@@ -1983,7 +_,7 @@
|
||||
@@ -1973,7 +_,7 @@
|
||||
}
|
||||
|
||||
public String getServerModName() {
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
- if (level > enchantment.getMaxLevel()) {
|
||||
+ if (!org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && level > enchantment.getMaxLevel()) { // Purpur - Config to allow unsafe enchants
|
||||
throw ERROR_LEVEL_TOO_HIGH.create(level, enchantment.getMaxLevel());
|
||||
} else {
|
||||
int success = 0;
|
||||
@@ -77,7 +_,7 @@
|
||||
ItemStack item = target.getMainHandItem();
|
||||
if (!item.isEmpty()) {
|
||||
if (enchantment.canEnchant(item)
|
||||
- && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(item).keySet(), enchantmentHolder)) {
|
||||
+ && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(item).keySet(), enchantmentHolder) || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && !item.hasEnchantment(enchantmentHolder))) { // Purpur - Config to allow unsafe enchants
|
||||
item.enchant(enchantmentHolder, level);
|
||||
success++;
|
||||
} else if (targets.size() == 1) {
|
||||
}
|
||||
|
||||
@@ -78,7 +_,7 @@
|
||||
ItemStack item = target.getMainHandItem();
|
||||
if (!item.isEmpty()) {
|
||||
if (enchantment.canEnchant(item)
|
||||
- && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(item).keySet(), enchantmentHolder)) {
|
||||
+ && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(item).keySet(), enchantmentHolder) || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && !item.hasEnchantment(enchantmentHolder))) { // Purpur - Config to allow unsafe enchants
|
||||
item.enchant(enchantmentHolder, level);
|
||||
success++;
|
||||
} else if (targets.size() == 1) {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
--- a/net/minecraft/server/commands/GiveCommand.java
|
||||
+++ b/net/minecraft/server/commands/GiveCommand.java
|
||||
@@ -61,6 +_,7 @@
|
||||
remaining -= size;
|
||||
ItemStack copyToDrop = prototypeItemStack.copyWithCount(size);
|
||||
boolean added = player.getInventory().add(copyToDrop);
|
||||
+ if (org.purpurmc.purpur.PurpurConfig.disableGiveCommandDrops) continue; // Purpur - add config option for toggling give command dropping
|
||||
if (added && copyToDrop.isEmpty()) {
|
||||
ItemEntity drop = player.drop(prototypeItemStack.copy(), false, false, false, null); // Paper - do not fire PlayerDropItemEvent for /give command
|
||||
if (drop != null) {
|
||||
@@ -62,6 +_,7 @@
|
||||
remaining -= size;
|
||||
ItemStack copyToDrop = prototypeItemStack.copyWithCount(size);
|
||||
boolean added = player.getInventory().add(copyToDrop);
|
||||
+ if (org.purpurmc.purpur.PurpurConfig.disableGiveCommandDrops) continue; // Purpur - add config option for toggling give command dropping
|
||||
if (added && copyToDrop.isEmpty()) {
|
||||
ItemEntity drop = player.drop(prototypeItemStack.copy(), false, false, false, null); // Paper - do not fire PlayerDropItemEvent for /give command
|
||||
if (drop != null) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -216,6 +_,7 @@
|
||||
@@ -211,6 +_,7 @@
|
||||
public void run() {
|
||||
if (!org.bukkit.craftbukkit.Main.useConsole) return; // CraftBukkit
|
||||
// Paper start - Use TerminalConsoleAppender
|
||||
@@ -8,7 +8,7 @@
|
||||
new com.destroystokyo.paper.console.PaperConsole(DedicatedServer.this).start();
|
||||
/*
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));
|
||||
@@ -294,6 +_,15 @@
|
||||
@@ -289,6 +_,15 @@
|
||||
io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command
|
||||
this.server.spark.registerCommandBeforePlugins(this.server); // Paper - spark
|
||||
com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics
|
||||
@@ -24,8 +24,8 @@
|
||||
com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now
|
||||
|
||||
// this.worldData.setGameType(properties.gameMode.get()); // CraftBukkit - moved to world loading
|
||||
@@ -336,6 +_,30 @@
|
||||
if (true) throw new IllegalStateException("Failed to bind to port", var11); // Paper - Propagate failed to bind to port error
|
||||
@@ -331,6 +_,30 @@
|
||||
if (true) throw new IllegalStateException("Failed to bind to port", e); // Paper - Propagate failed to bind to port error
|
||||
return false;
|
||||
}
|
||||
+ // Purpur start - UPnP Port Forwarding
|
||||
@@ -55,13 +55,13 @@
|
||||
|
||||
// CraftBukkit start
|
||||
this.server.loadPlugins();
|
||||
@@ -410,6 +_,9 @@
|
||||
MinecraftServerStatistics.registerJmxMonitoring(this);
|
||||
LOGGER.info("JMX monitoring enabled");
|
||||
}
|
||||
@@ -406,6 +_,9 @@
|
||||
MinecraftServerStatistics.registerJmxMonitoring(this);
|
||||
LOGGER.info("JMX monitoring enabled");
|
||||
}
|
||||
+
|
||||
+ org.purpurmc.purpur.task.BossBarTask.startAll(); // Purpur - Implement TPSBar
|
||||
+ if (org.purpurmc.purpur.PurpurConfig.beeCountPayload) org.purpurmc.purpur.task.BeehiveTask.instance().register(); // Purpur - Give bee counts in beehives to Purpur clients
|
||||
+ org.purpurmc.purpur.task.BossBarTask.startAll(); // Purpur - Implement TPSBar
|
||||
+ if (org.purpurmc.purpur.PurpurConfig.beeCountPayload) org.purpurmc.purpur.task.BeehiveTask.instance().register(); // Purpur - Give bee counts in beehives to Purpur clients
|
||||
|
||||
this.saveEverything(false, true, true);
|
||||
this.notificationManager().serverStarted();
|
||||
this.saveEverything(false, true, true);
|
||||
this.notificationManager().serverStarted();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/gui/MinecraftServerGui.java
|
||||
+++ b/net/minecraft/server/gui/MinecraftServerGui.java
|
||||
@@ -40,6 +_,11 @@
|
||||
@@ -39,6 +_,11 @@
|
||||
private Thread logAppenderThread;
|
||||
private final Collection<Runnable> finalizers = Lists.newArrayList();
|
||||
private final AtomicBoolean isClosing = new AtomicBoolean();
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
public static MinecraftServerGui showFrameFor(final DedicatedServer server) {
|
||||
try {
|
||||
@@ -47,7 +_,7 @@
|
||||
@@ -46,7 +_,7 @@
|
||||
} catch (Exception var3) {
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
final MinecraftServerGui gui = new MinecraftServerGui(server);
|
||||
frame.setDefaultCloseOperation(2);
|
||||
frame.add(gui);
|
||||
@@ -55,7 +_,7 @@
|
||||
@@ -54,7 +_,7 @@
|
||||
frame.setLocationRelativeTo(null);
|
||||
frame.setVisible(true);
|
||||
// Paper start - Improve ServerGUI
|
||||
@@ -30,7 +30,7 @@
|
||||
try {
|
||||
frame.setIconImage(javax.imageio.ImageIO.read(java.util.Objects.requireNonNull(MinecraftServerGui.class.getClassLoader().getResourceAsStream("logo.png"))));
|
||||
} catch (java.io.IOException ignore) {
|
||||
@@ -65,7 +_,7 @@
|
||||
@@ -64,7 +_,7 @@
|
||||
@Override
|
||||
public void windowClosing(final WindowEvent event) {
|
||||
if (!gui.isClosing.getAndSet(true)) {
|
||||
@@ -39,7 +39,7 @@
|
||||
server.halt(true);
|
||||
gui.runFinalizers();
|
||||
}
|
||||
@@ -113,7 +_,7 @@
|
||||
@@ -112,7 +_,7 @@
|
||||
|
||||
private JComponent buildChatPanel() {
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
@@ -48,7 +48,7 @@
|
||||
JScrollPane scrollPane = new JScrollPane(chatArea, 22, 30);
|
||||
chatArea.setEditable(false);
|
||||
chatArea.setFont(MONOSPACED);
|
||||
@@ -122,10 +_,43 @@
|
||||
@@ -121,10 +_,43 @@
|
||||
String text = chatField.getText().trim();
|
||||
if (!text.isEmpty()) {
|
||||
this.server.handleConsoleInput(text, this.server.createCommandSourceStack());
|
||||
@@ -90,9 +90,9 @@
|
||||
+ });
|
||||
+ // Purpur end - GUI Improvements
|
||||
chatArea.addFocusListener(new FocusAdapter() {
|
||||
{
|
||||
Objects.requireNonNull(MinecraftServerGui.this);
|
||||
@@ -164,7 +_,7 @@
|
||||
@Override
|
||||
public void focusGained(final FocusEvent arg0) {
|
||||
@@ -159,7 +_,7 @@
|
||||
}
|
||||
|
||||
private static final java.util.regex.Pattern ANSI = java.util.regex.Pattern.compile("\\e\\[[\\d;]*[^\\d;]"); // CraftBukkit // Paper
|
||||
@@ -101,7 +101,7 @@
|
||||
if (!SwingUtilities.isEventDispatchThread()) {
|
||||
SwingUtilities.invokeLater(() -> this.print(console, scrollPane, line));
|
||||
} else {
|
||||
@@ -175,16 +_,29 @@
|
||||
@@ -170,16 +_,29 @@
|
||||
shouldScroll = scrollBar.getValue() + scrollBar.getSize().getHeight() + MONOSPACED.getSize() * 4 > scrollBar.getMaximum();
|
||||
}
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@
|
||||
? this.getDestroyType(GameRules.MOB_EXPLOSION_DROP_DECAY)
|
||||
: Explosion.BlockInteraction.KEEP;
|
||||
case TNT -> this.getDestroyType(GameRules.TNT_EXPLOSION_DROP_DECAY);
|
||||
@@ -2919,7 +_,7 @@
|
||||
@@ -2914,7 +_,7 @@
|
||||
// Spigot start
|
||||
if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder && (!(entity instanceof ServerPlayer) || entity.getRemovalReason() != Entity.RemovalReason.KILLED)) { // SPIGOT-6876: closeInventory clears death message
|
||||
// Paper start - Fix merchant inventory not closing on entity removal
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -454,6 +_,9 @@
|
||||
@@ -435,6 +_,9 @@
|
||||
public boolean isRealPlayer; // Paper
|
||||
public com.destroystokyo.paper.event.entity.@Nullable PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent
|
||||
public org.bukkit.event.player.PlayerQuitEvent.@Nullable 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
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
// Paper start - rewrite chunk system
|
||||
private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader;
|
||||
@@ -527,6 +_,9 @@
|
||||
@@ -508,6 +_,9 @@
|
||||
this.respawnConfig = input.read("respawn", ServerPlayer.RespawnConfig.CODEC).orElse(null);
|
||||
this.spawnExtraParticlesOnFall = input.getBooleanOr("spawn_extra_particles_on_fall", false);
|
||||
this.raidOmenPosition = input.read("raid_omen_position", BlockPos.CODEC).orElse(null);
|
||||
@@ -20,7 +20,7 @@
|
||||
// Paper start - Expand PlayerGameModeChangeEvent
|
||||
this.loadGameTypes(input);
|
||||
}
|
||||
@@ -568,6 +_,9 @@
|
||||
@@ -549,6 +_,9 @@
|
||||
output.store("ShoulderEntityRight", CompoundTag.CODEC, this.getShoulderEntityRight());
|
||||
}
|
||||
this.getBukkitEntity().setExtraData(output); // CraftBukkit
|
||||
@@ -30,7 +30,7 @@
|
||||
}
|
||||
|
||||
private void saveParentVehicle(final ValueOutput playerOutput) {
|
||||
@@ -1203,6 +_,7 @@
|
||||
@@ -1179,6 +_,7 @@
|
||||
// Paper - moved up to sendClientboundPlayerCombatKillPacket()
|
||||
sendClientboundPlayerCombatKillPacket(event.getShowDeathMessages(), deathScreenMessage); // Paper - Expand PlayerDeathEvent
|
||||
Team team = this.getTeam();
|
||||
@@ -38,59 +38,66 @@
|
||||
if (team == null || team.getDeathMessageVisibility() == Team.Visibility.ALWAYS) {
|
||||
this.server.getPlayerList().broadcastSystemMessage(deathMessage, false);
|
||||
} else if (team.getDeathMessageVisibility() == Team.Visibility.HIDE_FOR_OTHER_TEAMS) {
|
||||
@@ -1311,6 +_,13 @@
|
||||
if (this.isInvulnerableTo(level, source)) {
|
||||
@@ -1288,6 +_,13 @@
|
||||
return false;
|
||||
} else {
|
||||
+ // Purpur start - Add boat fall damage config
|
||||
+ if (source.is(net.minecraft.tags.DamageTypeTags.IS_FALL)) {
|
||||
+ if (getRootVehicle() instanceof net.minecraft.world.entity.vehicle.boat.Boat && !level().purpurConfig.boatsDoFallDamage) {
|
||||
+ return false;
|
||||
+ }
|
||||
}
|
||||
|
||||
+ // Purpur start - Add boat fall damage config
|
||||
+ if (source.is(net.minecraft.tags.DamageTypeTags.IS_FALL)) {
|
||||
+ if (getRootVehicle() instanceof net.minecraft.world.entity.vehicle.boat.Boat && !level().purpurConfig.boatsDoFallDamage) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Purpur end - Add boat fall damage config
|
||||
Entity entity = source.getEntity();
|
||||
if (!( // Paper - split the if statement. If below statement is false, hurtServer would not have been evaluated. Return false.
|
||||
!(entity instanceof Player playerx && !this.canHarmPlayer(playerx))
|
||||
@@ -1570,6 +_,7 @@
|
||||
+ }
|
||||
+ // Purpur end - Add boat fall damage config
|
||||
Entity entity = source.getEntity();
|
||||
if (!( // Paper - split the if statement. If below statement is false, hurtServer would not have been evaluated. Return false.
|
||||
!(entity instanceof Player player && !this.canHarmPlayer(player))
|
||||
@@ -1529,7 +_,7 @@
|
||||
}
|
||||
|
||||
profiler.pop();
|
||||
profiler.push("placing");
|
||||
+ this.portalPos = org.bukkit.craftbukkit.util.CraftLocation.toBlockPos(exit); // Purpur - Fix stuck in portals
|
||||
this.setServerLevel(newLevel);
|
||||
this.connection.internalTeleport(PositionMoveRotation.of(transition), transition.relatives()); // CraftBukkit - use internal teleport without event
|
||||
this.connection.resetPosition();
|
||||
@@ -1686,7 +_,7 @@
|
||||
),
|
||||
monster -> monster.isPreventingPlayerRest(this.level(), this)
|
||||
);
|
||||
- if (!monsters.isEmpty()) {
|
||||
+ if (!this.level().purpurConfig.playerSleepNearMonsters && !monsters.isEmpty()) { // Purpur - Config to ignore nearby mobs when sleeping
|
||||
return Either.left(Player.BedSleepingProblem.NOT_SAFE);
|
||||
}
|
||||
}
|
||||
@@ -1726,8 +_,19 @@
|
||||
CriteriaTriggers.SLEPT_IN_BED.trigger(this);
|
||||
});
|
||||
if (!this.level().canSleepThroughNights()) {
|
||||
- this.sendOverlayMessage(Component.translatable("sleep.not_possible"));
|
||||
+ // Purpur start - Customizable sleeping actionbar messages
|
||||
+ 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.sendOverlayMessage(clientMessage);
|
||||
+ }// Purpur end - Customizable sleeping actionbar messages
|
||||
+ }
|
||||
if (newLevel.dimension() == lastDimension) {
|
||||
- this.connection.internalTeleport(PositionMoveRotation.of(transition), transition.relatives()); // CraftBukkit
|
||||
+ this.connection.internalTeleport(PositionMoveRotation.of(transition), transition.relatives()); // CraftBukkit
|
||||
this.connection.resetPosition();
|
||||
transition.postTeleportTransition().onTransition(this);
|
||||
return this;
|
||||
@@ -1552,6 +_,7 @@
|
||||
|
||||
this.level().updateSleepingPlayerList();
|
||||
return result;
|
||||
@@ -1821,6 +_,7 @@
|
||||
profiler.pop();
|
||||
profiler.push("placing");
|
||||
+ this.portalPos = org.bukkit.craftbukkit.util.CraftLocation.toBlockPos(exit); // Purpur - Fix stuck in portals
|
||||
this.setServerLevel(newLevel);
|
||||
this.connection.internalTeleport(PositionMoveRotation.of(transition), transition.relatives()); // CraftBukkit - use internal teleport without event
|
||||
this.connection.resetPosition();
|
||||
@@ -1664,7 +_,7 @@
|
||||
new AABB(bedCenter.x() - 8.0, bedCenter.y() - 5.0, bedCenter.z() - 8.0, bedCenter.x() + 8.0, bedCenter.y() + 5.0, bedCenter.z() + 8.0),
|
||||
monster -> monster.isPreventingPlayerRest(this.level(), this)
|
||||
);
|
||||
- if (!monsters.isEmpty()) {
|
||||
+ if (!this.level().purpurConfig.playerSleepNearMonsters && !monsters.isEmpty()) { // Purpur - Config to ignore nearby mobs when sleeping
|
||||
return Either.left(Player.BedSleepingProblem.NOT_SAFE);
|
||||
}
|
||||
}
|
||||
@@ -1700,7 +_,17 @@
|
||||
CriteriaTriggers.SLEPT_IN_BED.trigger(this);
|
||||
});
|
||||
if (!this.level().canSleepThroughNights()) {
|
||||
- this.sendOverlayMessage(Component.translatable("sleep.not_possible"));
|
||||
+ // Purpur start - Customizable sleeping actionbar messages
|
||||
+ 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.sendOverlayMessage(clientMessage);
|
||||
+ }// Purpur end - Customizable sleeping actionbar messages
|
||||
}
|
||||
|
||||
this.level().updateSleepingPlayerList();
|
||||
@@ -1794,6 +_,7 @@
|
||||
|
||||
@Override
|
||||
public void openTextEdit(final SignBlockEntity sign, final boolean isFrontText) {
|
||||
@@ -98,7 +105,7 @@
|
||||
this.connection.send(new ClientboundBlockUpdatePacket(this.level(), sign.getBlockPos()));
|
||||
this.connection.send(new ClientboundOpenSignEditorPacket(sign.getBlockPos(), isFrontText));
|
||||
}
|
||||
@@ -2164,6 +_,26 @@
|
||||
@@ -2138,6 +_,26 @@
|
||||
this.lastSentExp = -1; // CraftBukkit - Added to reset
|
||||
}
|
||||
|
||||
@@ -125,7 +132,7 @@
|
||||
@Override
|
||||
public void completeUsingItem() {
|
||||
if (!this.useItem.isEmpty() && this.isUsingItem()) {
|
||||
@@ -2403,6 +_,20 @@
|
||||
@@ -2373,6 +_,20 @@
|
||||
);
|
||||
}
|
||||
|
||||
@@ -146,7 +153,7 @@
|
||||
@Override
|
||||
public void sendSystemMessage(final Component message) {
|
||||
this.sendSystemMessage(message, false);
|
||||
@@ -2554,7 +_,67 @@
|
||||
@@ -2524,7 +_,67 @@
|
||||
|
||||
public void resetLastActionTime() {
|
||||
this.lastActionTime = Util.getMillis();
|
||||
@@ -215,7 +222,7 @@
|
||||
|
||||
public ServerStatsCounter getStats() {
|
||||
return this.stats;
|
||||
@@ -3179,4 +_,65 @@
|
||||
@@ -3149,4 +_,65 @@
|
||||
return (org.bukkit.craftbukkit.entity.CraftPlayer) super.getBukkitEntity();
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
@@ -371,6 +_,7 @@
|
||||
@@ -370,6 +_,7 @@
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
BlockPos pos = hitResult.getBlockPos();
|
||||
BlockState state = level.getBlockState(pos);
|
||||
boolean cancelledBlock = false;
|
||||
@@ -549,7 +_,7 @@
|
||||
@@ -551,7 +_,7 @@
|
||||
boolean haveSomethingInOurHands = !player.getMainHandItem().isEmpty() || !player.getOffhandItem().isEmpty();
|
||||
boolean suppressUsingBlock = player.isSecondaryUseActive() && haveSomethingInOurHands;
|
||||
ItemStack usedItemStack = itemStack.copy();
|
||||
@@ -25,7 +25,7 @@
|
||||
InteractionResult itemUse = state.useItemOn(player.getItemInHand(hand), level, player, hand, hitResult);
|
||||
if (itemUse.consumesAction()) {
|
||||
CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger(player, pos, usedItemStack);
|
||||
@@ -595,4 +_,18 @@
|
||||
@@ -597,4 +_,18 @@
|
||||
public void setLevel(final ServerLevel newLevel) {
|
||||
this.level = newLevel;
|
||||
}
|
||||
|
||||
@@ -206,7 +206,7 @@
|
||||
private boolean shouldCheckPlayerMovement(final boolean isFallFlying) {
|
||||
if (this.isSingleplayerOwner()) {
|
||||
return false;
|
||||
@@ -2227,6 +_,7 @@
|
||||
@@ -2229,6 +_,7 @@
|
||||
|
||||
boolean cancelled;
|
||||
if (hitResult == null || hitResult.getType() != HitResult.Type.BLOCK) {
|
||||
@@ -214,7 +214,7 @@
|
||||
org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.RIGHT_CLICK_AIR, itemStack, hand);
|
||||
cancelled = event.useItemInHand() == Event.Result.DENY;
|
||||
} else {
|
||||
@@ -2861,6 +_,7 @@
|
||||
@@ -2863,6 +_,7 @@
|
||||
ItemStack mainHandItem = this.player.getMainHandItem();
|
||||
if (this.player.isWithinAttackRange(mainHandItem, targetBounds, io.papermc.paper.configuration.GlobalConfiguration.get().misc.clientInteractionLeniencyDistance.or(3.0))) { // Paper - configurable lenience
|
||||
if (!mainHandItem.has(DataComponents.PIERCING_WEAPON)) {
|
||||
@@ -222,7 +222,7 @@
|
||||
if (target instanceof ItemEntity
|
||||
|| target instanceof ExperienceOrb
|
||||
|| target == this.player
|
||||
@@ -3642,7 +_,7 @@
|
||||
@@ -3644,7 +_,7 @@
|
||||
@Override
|
||||
public void handleChangeGameMode(final ServerboundChangeGameModePacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -288,7 +_,7 @@
|
||||
@@ -284,7 +_,7 @@
|
||||
ServerLoginPacketListenerImpl.LOGGER.warn("Failed to verify username but will let them in anyway!");
|
||||
ServerLoginPacketListenerImpl.this.startClientVerification(ServerLoginPacketListenerImpl.this.createOfflineProfile(name)); // Spigot
|
||||
} else {
|
||||
@@ -8,4 +8,4 @@
|
||||
+ 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 - Config for unverified username message
|
||||
ServerLoginPacketListenerImpl.LOGGER.error("Username '{}' tried to join with an invalid session", name);
|
||||
}
|
||||
} catch (AuthenticationUnavailableException var4) {
|
||||
} catch (AuthenticationUnavailableException ignored) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -313,6 +_,7 @@
|
||||
@@ -312,6 +_,7 @@
|
||||
scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam);
|
||||
}
|
||||
// Paper end - Configurable player collision
|
||||
@@ -8,7 +8,7 @@
|
||||
// CraftBukkit start - moved down
|
||||
LOGGER.info(
|
||||
"{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", // Paper - add world identifier
|
||||
@@ -437,6 +_,7 @@
|
||||
@@ -432,6 +_,7 @@
|
||||
}
|
||||
public net.kyori.adventure.text.@Nullable Component remove(final ServerPlayer player, final net.kyori.adventure.text.Component leaveMessage) {
|
||||
// Paper end - Fix kick event leave message not being sent
|
||||
@@ -16,7 +16,7 @@
|
||||
ServerLevel level = player.level();
|
||||
player.awardStat(Stats.LEAVE_GAME);
|
||||
// CraftBukkit start - Quitting must be before we do final save of data, in case plugins need to modify it
|
||||
@@ -771,6 +_,20 @@
|
||||
@@ -768,6 +_,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
public void broadcastAll(final Packet<?> packet, final ResourceKey<Level> dimension) {
|
||||
for (ServerPlayer player : this.players) {
|
||||
if (player.level().dimension() == dimension) {
|
||||
@@ -864,6 +_,7 @@
|
||||
@@ -861,6 +_,7 @@
|
||||
case ADMINS -> EntityEvent.PERMISSION_LEVEL_ADMINS;
|
||||
case OWNERS -> EntityEvent.PERMISSION_LEVEL_OWNERS;
|
||||
};
|
||||
@@ -45,7 +45,7 @@
|
||||
player.connection.send(new ClientboundEntityEventPacket(player, eventId));
|
||||
}
|
||||
|
||||
@@ -875,7 +_,7 @@
|
||||
@@ -872,7 +_,7 @@
|
||||
|
||||
// Paper start - whitelist verify event / login event
|
||||
public LoginResult canBypassFullServerLogin(final NameAndId nameAndId, final LoginResult currentResult) {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
+ public float maxUpStep; // Purpur - Add option to set armorstand step height
|
||||
public boolean noPhysics;
|
||||
- public final RandomSource random = SHARED_RANDOM; // Paper - Share random for entities to make them more random
|
||||
+ public final RandomSource random; // Paper - Share random for entities to make them more random // Add toggle for RNG manipulation
|
||||
+ public final RandomSource random; // Paper - Share random for entities to make them more random // Purpur - Add toggle for RNG manipulation
|
||||
public int tickCount;
|
||||
private int remainingFireTicks;
|
||||
private final EntityFluidInteraction fluidInteraction = new EntityFluidInteraction(Set.of(FluidTags.WATER, FluidTags.LAVA));
|
||||
@@ -69,7 +69,7 @@
|
||||
this.onBelowWorld();
|
||||
}
|
||||
}
|
||||
@@ -2005,7 +_,7 @@
|
||||
@@ -2007,7 +_,7 @@
|
||||
}
|
||||
|
||||
public boolean fireImmune() {
|
||||
@@ -78,7 +78,7 @@
|
||||
}
|
||||
|
||||
public boolean causeFallDamage(final double fallDistance, final float damageModifier, final DamageSource damageSource) {
|
||||
@@ -2591,7 +_,7 @@
|
||||
@@ -2593,7 +_,7 @@
|
||||
output.putBoolean("Bukkit.invisible", this.persistentInvisibility);
|
||||
}
|
||||
// SPIGOT-6907: re-implement LivingEntity#setMaximumAir()
|
||||
@@ -87,7 +87,7 @@
|
||||
output.putInt("Bukkit.MaxAirSupply", this.getMaxAirSupply());
|
||||
}
|
||||
output.putInt("Spigot.ticksLived", this.totalEntityAge); // Paper
|
||||
@@ -2678,6 +_,11 @@
|
||||
@@ -2679,6 +_,11 @@
|
||||
output.putBoolean("Paper.FreezeLock", true);
|
||||
}
|
||||
// Paper end
|
||||
@@ -96,28 +96,28 @@
|
||||
+ output.putBoolean("Purpur.FireImmune", immuneToFire);
|
||||
+ }
|
||||
+ // Purpur end - Fire immune API
|
||||
} catch (Throwable var7) {
|
||||
CrashReport report = CrashReport.forThrowable(var7, "Saving entity NBT");
|
||||
} catch (Throwable t) {
|
||||
CrashReport report = CrashReport.forThrowable(t, "Saving entity NBT");
|
||||
CrashReportCategory category = report.addCategory("Entity being saved");
|
||||
@@ -2800,6 +_,9 @@
|
||||
@@ -2802,6 +_,9 @@
|
||||
}
|
||||
freezeLocked = input.getBooleanOr("Paper.FreezeLock", false);
|
||||
// Paper end
|
||||
+
|
||||
+ immuneToFire = input.read("Purpur.FireImmune", com.mojang.serialization.Codec.BOOL).orElse(null); // Purpur - Fire immune API
|
||||
+
|
||||
} catch (Throwable var7) {
|
||||
CrashReport report = CrashReport.forThrowable(var7, "Loading entity NBT");
|
||||
} catch (Throwable t) {
|
||||
CrashReport report = CrashReport.forThrowable(t, "Loading entity NBT");
|
||||
CrashReportCategory category = report.addCategory("Entity being loaded");
|
||||
@@ -3068,6 +_,7 @@
|
||||
if (this.isAlive() && this instanceof Leashable leashablex) {
|
||||
if (leashablex.getLeashHolder() == player) {
|
||||
@@ -3067,6 +_,7 @@
|
||||
if (this.isAlive() && this instanceof Leashable leashable) {
|
||||
if (leashable.getLeashHolder() == player) {
|
||||
if (!this.level().isClientSide()) {
|
||||
+ if (hand == InteractionHand.OFF_HAND && (level().purpurConfig.villagerCanBeLeashed || level().purpurConfig.wanderingTraderCanBeLeashed) && this instanceof net.minecraft.world.entity.npc.villager.AbstractVillager) return InteractionResult.CONSUME; // Purpur - Allow leashing villagers
|
||||
// Paper start - EntityUnleashEvent
|
||||
if (!org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerUnleashEntityEvent(
|
||||
leashablex, player, hand, !player.hasInfiniteMaterials(), true
|
||||
@@ -3498,15 +_,18 @@
|
||||
leashable, player, hand, !player.hasInfiniteMaterials(), true
|
||||
@@ -3500,15 +_,18 @@
|
||||
return Vec3.directionFromRotation(this.getRotationVector());
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4236,7 +_,7 @@
|
||||
@@ -4238,7 +_,7 @@
|
||||
}
|
||||
|
||||
public boolean canUsePortal(final boolean ignorePassenger) {
|
||||
@@ -146,7 +146,7 @@
|
||||
}
|
||||
|
||||
public boolean canTeleport(final Level from, final Level to) {
|
||||
@@ -4786,6 +_,12 @@
|
||||
@@ -4788,6 +_,12 @@
|
||||
return Mth.lerp(partial, this.yRotO, this.yRot);
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@
|
||||
public boolean touchingUnloadedChunk() {
|
||||
AABB box = this.getBoundingBox().inflate(1.0);
|
||||
int x0 = Mth.floor(box.minX);
|
||||
@@ -5089,7 +_,7 @@
|
||||
@@ -5091,7 +_,7 @@
|
||||
}
|
||||
|
||||
public float maxUpStep() {
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1046,15 +_,33 @@
|
||||
@@ -1048,15 +_,33 @@
|
||||
}
|
||||
|
||||
if (targetingEntity != null) {
|
||||
@@ -74,40 +74,40 @@
|
||||
|
||||
return visibilityPercent;
|
||||
}
|
||||
@@ -1101,6 +_,7 @@
|
||||
Iterator<MobEffectInstance> iterator = this.activeEffects.values().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
MobEffectInstance effect = iterator.next();
|
||||
+ if (cause == EntityPotionEffectEvent.Cause.MILK && !this.level().purpurConfig.milkClearsBeneficialEffects && effect.getEffect().value().isBeneficial()) continue; // Purpur - Milk Keeps Beneficial Effects
|
||||
EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent(this, effect, null, cause, EntityPotionEffectEvent.Action.CLEARED);
|
||||
if (event.isCancelled()) {
|
||||
continue;
|
||||
@@ -1432,6 +_,24 @@
|
||||
this.stopSleeping();
|
||||
}
|
||||
@@ -1106,6 +_,7 @@
|
||||
Iterator<MobEffectInstance> iterator = this.activeEffects.values().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
MobEffectInstance effect = iterator.next();
|
||||
+ if (cause == EntityPotionEffectEvent.Cause.MILK && !this.level().purpurConfig.milkClearsBeneficialEffects && effect.getEffect().value().isBeneficial()) continue; // Purpur - Milk Keeps Beneficial Effects
|
||||
EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent(this, effect, null, cause, EntityPotionEffectEvent.Action.CLEARED);
|
||||
if (event.isCancelled()) {
|
||||
continue;
|
||||
@@ -1438,7 +_,23 @@
|
||||
this.stopSleeping();
|
||||
}
|
||||
|
||||
+ // Purpur start - One Punch Man!
|
||||
+ if (source.getEntity() instanceof net.minecraft.world.entity.player.Player player && source.getEntity().level().purpurConfig.creativeOnePunch && !source.is(DamageTypeTags.IS_PROJECTILE)) {
|
||||
+ if (player.isCreative()) {
|
||||
+ org.apache.commons.lang3.mutable.MutableDouble attackDamage = new org.apache.commons.lang3.mutable.MutableDouble();
|
||||
+ player.getMainHandItem().forEachModifier(EquipmentSlot.MAINHAND, (attributeHolder, attributeModifier) -> {
|
||||
+ if (attributeModifier.operation() == AttributeModifier.Operation.ADD_VALUE) {
|
||||
+ attackDamage.addAndGet(attributeModifier.amount());
|
||||
+ }
|
||||
+ });
|
||||
+
|
||||
+ if (attackDamage.doubleValue() == 0.0D) {
|
||||
+ // One punch!
|
||||
+ damage = this.getHealth();
|
||||
- this.noActionTime = 0;
|
||||
+ // Purpur start - One Punch Man!
|
||||
+ if (source.getEntity() instanceof net.minecraft.world.entity.player.Player player && source.getEntity().level().purpurConfig.creativeOnePunch && !source.is(DamageTypeTags.IS_PROJECTILE)) {
|
||||
+ if (player.isCreative()) {
|
||||
+ org.apache.commons.lang3.mutable.MutableDouble attackDamage = new org.apache.commons.lang3.mutable.MutableDouble();
|
||||
+ player.getMainHandItem().forEachModifier(EquipmentSlot.MAINHAND, (attributeHolder, attributeModifier) -> {
|
||||
+ if (attributeModifier.operation() == AttributeModifier.Operation.ADD_VALUE) {
|
||||
+ attackDamage.addAndGet(attributeModifier.amount());
|
||||
+ }
|
||||
+ });
|
||||
+
|
||||
+ if (attackDamage.doubleValue() == 0.0D) {
|
||||
+ // One punch!
|
||||
+ damage = this.getHealth();
|
||||
+ }
|
||||
+ }
|
||||
+ // Purpur end - One Punch Man!
|
||||
+
|
||||
this.noActionTime = 0;
|
||||
if (damage < 0.0F) {
|
||||
damage = 0.0F;
|
||||
@@ -1693,10 +_,10 @@
|
||||
+ }
|
||||
+ // Purpur end - One Punch Man!this.noActionTime = 0;
|
||||
if (damage < 0.0F) {
|
||||
damage = 0.0F;
|
||||
}
|
||||
@@ -1699,10 +_,10 @@
|
||||
protected @Nullable Player resolvePlayerResponsibleForDamage(final DamageSource source) {
|
||||
Entity sourceEntity = source.getEntity();
|
||||
if (sourceEntity instanceof Player playerSource) {
|
||||
@@ -120,26 +120,25 @@
|
||||
} else {
|
||||
this.lastHurtByPlayer = null;
|
||||
this.lastHurtByPlayerMemoryTime = 0;
|
||||
@@ -1747,6 +_,18 @@
|
||||
}
|
||||
@@ -1754,6 +_,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ // Purpur start - Totems work in inventory
|
||||
+ if (level().purpurConfig.totemOfUndyingWorksInInventory && this instanceof ServerPlayer player && (itemStack == null || itemStack.getItem() != Items.TOTEM_OF_UNDYING) && player.getBukkitEntity().hasPermission("purpur.inventory_totem")) {
|
||||
+ for (ItemStack item : player.getInventory().getNonEquipmentItems()) {
|
||||
+ if (item.getItem() == Items.TOTEM_OF_UNDYING) {
|
||||
+ itemStack = item;
|
||||
+ protectionItem = item.copy();
|
||||
+ break;
|
||||
+ }
|
||||
+ // Purpur start - Totems work in inventory
|
||||
+ if (level().purpurConfig.totemOfUndyingWorksInInventory && this instanceof ServerPlayer player && (itemStack == null || itemStack.getItem() != Items.TOTEM_OF_UNDYING) && player.getBukkitEntity().hasPermission("purpur.inventory_totem")) {
|
||||
+ for (ItemStack item : player.getInventory().getNonEquipmentItems()) {
|
||||
+ if (item.getItem() == Items.TOTEM_OF_UNDYING) {
|
||||
+ itemStack = item;
|
||||
+ protectionItem = item.copy();
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ // Purpur end - Totems work in inventory
|
||||
+
|
||||
final org.bukkit.inventory.EquipmentSlot handSlot = (usedHand != null) ? org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(usedHand) : null;
|
||||
final EntityResurrectEvent event = new EntityResurrectEvent((org.bukkit.entity.LivingEntity) this.getBukkitEntity(), handSlot);
|
||||
event.setCancelled(protectionItem == null);
|
||||
@@ -1921,6 +_,7 @@
|
||||
+ }
|
||||
+ // Purpur end - Totems work in inventory
|
||||
final org.bukkit.inventory.EquipmentSlot handSlot = (usedHand != null) ? org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(usedHand) : null;
|
||||
final EntityResurrectEvent event = new EntityResurrectEvent((org.bukkit.entity.LivingEntity) this.getBukkitEntity(), handSlot);
|
||||
event.setCancelled(protectionItem == null);
|
||||
@@ -1927,6 +_,7 @@
|
||||
boolean playerKilled = this.lastHurtByPlayerMemoryTime > 0;
|
||||
this.dropEquipment(level); // CraftBukkit - from below
|
||||
if (this.shouldDropLoot(level)) {
|
||||
@@ -147,7 +146,7 @@
|
||||
this.dropFromLootTable(level, source, playerKilled);
|
||||
// Paper start
|
||||
final boolean prev = this.clearEquipmentSlots;
|
||||
@@ -1929,6 +_,7 @@
|
||||
@@ -1935,6 +_,7 @@
|
||||
// Paper end
|
||||
this.dropCustomDeathLoot(level, source, playerKilled);
|
||||
this.clearEquipmentSlots = prev; // Paper
|
||||
@@ -155,7 +154,7 @@
|
||||
}
|
||||
|
||||
// CraftBukkit start - Call death event // Paper start - call advancement triggers with correct entity equipment
|
||||
@@ -3256,6 +_,7 @@
|
||||
@@ -3264,6 +_,7 @@
|
||||
float dmg = (float)(diff * 10.0 - 3.0);
|
||||
if (dmg > 0.0F) {
|
||||
this.playSound(this.getFallDamageSound((int)dmg), 1.0F, 1.0F);
|
||||
@@ -163,7 +162,7 @@
|
||||
this.hurt(this.damageSources().flyIntoWall(), dmg);
|
||||
}
|
||||
}
|
||||
@@ -4740,6 +_,12 @@
|
||||
@@ -4749,6 +_,12 @@
|
||||
? slot == EquipmentSlot.MAINHAND && this.canUseSlot(EquipmentSlot.MAINHAND)
|
||||
: slot == equippable.slot() && this.canUseSlot(equippable.slot()) && equippable.canBeEquippedBy(this.typeHolder());
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
// Paper start - allow changing despawnInPeaceful
|
||||
this.despawnInPeacefulOverride = readDespawnInPeacefulOverride(input);
|
||||
}
|
||||
@@ -1256,7 +_,7 @@
|
||||
@@ -1251,7 +_,7 @@
|
||||
);
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
return groupData;
|
||||
}
|
||||
|
||||
@@ -1613,6 +_,7 @@
|
||||
@@ -1608,6 +_,7 @@
|
||||
}
|
||||
|
||||
this.postPiercingAttack();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/ai/attributes/RangedAttribute.java
|
||||
+++ b/net/minecraft/world/entity/ai/attributes/RangedAttribute.java
|
||||
@@ -29,6 +_,7 @@
|
||||
@@ -33,6 +_,7 @@
|
||||
|
||||
@Override
|
||||
public double sanitizeValue(final double value) {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
--- a/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
|
||||
+++ b/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
|
||||
@@ -90,7 +_,7 @@
|
||||
};
|
||||
// Paper start - optimise POI searches
|
||||
java.util.List<Pair<Holder<PoiType>, BlockPos>> poiPositionsRaw = new java.util.ArrayList<>();
|
||||
- ca.spottedleaf.moonrise.patches.poi_lookup.PoiAccess.findNearestPoiPositions(poiManager, poiType, cacheTest, body.blockPosition(), SCAN_RANGE, Double.MAX_VALUE, PoiManager.Occupancy.HAS_SPACE, ca.spottedleaf.moonrise.patches.poi_lookup.PoiAccess.LOAD_FOR_SEARCHING, 5, poiPositionsRaw);
|
||||
+ ca.spottedleaf.moonrise.patches.poi_lookup.PoiAccess.findNearestPoiPositions(poiManager, poiType, cacheTest, body.blockPosition(), level.purpurConfig.villagerAcquirePoiSearchRadius, Double.MAX_VALUE, PoiManager.Occupancy.HAS_SPACE, ca.spottedleaf.moonrise.patches.poi_lookup.PoiAccess.LOAD_FOR_SEARCHING, 5, poiPositionsRaw); // Purpur - Configurable villager search radius
|
||||
Set<Pair<Holder<PoiType>, BlockPos>> poiPositions = new java.util.HashSet<>(poiPositionsRaw.size());
|
||||
for (Pair<Holder<PoiType>, BlockPos> pair : poiPositionsRaw) {
|
||||
if (validPoi.test(level, pair.getSecond())) {
|
||||
@@ -96,7 +_,7 @@
|
||||
};
|
||||
// Paper start - optimise POI searches
|
||||
java.util.List<Pair<Holder<PoiType>, BlockPos>> poiPositionsRaw = new java.util.ArrayList<>();
|
||||
- ca.spottedleaf.moonrise.patches.poi_lookup.PoiAccess.findNearestPoiPositions(poiManager, poiType, cacheTest, body.blockPosition(), SCAN_RANGE, Double.MAX_VALUE, PoiManager.Occupancy.HAS_SPACE, ca.spottedleaf.moonrise.patches.poi_lookup.PoiAccess.LOAD_FOR_SEARCHING, 5, poiPositionsRaw);
|
||||
+ ca.spottedleaf.moonrise.patches.poi_lookup.PoiAccess.findNearestPoiPositions(poiManager, poiType, cacheTest, body.blockPosition(), level.purpurConfig.villagerAcquirePoiSearchRadius, Double.MAX_VALUE, PoiManager.Occupancy.HAS_SPACE, ca.spottedleaf.moonrise.patches.poi_lookup.PoiAccess.LOAD_FOR_SEARCHING, 5, poiPositionsRaw); // Purpur - Configurable villager search radius
|
||||
Set<Pair<Holder<PoiType>, BlockPos>> poiPositions = new java.util.HashSet<>(poiPositionsRaw.size());
|
||||
for (Pair<Holder<PoiType>, BlockPos> pair : poiPositionsRaw) {
|
||||
if (validPoi.test(level, pair.getSecond())) {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
if (!this.llama.isLeashed() && !this.llama.inCaravan()) {
|
||||
List<Entity> llamas = this.llama
|
||||
.level()
|
||||
@@ -70,6 +_,7 @@
|
||||
@@ -74,6 +_,7 @@
|
||||
|
||||
@Override
|
||||
public boolean canContinueToUse() {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
--- a/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java
|
||||
+++ b/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java
|
||||
@@ -54,7 +_,7 @@
|
||||
}
|
||||
@@ -56,7 +_,7 @@
|
||||
return true;
|
||||
};
|
||||
Set<Pair<Holder<PoiType>, BlockPos>> pois = poiManager.findAllWithType(
|
||||
- e -> e.is(PoiTypes.HOME), cacheTest, body.blockPosition(), AcquirePoi.SCAN_RANGE, PoiManager.Occupancy.ANY
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
--- a/net/minecraft/world/entity/ai/targeting/TargetingConditions.java
|
||||
+++ b/net/minecraft/world/entity/ai/targeting/TargetingConditions.java
|
||||
@@ -63,6 +_,10 @@
|
||||
return false;
|
||||
} else if (this.selector != null && !this.selector.test(target, level)) {
|
||||
@@ -67,6 +_,10 @@
|
||||
|
||||
if (this.selector != null && !this.selector.test(target, level)) {
|
||||
return false;
|
||||
+ // Purpur start - AFK API
|
||||
+ } else if (!level.purpurConfig.idleTimeoutTargetPlayer && target instanceof net.minecraft.server.level.ServerPlayer player && player.isAfk()) {
|
||||
+ return false;
|
||||
+ // Purpur end - AFK API
|
||||
} else {
|
||||
if (targeter == null) {
|
||||
if (this.isCombat && (!target.canBeSeenAsEnemy() || level.getDifficulty() == Difficulty.PEACEFUL)) {
|
||||
}
|
||||
|
||||
if (targeter == null) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/animal/bee/Bee.java
|
||||
+++ b/net/minecraft/world/entity/animal/bee/Bee.java
|
||||
@@ -172,7 +_,7 @@
|
||||
@@ -171,7 +_,7 @@
|
||||
// Paper end - Fix MC-167279
|
||||
this.lookControl = new Bee.BeeLookControl(this);
|
||||
this.setPathfindingMalus(PathType.FIRE_IN_NEIGHBOR, -1.0F);
|
||||
@@ -9,7 +9,7 @@
|
||||
this.setPathfindingMalus(PathType.WATER_BORDER, 16.0F);
|
||||
this.setPathfindingMalus(PathType.COCOA, -1.0F);
|
||||
this.setPathfindingMalus(PathType.FENCE, -1.0F);
|
||||
@@ -363,13 +_,19 @@
|
||||
@@ -362,13 +_,19 @@
|
||||
if (this.stayOutOfHiveCountdown <= 0 && !this.beePollinateGoal.isPollinating() && !this.hasStung() && this.getTarget() == null) {
|
||||
boolean wantsToEnterHive = this.hasNectar()
|
||||
|| this.isTiredOfLookingForNectar()
|
||||
@@ -30,7 +30,7 @@
|
||||
public void setStayOutOfHiveCountdown(final int ticks) {
|
||||
this.stayOutOfHiveCountdown = ticks;
|
||||
}
|
||||
@@ -390,7 +_,7 @@
|
||||
@@ -389,7 +_,7 @@
|
||||
@Override
|
||||
protected void customServerAiStep(final ServerLevel level) {
|
||||
boolean hasStung = this.hasStung();
|
||||
@@ -39,7 +39,7 @@
|
||||
this.underWaterTicks++;
|
||||
} else {
|
||||
this.underWaterTicks = 0;
|
||||
@@ -400,6 +_,7 @@
|
||||
@@ -399,6 +_,7 @@
|
||||
this.hurtServer(level, this.damageSources().drown(), 1.0F);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
if (hasStung) {
|
||||
this.timeSinceSting++;
|
||||
if (this.timeSinceSting % 5 == 0 && this.random.nextInt(Mth.clamp(1200 - this.timeSinceSting, 1, 1200)) == 0) {
|
||||
@@ -1168,6 +_,7 @@
|
||||
@@ -1132,6 +_,7 @@
|
||||
Bee.this.savedFlowerPos = nearbyPos.get();
|
||||
Bee.this.navigation
|
||||
.moveTo(Bee.this.savedFlowerPos.getX() + 0.5, Bee.this.savedFlowerPos.getY() + 0.5, Bee.this.savedFlowerPos.getZ() + 0.5, 1.2F);
|
||||
@@ -55,7 +55,7 @@
|
||||
return true;
|
||||
} else {
|
||||
Bee.this.remainingCooldownBeforeLocatingNewFlower = Mth.nextInt(Bee.this.random, 20, 60);
|
||||
@@ -1214,6 +_,7 @@
|
||||
@@ -1178,6 +_,7 @@
|
||||
this.pollinating = false;
|
||||
Bee.this.navigation.stop();
|
||||
Bee.this.remainingCooldownBeforeLocatingNewFlower = 200;
|
||||
@@ -63,7 +63,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1260,6 +_,7 @@
|
||||
@@ -1224,6 +_,7 @@
|
||||
this.setWantedPos();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/animal/fox/Fox.java
|
||||
+++ b/net/minecraft/world/entity/animal/fox/Fox.java
|
||||
@@ -364,6 +_,11 @@
|
||||
@@ -363,6 +_,11 @@
|
||||
}
|
||||
|
||||
private void setTargetGoals() {
|
||||
@@ -12,7 +12,7 @@
|
||||
if (this.getVariant() == Fox.Variant.RED) {
|
||||
this.targetSelector.addGoal(4, this.landTargetGoal);
|
||||
this.targetSelector.addGoal(4, this.turtleEggTargetGoal);
|
||||
@@ -391,6 +_,7 @@
|
||||
@@ -390,6 +_,7 @@
|
||||
|
||||
public void setVariant(final Fox.Variant variant) {
|
||||
this.entityData.set(DATA_TYPE_ID, variant.getId());
|
||||
@@ -20,7 +20,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -716,6 +_,29 @@
|
||||
@@ -715,6 +_,29 @@
|
||||
return slot == EquipmentSlot.MAINHAND;
|
||||
}
|
||||
// Paper end
|
||||
|
||||
@@ -42,11 +42,11 @@
|
||||
this.readPersistentAngerSaveData(this.level(), input);
|
||||
}
|
||||
|
||||
@@ -267,6 +_,7 @@
|
||||
float pitch = 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F;
|
||||
this.playSound(SoundEvents.IRON_GOLEM_REPAIR, 1.0F, pitch);
|
||||
itemStack.consume(1, player);
|
||||
+ if (this.level().purpurConfig.ironGolemHealCalm && isAngry() && getHealth() == getMaxHealth()) stopBeingAngry(); // Purpur - Iron golem calm anger options
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -269,6 +_,7 @@
|
||||
float pitch = 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F;
|
||||
this.playSound(SoundEvents.IRON_GOLEM_REPAIR, 1.0F, pitch);
|
||||
itemStack.consume(1, player);
|
||||
+ if (this.level().purpurConfig.ironGolemHealCalm && isAngry() && getHealth() == getMaxHealth()) stopBeingAngry(); // Purpur - Iron golem calm anger options
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/animal/polarbear/PolarBear.java
|
||||
+++ b/net/minecraft/world/entity/animal/polarbear/PolarBear.java
|
||||
@@ -67,6 +_,29 @@
|
||||
@@ -66,6 +_,29 @@
|
||||
super(type, level);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
@Override
|
||||
public @Nullable AgeableMob getBreedOffspring(final ServerLevel level, final AgeableMob partner) {
|
||||
return EntityType.POLAR_BEAR.create(level, EntitySpawnReason.BREEDING);
|
||||
@@ -74,7 +_,7 @@
|
||||
@@ -73,7 +_,7 @@
|
||||
|
||||
@Override
|
||||
public boolean isFood(final ItemStack itemStack) {
|
||||
@@ -39,7 +39,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,6 +_,12 @@
|
||||
@@ -82,6 +_,12 @@
|
||||
this.goalSelector.addGoal(0, new FloatGoal(this));
|
||||
this.goalSelector.addGoal(1, new PolarBear.PolarBearMeleeAttackGoal());
|
||||
this.goalSelector.addGoal(1, new PanicGoal(this, 2.0, bear -> bear.isBaby() ? DamageTypeTags.PANIC_CAUSES : DamageTypeTags.PANIC_ENVIRONMENTAL_CAUSES));
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
if (this.tentacleMovement < Mth.PI) {
|
||||
float tentacleScale = this.tentacleMovement / Mth.PI;
|
||||
this.tentacleAngle = Mth.sin(tentacleScale * tentacleScale * Mth.PI) * Mth.PI * 0.25F;
|
||||
@@ -321,7 +_,7 @@
|
||||
@@ -316,7 +_,7 @@
|
||||
int noActionTime = this.squid.getNoActionTime();
|
||||
if (noActionTime > 100) {
|
||||
this.squid.movementVector = Vec3.ZERO;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/animal/wolf/Wolf.java
|
||||
+++ b/net/minecraft/world/entity/animal/wolf/Wolf.java
|
||||
@@ -97,6 +_,37 @@
|
||||
@@ -96,6 +_,37 @@
|
||||
public static final TargetingConditions.Selector PREY_SELECTOR = (target, level) -> target.is(EntityType.SHEEP)
|
||||
|| target.is(EntityType.RABBIT)
|
||||
|| target.is(EntityType.FOX);
|
||||
@@ -38,7 +38,7 @@
|
||||
private static final float START_HEALTH = 8.0F;
|
||||
private static final float TAME_HEALTH = 40.0F;
|
||||
private static final float ARMOR_REPAIR_UNIT = 0.125F;
|
||||
@@ -118,12 +_,47 @@
|
||||
@@ -117,12 +_,47 @@
|
||||
this.setPathfindingMalus(PathType.ON_TOP_OF_POWDER_SNOW, -1.0F);
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
this.goalSelector.addGoal(4, new LeapAtTargetGoal(this, 0.4F));
|
||||
this.goalSelector.addGoal(5, new MeleeAttackGoal(this, 1.0, true));
|
||||
this.goalSelector.addGoal(6, new FollowOwnerGoal(this, 1.0, 10.0F, 2.0F));
|
||||
@@ -136,7 +_,7 @@
|
||||
@@ -135,7 +_,7 @@
|
||||
this.targetSelector.addGoal(2, new OwnerHurtTargetGoal(this));
|
||||
this.targetSelector.addGoal(3, new HurtByTargetGoal(this).setAlertOthers());
|
||||
this.targetSelector.addGoal(4, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, this::isAngryAt));
|
||||
@@ -95,7 +95,7 @@
|
||||
this.targetSelector.addGoal(6, new NonTameRandomTargetGoal<>(this, Turtle.class, false, Turtle.BABY_ON_LAND_SELECTOR));
|
||||
this.targetSelector.addGoal(7, new NearestAttackableTargetGoal<>(this, AbstractSkeleton.class, false));
|
||||
this.targetSelector.addGoal(8, new ResetUniversalAngerTargetGoal<>(this, true));
|
||||
@@ -231,6 +_,7 @@
|
||||
@@ -230,6 +_,7 @@
|
||||
protected void addAdditionalSaveData(final ValueOutput output) {
|
||||
super.addAdditionalSaveData(output);
|
||||
output.store("CollarColor", DyeColor.LEGACY_ID_CODEC, this.getCollarColor());
|
||||
@@ -103,7 +103,7 @@
|
||||
VariantUtils.writeVariant(output, this.getVariant());
|
||||
this.addPersistentAngerSaveData(output);
|
||||
this.getSoundVariant()
|
||||
@@ -245,6 +_,10 @@
|
||||
@@ -244,6 +_,10 @@
|
||||
super.readAdditionalSaveData(input);
|
||||
VariantUtils.readVariant(input, Registries.WOLF_VARIANT).ifPresent(this::setVariant);
|
||||
this.setCollarColor(input.read("CollarColor", DyeColor.LEGACY_ID_CODEC).orElse(DEFAULT_COLLAR_COLOR));
|
||||
@@ -114,7 +114,7 @@
|
||||
this.readPersistentAngerSaveData(this.level(), input);
|
||||
input.read("sound_variant", ResourceKey.codec(Registries.WOLF_SOUND_VARIANT))
|
||||
.flatMap(soundVariant -> this.registryAccess().lookupOrThrow(Registries.WOLF_SOUND_VARIANT).get((ResourceKey<WolfSoundVariant>)soundVariant))
|
||||
@@ -268,6 +_,10 @@
|
||||
@@ -267,6 +_,10 @@
|
||||
}
|
||||
|
||||
this.setSoundVariant(WolfSoundVariants.pickRandomSoundVariant(this.registryAccess(), level.getRandom()));
|
||||
@@ -125,7 +125,7 @@
|
||||
return super.finalizeSpawn(level, difficulty, spawnReason, groupData);
|
||||
}
|
||||
|
||||
@@ -316,6 +_,11 @@
|
||||
@@ -315,6 +_,11 @@
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (this.isAlive()) {
|
||||
|
||||
@@ -34,23 +34,23 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -115,15 +_,17 @@
|
||||
@@ -118,15 +_,17 @@
|
||||
}
|
||||
// CraftBukkit end
|
||||
if (!source.is(DamageTypeTags.IS_EXPLOSION)) {
|
||||
+ if (shouldExplode()) {// Purpur - End crystal explosion options
|
||||
DamageSource damageSource = source.getEntity() != null ? this.damageSources().explosion(this, source.getEntity()) : null;
|
||||
// CraftBukkit start
|
||||
- org.bukkit.event.entity.ExplosionPrimeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callExplosionPrimeEvent(this, 6.0F, false);
|
||||
+ org.bukkit.event.entity.ExplosionPrimeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callExplosionPrimeEvent(this, getExplosionPower(), hasExplosionFire()); // Purpur - End crystal explosion options
|
||||
if (event.isCancelled()) {
|
||||
return false;
|
||||
}
|
||||
// CraftBukkit end
|
||||
if (!source.is(DamageTypeTags.IS_EXPLOSION)) {
|
||||
+ if (shouldExplode()) {// Purpur - End crystal explosion options
|
||||
DamageSource damageSource = source.getEntity() != null ? this.damageSources().explosion(this, source.getEntity()) : null;
|
||||
// CraftBukkit start
|
||||
- org.bukkit.event.entity.ExplosionPrimeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callExplosionPrimeEvent(this, 6.0F, false);
|
||||
+ org.bukkit.event.entity.ExplosionPrimeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callExplosionPrimeEvent(this, getExplosionPower(), hasExplosionFire()); // Purpur - End crystal explosion options
|
||||
if (event.isCancelled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.remove(Entity.RemovalReason.KILLED, org.bukkit.event.entity.EntityRemoveEvent.Cause.EXPLODE); // Paper - add Bukkit remove cause
|
||||
- level.explode(this, damageSource, null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.BLOCK);
|
||||
+ level.explode(this, damageSource, null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), getExplosionEffect()); // Purpur - End crystal explosion options
|
||||
+ } else this.unsetRemoved(); // Purpur - End crystal explosion options
|
||||
} else {
|
||||
this.remove(Entity.RemovalReason.KILLED, org.bukkit.event.entity.EntityRemoveEvent.Cause.DEATH); // Paper - add Bukkit remove cause
|
||||
// CraftBukkit end
|
||||
this.remove(Entity.RemovalReason.KILLED, org.bukkit.event.entity.EntityRemoveEvent.Cause.EXPLODE); // Paper - add Bukkit remove cause
|
||||
- level.explode(this, damageSource, null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.BLOCK);
|
||||
+ level.explode(this, damageSource, null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), getExplosionEffect()); // Purpur - End crystal explosion options
|
||||
+ } else this.unsetRemoved(); // Purpur - End crystal explosion options
|
||||
} else {
|
||||
this.remove(Entity.RemovalReason.KILLED, org.bukkit.event.entity.EntityRemoveEvent.Cause.DEATH); // Paper - add Bukkit remove cause
|
||||
// CraftBukkit end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
+++ b/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
@@ -959,6 +_,7 @@
|
||||
@@ -960,6 +_,7 @@
|
||||
|
||||
@Override
|
||||
protected boolean canRide(final Entity vehicle) {
|
||||
@@ -8,7 +8,7 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -994,7 +_,7 @@
|
||||
@@ -995,7 +_,7 @@
|
||||
boolean shouldDrop = level.getGameRules().get(GameRules.MOB_DROPS);
|
||||
int xpCount = 500;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
||||
+++ b/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
||||
@@ -82,6 +_,7 @@
|
||||
@@ -81,6 +_,7 @@
|
||||
private static final TargetingConditions.Selector LIVING_ENTITY_SELECTOR = (target, level) -> !target.is(EntityTypeTags.WITHER_FRIENDS)
|
||||
&& target.attackable();
|
||||
private static final TargetingConditions TARGETING_CONDITIONS = TargetingConditions.forCombat().range(20.0).selector(LIVING_ENTITY_SELECTOR);
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
public WitherBoss(final EntityType<? extends WitherBoss> type, final Level level) {
|
||||
super(type, level);
|
||||
@@ -90,6 +_,16 @@
|
||||
@@ -89,6 +_,16 @@
|
||||
this.xpReward = 50;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
@Override
|
||||
protected PathNavigation createNavigation(final Level level) {
|
||||
FlyingPathNavigation flyingPathNavigation = new FlyingPathNavigation(this, level);
|
||||
@@ -122,6 +_,7 @@
|
||||
@@ -121,6 +_,7 @@
|
||||
protected void addAdditionalSaveData(final ValueOutput output) {
|
||||
super.addAdditionalSaveData(output);
|
||||
output.putInt("Invul", this.getInvulnerableTicks());
|
||||
@@ -33,7 +33,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -131,6 +_,7 @@
|
||||
@@ -130,6 +_,7 @@
|
||||
if (this.hasCustomName()) {
|
||||
this.bossEvent.setName(this.getDisplayName());
|
||||
}
|
||||
@@ -41,7 +41,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -274,7 +_,7 @@
|
||||
@@ -273,7 +_,7 @@
|
||||
level.explode(this, this.getX(), this.getEyeY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB);
|
||||
}
|
||||
// CraftBukkit end
|
||||
@@ -50,7 +50,7 @@
|
||||
// CraftBukkit start - Use relative location for far away sounds
|
||||
// level.globalLevelEvent(LevelEvent.SOUND_WITHER_BOSS_SPAWN, this.blockPosition(), 0);
|
||||
int viewDistance = level.getCraftServer().getViewDistance() * 16;
|
||||
@@ -378,8 +_,10 @@
|
||||
@@ -377,8 +_,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
}
|
||||
|
||||
this.bossEvent.setProgress(this.getHealth() / this.getMaxHealth());
|
||||
@@ -576,6 +_,7 @@
|
||||
@@ -579,6 +_,7 @@
|
||||
|
||||
@Override
|
||||
protected boolean canRide(final Entity vehicle) {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
}
|
||||
|
||||
public ArmorStand(final Level level, final double x, final double y, final double z) {
|
||||
@@ -523,6 +_,7 @@
|
||||
@@ -546,6 +_,7 @@
|
||||
// Paper start - Allow ArmorStands not to tick
|
||||
@Override
|
||||
public void tick() {
|
||||
@@ -22,7 +22,7 @@
|
||||
if (!this.canTick) {
|
||||
if (this.noTickEquipmentDirty) {
|
||||
this.noTickEquipmentDirty = false;
|
||||
@@ -809,4 +_,19 @@
|
||||
@@ -832,4 +_,19 @@
|
||||
}
|
||||
}
|
||||
// Paper end
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
+ } else if (this.isInvulnerableToBase(source)) {
|
||||
+ // Purpur end - Item entity immunities
|
||||
return false;
|
||||
} else if (!level.getGameRules().get(GameRules.MOB_GRIEFING) && source.getEntity() instanceof Mob) {
|
||||
return false;
|
||||
@@ -517,6 +_,12 @@
|
||||
}
|
||||
|
||||
@@ -521,6 +_,12 @@
|
||||
public void setItem(final ItemStack itemStack) {
|
||||
this.getEntityData().set(DATA_ITEM, itemStack);
|
||||
this.despawnRate = this.level().paperConfig().entities.spawning.altItemDespawnRate.enabled ? this.level().paperConfig().entities.spawning.altItemDespawnRate.items.getOrDefault(itemStack.getItem(), this.level().spigotConfig.itemDespawnRate) : this.level().spigotConfig.itemDespawnRate; // Paper - Alternative item-despawn-rate
|
||||
|
||||
@@ -18,22 +18,23 @@
|
||||
final com.destroystokyo.paper.event.entity.EndermanAttackPlayerEvent event = new com.destroystokyo.paper.event.entity.EndermanAttackPlayerEvent((org.bukkit.entity.Enderman) getBukkitEntity(), (org.bukkit.entity.Player) player.getBukkitEntity());
|
||||
event.setCancelled(!shouldAttack);
|
||||
return event.callEvent();
|
||||
@@ -373,6 +_,7 @@
|
||||
@@ -373,7 +_,7 @@
|
||||
public boolean hurtServer(final ServerLevel level, final DamageSource source, final float damage) {
|
||||
if (this.isInvulnerableTo(level, source)) {
|
||||
return false;
|
||||
+ } else if (org.purpurmc.purpur.PurpurConfig.endermanShortHeight && source.is(net.minecraft.world.damagesource.DamageTypes.IN_WALL)) { return false; // Purpur - no suffocation damage if short height - Short enderman height
|
||||
} else {
|
||||
AbstractThrownPotion thrownPotion = source.getDirectEntity() instanceof AbstractThrownPotion potion ? potion : null;
|
||||
if (!source.is(DamageTypeTags.IS_PROJECTILE) && thrownPotion == null) { // Paper - EndermanEscapeEvent - diff on change - below logic relies on this path covering non-projectile damage.
|
||||
@@ -387,6 +_,7 @@
|
||||
} else {
|
||||
boolean hurtWithCleanWater = thrownPotion != null && this.hurtWithCleanWater(level, source, thrownPotion, damage);
|
||||
- }
|
||||
+ } else if (org.purpurmc.purpur.PurpurConfig.endermanShortHeight && source.is(net.minecraft.world.damagesource.DamageTypes.IN_WALL)) { return false; } // Purpur - no suffocation damage if short height - Short enderman height
|
||||
|
||||
+ if (!hurtWithCleanWater && level.purpurConfig.endermanIgnoreProjectiles) return super.hurtServer(level, source, damage); // Purpur - Config to disable Enderman teleport on projectile hit
|
||||
if (this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.INDIRECT)) { // Paper - EndermanEscapeEvent
|
||||
for (int i = 0; i < 64; i++) {
|
||||
if (this.teleport()) {
|
||||
AbstractThrownPotion thrownPotion = source.getDirectEntity() instanceof AbstractThrownPotion potion ? potion : null;
|
||||
if (!source.is(DamageTypeTags.IS_PROJECTILE) && thrownPotion == null) { // Paper - EndermanEscapeEvent - diff on change - below logic relies on this path covering non-projectile damage.
|
||||
@@ -388,6 +_,7 @@
|
||||
} else {
|
||||
boolean hurtWithCleanWater = thrownPotion != null && this.hurtWithCleanWater(level, source, thrownPotion, damage);
|
||||
|
||||
+ if (!hurtWithCleanWater && level.purpurConfig.endermanIgnoreProjectiles) return super.hurtServer(level, source, damage); // Purpur - Config to disable Enderman teleport on projectile hit
|
||||
if (this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.INDIRECT)) { // Paper - EndermanEscapeEvent
|
||||
for (int i = 0; i < 64; i++) {
|
||||
if (this.teleport()) {
|
||||
@@ -430,7 +_,7 @@
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/monster/Guardian.java
|
||||
+++ b/net/minecraft/world/entity/monster/Guardian.java
|
||||
@@ -308,6 +_,11 @@
|
||||
@@ -310,6 +_,11 @@
|
||||
final BlockPos pos,
|
||||
final RandomSource random
|
||||
) {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
+ // Purpur end - Config to disable hostile mob spawn on ice
|
||||
if (level.getBrightness(LightLayer.SKY, pos) > random.nextInt(32)) {
|
||||
return false;
|
||||
} else {
|
||||
}
|
||||
@@ -113,6 +_,11 @@
|
||||
public static boolean checkAnyLightMonsterSpawnRules(
|
||||
final EntityType<? extends Monster> type, final LevelAccessor level, final EntitySpawnReason spawnReason, final BlockPos pos, final RandomSource random
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/monster/Phantom.java
|
||||
+++ b/net/minecraft/world/entity/monster/Phantom.java
|
||||
@@ -167,7 +_,11 @@
|
||||
@@ -166,7 +_,11 @@
|
||||
final ServerLevelAccessor level, final DifficultyInstance difficulty, final EntitySpawnReason spawnReason, final @Nullable SpawnGroupData groupData
|
||||
) {
|
||||
this.anchorPoint = this.blockPosition().above(5);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/monster/Shulker.java
|
||||
+++ b/net/minecraft/world/entity/monster/Shulker.java
|
||||
@@ -94,6 +_,22 @@
|
||||
@@ -93,6 +_,22 @@
|
||||
this.lookControl = new Shulker.ShulkerLookControl(this);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
@Override
|
||||
protected void registerGoals() {
|
||||
this.goalSelector.addGoal(1, new LookAtPlayerGoal(this, Player.class, 8.0F, 0.02F, true));
|
||||
@@ -455,11 +_,21 @@
|
||||
@@ -454,11 +_,21 @@
|
||||
private void hitByShulkerBullet() {
|
||||
Vec3 oldPosition = this.position();
|
||||
AABB oldAabb = this.getBoundingBox();
|
||||
@@ -49,7 +49,7 @@
|
||||
if (baby != null) {
|
||||
baby.setVariant(this.getVariant());
|
||||
baby.snapTo(oldPosition);
|
||||
@@ -566,7 +_,7 @@
|
||||
@@ -565,7 +_,7 @@
|
||||
}
|
||||
|
||||
public Optional<DyeColor> getVariant() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/monster/piglin/PiglinAi.java
|
||||
+++ b/net/minecraft/world/entity/monster/piglin/PiglinAi.java
|
||||
@@ -669,14 +_,24 @@
|
||||
@@ -666,14 +_,24 @@
|
||||
}
|
||||
|
||||
public static boolean isWearingSafeArmor(final LivingEntity livingEntity) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java
|
||||
+++ b/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java
|
||||
@@ -142,7 +_,7 @@
|
||||
@@ -137,7 +_,7 @@
|
||||
this.populateDefaultEquipmentEnchantments(level, random, difficulty);
|
||||
this.reassessWeaponGoal();
|
||||
this.setCanPickUpLoot(level.getLevel().paperConfig().entities.behavior.mobsCanAlwaysPickUpLoot.skeletons || random.nextFloat() < 0.55F * difficulty.getSpecialMultiplier()); // Paper - Add world settings for mobs picking up loot
|
||||
@@ -9,7 +9,7 @@
|
||||
this.setItemSlot(EquipmentSlot.HEAD, new ItemStack(random.nextFloat() < 0.1F ? Blocks.JACK_O_LANTERN : Blocks.CARVED_PUMPKIN));
|
||||
this.setDropChance(EquipmentSlot.HEAD, 0.0F);
|
||||
}
|
||||
@@ -189,7 +_,7 @@
|
||||
@@ -184,7 +_,7 @@
|
||||
double distanceToTarget = Math.sqrt(xd * xd + zd * zd);
|
||||
if (this.level() instanceof ServerLevel serverLevel) {
|
||||
Projectile.Delayed<AbstractArrow> delayedEntity = Projectile.spawnProjectileUsingShootDelayed( // Paper - delayed
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/monster/zombie/Zombie.java
|
||||
+++ b/net/minecraft/world/entity/monster/zombie/Zombie.java
|
||||
@@ -128,7 +_,19 @@
|
||||
@@ -127,7 +_,19 @@
|
||||
this.goalSelector.addGoal(7, new WaterAvoidingRandomStrollGoal(this, 1.0));
|
||||
this.targetSelector.addGoal(1, new HurtByTargetGoal(this).setAlertOthers(ZombifiedPiglin.class));
|
||||
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true));
|
||||
@@ -21,7 +21,7 @@
|
||||
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true));
|
||||
this.targetSelector.addGoal(5, new NearestAttackableTargetGoal<>(this, Turtle.class, 10, true, false, Turtle.BABY_ON_LAND_SELECTOR));
|
||||
}
|
||||
@@ -543,7 +_,7 @@
|
||||
@@ -540,7 +_,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -92,15 +92,15 @@
|
||||
profiler.pop();
|
||||
if (this.assignProfessionWhenSpawned) {
|
||||
this.assignProfessionWhenSpawned = false;
|
||||
@@ -344,6 +_,7 @@
|
||||
return InteractionResult.CONSUME;
|
||||
}
|
||||
|
||||
+ if (this.level().purpurConfig.villagerAllowTrading) // Purpur - Add config for villager trading
|
||||
this.startTrading(player);
|
||||
@@ -347,6 +_,7 @@
|
||||
return InteractionResult.CONSUME;
|
||||
}
|
||||
|
||||
@@ -485,7 +_,7 @@
|
||||
+ if (this.level().purpurConfig.villagerAllowTrading) // Purpur - Add config for villager trading
|
||||
this.startTrading(player);
|
||||
}
|
||||
|
||||
@@ -487,7 +_,7 @@
|
||||
|
||||
public void updateDemand() {
|
||||
for (MerchantOffer offer : this.getOffers()) {
|
||||
@@ -109,7 +109,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -685,7 +_,7 @@
|
||||
@@ -687,7 +_,7 @@
|
||||
|
||||
@Override
|
||||
public boolean canBreed() {
|
||||
@@ -118,7 +118,7 @@
|
||||
}
|
||||
|
||||
private boolean hungry() {
|
||||
@@ -891,6 +_,7 @@
|
||||
@@ -893,6 +_,7 @@
|
||||
}
|
||||
|
||||
public void spawnGolemIfNeeded(final ServerLevel level, final long timestamp, final int villagersNeededToAgree) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/npc/wanderingtrader/WanderingTrader.java
|
||||
+++ b/net/minecraft/world/entity/npc/wanderingtrader/WanderingTrader.java
|
||||
@@ -61,6 +_,13 @@
|
||||
@@ -60,6 +_,13 @@
|
||||
super(type, level);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
@Override
|
||||
protected void registerGoals() {
|
||||
this.goalSelector.addGoal(0, new FloatGoal(this));
|
||||
@@ -78,7 +_,7 @@
|
||||
@@ -77,7 +_,7 @@
|
||||
.addGoal(
|
||||
0,
|
||||
new UseItemGoal<>(
|
||||
@@ -23,7 +23,7 @@
|
||||
)
|
||||
);
|
||||
this.goalSelector.addGoal(1, new TradeWithPlayerGoal(this));
|
||||
@@ -121,8 +_,10 @@
|
||||
@@ -120,8 +_,10 @@
|
||||
return InteractionResult.CONSUME;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/npc/wanderingtrader/WanderingTraderSpawner.java
|
||||
+++ b/net/minecraft/world/entity/npc/wanderingtrader/WanderingTraderSpawner.java
|
||||
@@ -133,7 +_,17 @@
|
||||
@@ -135,7 +_,17 @@
|
||||
int xPosition = referencePosition.getX() + this.random.nextInt(radius * 2) - radius;
|
||||
int zPosition = referencePosition.getZ() + this.random.nextInt(radius * 2) - radius;
|
||||
int yPosition = level.getHeight(SpawnPlacements.getHeightmapType(EntityType.WANDERING_TRADER), xPosition, zPosition);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/net/minecraft/world/entity/player/Player.java
|
||||
@@ -174,11 +_,20 @@
|
||||
@@ -173,11 +_,20 @@
|
||||
public float hurtDir;
|
||||
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
|
||||
@@ -21,7 +21,7 @@
|
||||
@Override
|
||||
public org.bukkit.craftbukkit.entity.CraftHumanEntity getBukkitEntity() {
|
||||
return (org.bukkit.craftbukkit.entity.CraftHumanEntity) super.getBukkitEntity();
|
||||
@@ -239,6 +_,12 @@
|
||||
@@ -242,6 +_,12 @@
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
@@ -34,7 +34,7 @@
|
||||
this.noPhysics = this.isSpectator();
|
||||
if (this.isSpectator() || this.isPassenger()) {
|
||||
this.setOnGround(false);
|
||||
@@ -296,6 +_,17 @@
|
||||
@@ -299,6 +_,17 @@
|
||||
this.turtleHelmetTick();
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
this.cooldowns.tick();
|
||||
this.updatePlayerPose();
|
||||
}
|
||||
@@ -501,7 +_,7 @@
|
||||
@@ -504,7 +_,7 @@
|
||||
List<Entity> orbs = Lists.newArrayList();
|
||||
|
||||
for (Entity entity : entities) {
|
||||
@@ -61,7 +61,7 @@
|
||||
orbs.add(entity);
|
||||
} else if (!entity.isRemoved()) {
|
||||
this.touch(entity);
|
||||
@@ -1044,7 +_,7 @@
|
||||
@@ -1052,7 +_,7 @@
|
||||
criticalAttack = criticalAttack && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper - Toggleable player crits
|
||||
if (criticalAttack) {
|
||||
damageSource = damageSource.critical(); // Paper - critical damage API
|
||||
@@ -70,7 +70,7 @@
|
||||
}
|
||||
|
||||
float totalDamage = baseDamage + magicBoost;
|
||||
@@ -1740,7 +_,23 @@
|
||||
@@ -1748,7 +_,23 @@
|
||||
|
||||
@Override
|
||||
protected int getBaseExperienceReward(final ServerLevel level) {
|
||||
@@ -95,7 +95,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1783,6 +_,13 @@
|
||||
@@ -1791,6 +_,13 @@
|
||||
public boolean addItem(final ItemStack itemStack) {
|
||||
return this.inventory.add(itemStack);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/projectile/throwableitemprojectile/Snowball.java
|
||||
+++ b/net/minecraft/world/entity/projectile/throwableitemprojectile/Snowball.java
|
||||
@@ -56,9 +_,39 @@
|
||||
@@ -54,9 +_,39 @@
|
||||
protected void onHitEntity(final EntityHitResult hitResult) {
|
||||
super.onHitEntity(hitResult);
|
||||
Entity entity = hitResult.getEntity();
|
||||
|
||||
@@ -26,17 +26,17 @@
|
||||
Iterator<Raid> raidIterator = this.raidMap.values().iterator();
|
||||
|
||||
while (raidIterator.hasNext()) {
|
||||
@@ -137,11 +_,11 @@
|
||||
// }
|
||||
@@ -139,11 +_,12 @@
|
||||
// }
|
||||
|
||||
if (!raid.isStarted() || (raid.isInProgress() && raid.getRaidOmenLevel() < raid.getMaxRaidOmenLevel())) { // CraftBukkit - fixed a bug with raid: players could add up Bad Omen level even when the raid had finished
|
||||
- // CraftBukkit start
|
||||
+ if (level.purpurConfig.raidCooldownSeconds != 0 && playerCooldowns.containsKey(player.getUUID())) return null; // Purpur - Raid cooldown setting// CraftBukkit start
|
||||
if (!org.bukkit.craftbukkit.event.CraftEventFactory.callRaidTriggerEvent(level, raid, player)) {
|
||||
player.removeEffect(net.minecraft.world.effect.MobEffects.RAID_OMEN);
|
||||
return null;
|
||||
- }
|
||||
+ }if (level.purpurConfig.raidCooldownSeconds != 0) playerCooldowns.put(player.getUUID(), level.purpurConfig.raidCooldownSeconds); // Purpur - Raid cooldown setting
|
||||
if (!raid.isStarted() || (raid.isInProgress() && raid.getRaidOmenLevel() < raid.getMaxRaidOmenLevel())) { // CraftBukkit - fixed a bug with raid: players could add up Bad Omen level even when the raid had finished
|
||||
+ if (level.purpurConfig.raidCooldownSeconds != 0 && playerCooldowns.containsKey(player.getUUID())) return null; // Purpur - Raid cooldown setting
|
||||
// CraftBukkit start
|
||||
if (!org.bukkit.craftbukkit.event.CraftEventFactory.callRaidTriggerEvent(level, raid, player)) {
|
||||
player.removeEffect(net.minecraft.world.effect.MobEffects.RAID_OMEN);
|
||||
return null;
|
||||
- }
|
||||
+ }if (level.purpurConfig.raidCooldownSeconds != 0) playerCooldowns.put(player.getUUID(), level.purpurConfig.raidCooldownSeconds); // Purpur - Raid cooldown setting
|
||||
|
||||
if (!raid.isStarted() && !this.raidMap.containsValue(raid)) {
|
||||
this.raidMap.put(this.getUniqueId(), raid);
|
||||
if (!raid.isStarted() && !this.raidMap.containsValue(raid)) {
|
||||
this.raidMap.put(this.getUniqueId(), raid);
|
||||
|
||||
@@ -6,6 +6,6 @@
|
||||
if (deltaMovement.length() > 0.01) {
|
||||
- return deltaMovement.normalize().scale(deltaMovement.length() + 0.06);
|
||||
+ return deltaMovement.normalize().scale(deltaMovement.length() + this.level().purpurConfig.poweredRailBoostModifier); // Purpur - Configurable powered rail boost modifier
|
||||
} else {
|
||||
Vec3 powerDirection = this.minecart.getRedstoneDirection(pos);
|
||||
return powerDirection.lengthSqr() <= 0.0 ? deltaMovement : powerDirection.scale(deltaMovement.length() + 0.2);
|
||||
}
|
||||
|
||||
Vec3 powerDirection = this.minecart.getRedstoneDirection(pos);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
+++ b/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
@@ -65,6 +_,7 @@
|
||||
@@ -64,6 +_,7 @@
|
||||
private final List<ContainerListener> containerListeners = Lists.newArrayList();
|
||||
private @Nullable ContainerSynchronizer synchronizer;
|
||||
private boolean suppressRemoteUpdates;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/inventory/AbstractFurnaceMenu.java
|
||||
+++ b/net/minecraft/world/inventory/AbstractFurnaceMenu.java
|
||||
@@ -122,7 +_,13 @@
|
||||
@@ -121,7 +_,13 @@
|
||||
} else if (slotIndex != 1 && slotIndex != 0) {
|
||||
if (this.canSmelt(stack)) {
|
||||
if (!this.moveItemStackTo(stack, 0, 1, false)) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/inventory/EnchantmentMenu.java
|
||||
+++ b/net/minecraft/world/inventory/EnchantmentMenu.java
|
||||
@@ -64,6 +_,22 @@
|
||||
@@ -63,6 +_,22 @@
|
||||
return access.getLocation();
|
||||
}
|
||||
// CraftBukkit end
|
||||
@@ -23,7 +23,7 @@
|
||||
};
|
||||
// Paper end - Add missing InventoryHolders
|
||||
this.access = access;
|
||||
@@ -92,6 +_,16 @@
|
||||
@@ -83,6 +_,16 @@
|
||||
return EnchantmentMenu.EMPTY_SLOT_LAPIS_LAZULI;
|
||||
}
|
||||
});
|
||||
@@ -40,7 +40,7 @@
|
||||
this.addStandardInventorySlots(inventory, 8, 84);
|
||||
this.addDataSlot(DataSlot.shared(this.costs, 0));
|
||||
this.addDataSlot(DataSlot.shared(this.costs, 1));
|
||||
@@ -308,7 +_,7 @@
|
||||
@@ -301,7 +_,7 @@
|
||||
@Override
|
||||
public void removed(final Player player) {
|
||||
super.removed(player);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/inventory/GrindstoneMenu.java
|
||||
+++ b/net/minecraft/world/inventory/GrindstoneMenu.java
|
||||
@@ -105,11 +_,13 @@
|
||||
@@ -92,11 +_,13 @@
|
||||
@Override
|
||||
public void onTake(final Player player, final ItemStack carried) {
|
||||
access.execute((level, pos) -> {
|
||||
@@ -15,7 +15,7 @@
|
||||
// Paper end - Fire BlockExpEvent on grindstone use
|
||||
}
|
||||
|
||||
@@ -138,7 +_,7 @@
|
||||
@@ -125,7 +_,7 @@
|
||||
for (Entry<Holder<Enchantment>> entry : enchantments.entrySet()) {
|
||||
Holder<Enchantment> enchant = entry.getKey();
|
||||
int lvl = entry.getIntValue();
|
||||
@@ -24,7 +24,7 @@
|
||||
amount += enchant.value().getMinCost(lvl);
|
||||
}
|
||||
}
|
||||
@@ -216,16 +_,76 @@
|
||||
@@ -205,16 +_,76 @@
|
||||
|
||||
for (Entry<Holder<Enchantment>> entry : enchantments.entrySet()) {
|
||||
Holder<Enchantment> enchant = entry.getKey();
|
||||
@@ -103,7 +103,7 @@
|
||||
);
|
||||
if (item.is(Items.ENCHANTED_BOOK) && newEnchantments.isEmpty()) {
|
||||
item = item.transmuteCopy(Items.BOOK);
|
||||
@@ -238,6 +_,22 @@
|
||||
@@ -227,6 +_,22 @@
|
||||
}
|
||||
|
||||
item.set(DataComponents.REPAIR_COST, repairCost);
|
||||
@@ -126,7 +126,7 @@
|
||||
return item;
|
||||
}
|
||||
|
||||
@@ -294,7 +_,9 @@
|
||||
@@ -283,7 +_,9 @@
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/inventory/ItemCombinerMenu.java
|
||||
+++ b/net/minecraft/world/inventory/ItemCombinerMenu.java
|
||||
@@ -177,7 +_,9 @@
|
||||
@@ -160,7 +_,9 @@
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,41 +1,42 @@
|
||||
--- a/net/minecraft/world/item/AxeItem.java
|
||||
+++ b/net/minecraft/world/item/AxeItem.java
|
||||
@@ -65,13 +_,15 @@
|
||||
if (playerHasBlockingItemUseIntent(context)) {
|
||||
@@ -66,14 +_,16 @@
|
||||
return InteractionResult.PASS;
|
||||
} else {
|
||||
- Optional<BlockState> newBlock = this.evaluateNewBlockState(level, pos, player, level.getBlockState(pos));
|
||||
+ Optional<org.purpurmc.purpur.tool.Actionable> newBlock = this.evaluateActionable(level, pos, player, level.getBlockState(pos)); // Purpur - Tool actionable options
|
||||
if (newBlock.isEmpty()) {
|
||||
return InteractionResult.PASS;
|
||||
} else {
|
||||
+ org.purpurmc.purpur.tool.Actionable actionable = newBlock.get(); // Purpur - Tool actionable options
|
||||
+ BlockState state = actionable.into().withPropertiesOf(level.getBlockState(pos)); // Purpur - Tool actionable options
|
||||
ItemStack itemInHand = context.getItemInHand();
|
||||
// Paper start - EntityChangeBlockEvent
|
||||
- if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, pos, newBlock.get())) {
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, pos, state)) { // Purpur - Tool actionable options
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
// Paper end
|
||||
@@ -79,8 +_,15 @@
|
||||
CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger((ServerPlayer)player, pos, itemInHand);
|
||||
}
|
||||
}
|
||||
|
||||
- level.setBlock(pos, newBlock.get(), Block.UPDATE_ALL_IMMEDIATE);
|
||||
- level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(player, newBlock.get()));
|
||||
+ // Purpur start - Tool actionable options
|
||||
+ level.setBlock(pos, state, Block.UPDATE_ALL_IMMEDIATE);
|
||||
+ actionable.drops().forEach((drop, chance) -> {
|
||||
+ if (level.getRandom().nextDouble() < chance) {
|
||||
+ Block.popResourceFromFace(level, pos, context.getClickedFace(), new ItemStack(drop));
|
||||
+ }
|
||||
+ });
|
||||
+ level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(player, state));
|
||||
+ // Purpur end - Tool actionable options
|
||||
if (player != null) {
|
||||
itemInHand.hurtAndBreak(1, player, context.getHand().asEquipmentSlot());
|
||||
}
|
||||
- Optional<BlockState> newBlock = this.evaluateNewBlockState(level, pos, player, level.getBlockState(pos));
|
||||
+ Optional<org.purpurmc.purpur.tool.Actionable> newBlock = this.evaluateActionable(level, pos, player, level.getBlockState(pos)); // Purpur - Tool actionable options
|
||||
if (newBlock.isEmpty()) {
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
|
||||
+ org.purpurmc.purpur.tool.Actionable actionable = newBlock.get(); // Purpur - Tool actionable options
|
||||
+ BlockState state = actionable.into().withPropertiesOf(level.getBlockState(pos)); // Purpur - Tool actionable options
|
||||
ItemStack itemInHand = context.getItemInHand();
|
||||
// Paper start - EntityChangeBlockEvent
|
||||
- if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, pos, newBlock.get())) {
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, pos, state)) { // Purpur - Tool actionable options
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
// Paper end
|
||||
@@ -81,8 +_,15 @@
|
||||
CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger((ServerPlayer)player, pos, itemInHand);
|
||||
}
|
||||
|
||||
- level.setBlock(pos, newBlock.get(), Block.UPDATE_ALL_IMMEDIATE);
|
||||
- level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(player, newBlock.get()));
|
||||
+ // Purpur start - Tool actionable options
|
||||
+ level.setBlock(pos, state, Block.UPDATE_ALL_IMMEDIATE);
|
||||
+ actionable.drops().forEach((drop, chance) -> {
|
||||
+ if (level.getRandom().nextDouble() < chance) {
|
||||
+ Block.popResourceFromFace(level, pos, context.getClickedFace(), new ItemStack(drop));
|
||||
+ }
|
||||
+ });
|
||||
+ level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(player, state));
|
||||
+ // Purpur end - Tool actionable options
|
||||
if (player != null) {
|
||||
itemInHand.hurtAndBreak(1, player, context.getHand().asEquipmentSlot());
|
||||
}
|
||||
@@ -97,21 +_,23 @@
|
||||
&& !player.isSecondaryUseActive();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/item/BlockItem.java
|
||||
+++ b/net/minecraft/world/item/BlockItem.java
|
||||
@@ -132,7 +_,16 @@
|
||||
@@ -134,7 +_,16 @@
|
||||
protected boolean updateCustomBlockEntityTag(
|
||||
final BlockPos pos, final Level level, final @Nullable Player player, final ItemStack itemStack, final BlockState placedState
|
||||
) {
|
||||
@@ -18,15 +18,15 @@
|
||||
}
|
||||
|
||||
protected @Nullable BlockState getPlacementState(final BlockPlaceContext context) {
|
||||
@@ -194,6 +_,7 @@
|
||||
}
|
||||
@@ -197,6 +_,7 @@
|
||||
}
|
||||
|
||||
if (!type.onlyOpCanSetNbt() || player != null && (player.canUseGameMasterBlocks() || (player.getAbilities().instabuild && player.getBukkitEntity().hasPermission("minecraft.nbt.place")))) { // Spigot - add permission
|
||||
+ if (!(level.purpurConfig.silkTouchEnabled && blockEntity instanceof net.minecraft.world.level.block.entity.SpawnerBlockEntity && player.getBukkitEntity().hasPermission("purpur.drop.spawners"))) // Purpur - Silk touch spawners
|
||||
return customData.loadInto(blockEntity, level.registryAccess());
|
||||
}
|
||||
if (!type.onlyOpCanSetNbt() || player != null && (player.canUseGameMasterBlocks() || (player.getAbilities().instabuild && player.getBukkitEntity().hasPermission("minecraft.nbt.place")))) { // Spigot - add permission
|
||||
+ if (!(level.purpurConfig.silkTouchEnabled && blockEntity instanceof net.minecraft.world.level.block.entity.SpawnerBlockEntity && player.getBukkitEntity().hasPermission("purpur.drop.spawners"))) // Purpur - Silk touch spawners
|
||||
return customData.loadInto(blockEntity, level.registryAccess());
|
||||
}
|
||||
|
||||
@@ -234,6 +_,7 @@
|
||||
@@ -236,6 +_,7 @@
|
||||
public void onDestroyed(final ItemEntity entity) {
|
||||
ItemContainerContents container = entity.getItem().set(DataComponents.CONTAINER, ItemContainerContents.EMPTY);
|
||||
if (container != null) {
|
||||
|
||||
@@ -11,16 +11,16 @@
|
||||
+ // Purpur end - Infinity bow settings
|
||||
if (projectile.isEmpty()) {
|
||||
return false;
|
||||
} else {
|
||||
@@ -38,7 +_,7 @@
|
||||
} else {
|
||||
List<ItemStack> firedProjectiles = draw(itemStack, projectile, player);
|
||||
if (level instanceof ServerLevel serverLevel && !firedProjectiles.isEmpty()) {
|
||||
- this.shoot(serverLevel, player, player.getUsedItemHand(), itemStack, firedProjectiles, pow * 3.0F, 1.0F, pow == 1.0F, null, pow); // Paper - Pass draw strength
|
||||
+ this.shoot(serverLevel, player, player.getUsedItemHand(), itemStack, firedProjectiles, pow * 3.0F, (float) serverLevel.purpurConfig.bowProjectileOffset, pow == 1.0F, null, pow); // Paper - Pass draw strength // Purpur - Projectile offset config
|
||||
}
|
||||
}
|
||||
@@ -40,7 +_,7 @@
|
||||
|
||||
level.playSound(
|
||||
List<ItemStack> firedProjectiles = draw(itemStack, projectile, player);
|
||||
if (level instanceof ServerLevel serverLevel && !firedProjectiles.isEmpty()) {
|
||||
- this.shoot(serverLevel, player, player.getUsedItemHand(), itemStack, firedProjectiles, pow * 3.0F, 1.0F, pow == 1.0F, null, pow); // Paper - Pass draw strength
|
||||
+ this.shoot(serverLevel, player, player.getUsedItemHand(), itemStack, firedProjectiles, pow * 3.0F, (float) serverLevel.purpurConfig.bowProjectileOffset, pow == 1.0F, null, pow); // Paper - Pass draw strength // Purpur - Projectile offset config
|
||||
}
|
||||
|
||||
level.playSound(
|
||||
@@ -95,7 +_,7 @@
|
||||
public InteractionResult use(final Level level, final Player player, final InteractionHand hand) {
|
||||
ItemStack itemStack = player.getItemInHand(hand);
|
||||
@@ -28,5 +28,5 @@
|
||||
- if (!player.hasInfiniteMaterials() && !foundProjectile) {
|
||||
+ if (!player.hasInfiniteMaterials() && !foundProjectile && !(level.purpurConfig.infinityWorksWithoutArrows && net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.INFINITY, itemStack) > 0)) { // Purpur - Infinity bow settings
|
||||
return InteractionResult.FAIL;
|
||||
} else {
|
||||
player.startUsingItem(hand);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
--- a/net/minecraft/world/item/BucketItem.java
|
||||
+++ b/net/minecraft/world/item/BucketItem.java
|
||||
@@ -146,7 +_,7 @@
|
||||
// CraftBukkit end
|
||||
if (!canPlaceFluidInsideBlock) {
|
||||
@@ -152,7 +_,7 @@
|
||||
return hitResult != null && this.emptyContents(user, level, hitResult.getBlockPos().relative(hitResult.getDirection()), null, direction, clicked, itemStack, hand); // CraftBukkit
|
||||
- } else if (level.environmentAttributes().getValue(EnvironmentAttributes.WATER_EVAPORATES, pos) && this.content.is(FluidTags.WATER)) {
|
||||
+ } else if ((level.environmentAttributes().getValue(EnvironmentAttributes.WATER_EVAPORATES, pos) || (level.isTheEnd() && !org.purpurmc.purpur.PurpurConfig.allowWaterPlacementInTheEnd)) && this.content.is(FluidTags.WATER)) { // Purpur - Add allow water in end world option
|
||||
}
|
||||
|
||||
- if (level.environmentAttributes().getValue(EnvironmentAttributes.WATER_EVAPORATES, pos) && this.content.is(FluidTags.WATER)) {
|
||||
+ if ((level.environmentAttributes().getValue(EnvironmentAttributes.WATER_EVAPORATES, pos) || (level.isTheEnd() && !org.purpurmc.purpur.PurpurConfig.allowWaterPlacementInTheEnd)) && this.content.is(FluidTags.WATER)) { // Purpur - Add allow water in end world option
|
||||
int x = pos.getX();
|
||||
int y = pos.getY();
|
||||
int z = pos.getZ();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
--- a/net/minecraft/world/item/DyeColor.java
|
||||
+++ b/net/minecraft/world/item/DyeColor.java
|
||||
@@ -154,4 +_,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
+
|
||||
+ // Purpur start - Shulker spawn from bullet options
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
- if (!blockState.is(Blocks.OBSIDIAN) && !blockState.is(Blocks.BEDROCK)) {
|
||||
+ if (!level.purpurConfig.endCrystalPlaceAnywhere && !blockState.is(Blocks.OBSIDIAN) && !blockState.is(Blocks.BEDROCK)) { // Purpur - place end crystal on any block
|
||||
return InteractionResult.FAIL;
|
||||
} else {
|
||||
BlockPos above = pos.above();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/item/HoeItem.java
|
||||
+++ b/net/minecraft/world/item/HoeItem.java
|
||||
@@ -44,15 +_,25 @@
|
||||
@@ -44,16 +_,26 @@
|
||||
public InteractionResult useOn(final UseOnContext context) {
|
||||
Level level = context.getLevel();
|
||||
BlockPos pos = context.getClickedPos();
|
||||
@@ -11,23 +11,24 @@
|
||||
+ org.purpurmc.purpur.tool.Tillable tillable = level.purpurConfig.hoeTillables.get(clickedBlock);
|
||||
+ if (tillable == null) {
|
||||
return InteractionResult.PASS;
|
||||
} else {
|
||||
- Predicate<UseOnContext> predicate = logicPair.getFirst();
|
||||
- Consumer<UseOnContext> action = logicPair.getSecond();
|
||||
+ Predicate<UseOnContext> predicate = tillable.condition().predicate();
|
||||
+ Consumer<UseOnContext> action = (ctx) -> {
|
||||
+ level.setBlock(pos, tillable.into().defaultBlockState(), 11);
|
||||
+ tillable.drops().forEach((drop, chance) -> {
|
||||
+ if (level.getRandom().nextDouble() < chance) {
|
||||
+ Block.popResourceFromFace(level, pos, ctx.getClickedFace(), new ItemStack(drop));
|
||||
+ }
|
||||
+ });
|
||||
+ };
|
||||
+ // Purpur end - Tool actionable options
|
||||
if (predicate.test(context)) {
|
||||
Player player = context.getPlayer();
|
||||
- level.playSound(player, pos, SoundEvents.HOE_TILL, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
+ if (!TILLABLES.containsKey(clickedBlock)) level.playSound(null, pos, SoundEvents.HOE_TILL, SoundSource.BLOCKS, 1.0F, 1.0F); // Purpur - Tool actionable options - force sound
|
||||
if (!level.isClientSide()) {
|
||||
action.accept(context);
|
||||
if (player != null) {
|
||||
}
|
||||
|
||||
- Predicate<UseOnContext> predicate = logicPair.getFirst();
|
||||
- Consumer<UseOnContext> action = logicPair.getSecond();
|
||||
+ Predicate<UseOnContext> predicate = tillable.condition().predicate();
|
||||
+ Consumer<UseOnContext> action = (ctx) -> {
|
||||
+ level.setBlock(pos, tillable.into().defaultBlockState(), 11);
|
||||
+ tillable.drops().forEach((drop, chance) -> {
|
||||
+ if (level.getRandom().nextDouble() < chance) {
|
||||
+ Block.popResourceFromFace(level, pos, ctx.getClickedFace(), new ItemStack(drop));
|
||||
+ }
|
||||
+ });
|
||||
+ };
|
||||
+ // Purpur end - Tool actionable options
|
||||
if (predicate.test(context)) {
|
||||
Player player = context.getPlayer();
|
||||
- level.playSound(player, pos, SoundEvents.HOE_TILL, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
+ if (!TILLABLES.containsKey(clickedBlock)) level.playSound(null, pos, SoundEvents.HOE_TILL, SoundSource.BLOCKS, 1.0F, 1.0F); // Purpur - Tool actionable options - force sound
|
||||
if (!level.isClientSide()) {
|
||||
action.accept(context);
|
||||
if (player != null) {
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
--- a/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/net/minecraft/world/item/ItemStack.java
|
||||
@@ -452,6 +_,7 @@
|
||||
// revert back all captured blocks
|
||||
for (org.bukkit.block.BlockState blockstate : blocks) {
|
||||
((org.bukkit.craftbukkit.block.CraftBlockState) blockstate).revertPlace();
|
||||
+ ((org.bukkit.craftbukkit.block.CraftBlock) blockstate.getBlock()).getBlockState().getBlock().forgetPlacer(); // Purpur - Store placer on Block when placed
|
||||
}
|
||||
@@ -453,6 +_,7 @@
|
||||
// revert back all captured blocks
|
||||
for (org.bukkit.block.BlockState blockstate : blocks) {
|
||||
((org.bukkit.craftbukkit.block.CraftBlockState) blockstate).revertPlace();
|
||||
+ ((org.bukkit.craftbukkit.block.CraftBlock) blockstate.getBlock()).getBlockState().getBlock().forgetPlacer(); // Purpur - Store placer on Block when placed
|
||||
}
|
||||
|
||||
SignItem.openSign = null; // SPIGOT-6758 - Reset on early return
|
||||
@@ -475,6 +_,7 @@
|
||||
if (!(block.getBlock() instanceof net.minecraft.world.level.block.BaseEntityBlock)) { // Containers get placed automatically
|
||||
block.onPlace(level, newPos, oldBlock, true, context);
|
||||
}
|
||||
+ block.getBlock().forgetPlacer(); // Purpur - Store placer on Block when placed
|
||||
|
||||
level.notifyAndUpdatePhysics(newPos, null, oldBlock, block, level.getBlockState(newPos), updateFlags, net.minecraft.world.level.block.Block.UPDATE_LIMIT); // send null chunk as chunk.k() returns false by this point
|
||||
SignItem.openSign = null; // SPIGOT-6758 - Reset on early return
|
||||
@@ -476,6 +_,7 @@
|
||||
if (!(block.getBlock() instanceof net.minecraft.world.level.block.BaseEntityBlock)) { // Containers get placed automatically
|
||||
block.onPlace(level, newPos, oldBlock, true, context);
|
||||
}
|
||||
+ block.getBlock().forgetPlacer(); // Purpur - Store placer on Block when placed
|
||||
|
||||
level.notifyAndUpdatePhysics(newPos, null, oldBlock, block, level.getBlockState(newPos), updateFlags, net.minecraft.world.level.block.Block.UPDATE_LIMIT); // send null chunk as chunk.k() returns false by this point
|
||||
}
|
||||
@@ -591,6 +_,26 @@
|
||||
return this.isDamageableItem() && this.getDamageValue() > 0;
|
||||
}
|
||||
@@ -43,7 +43,7 @@
|
||||
public int getDamageValue() {
|
||||
return Mth.clamp(this.getOrDefault(DataComponents.DAMAGE, 0), 0, this.getMaxDamage());
|
||||
}
|
||||
@@ -1246,6 +_,12 @@
|
||||
@@ -1254,6 +_,12 @@
|
||||
public boolean isEnchanted() {
|
||||
return !this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY).isEmpty();
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
--- a/net/minecraft/world/item/ProjectileWeaponItem.java
|
||||
+++ b/net/minecraft/world/item/ProjectileWeaponItem.java
|
||||
@@ -114,6 +_,8 @@
|
||||
arrowx.setCritArrow(true);
|
||||
arrow.setCritArrow(true);
|
||||
}
|
||||
|
||||
+ arrowx.setActualEnchantments(weapon.getEnchantments()); // Purpur - Add an option to fix MC-3304 projectile looting
|
||||
+ arrow.setActualEnchantments(weapon.getEnchantments()); // Purpur - Add an option to fix MC-3304 projectile looting
|
||||
+
|
||||
return arrowx;
|
||||
return arrow;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
--- a/net/minecraft/world/item/ShovelItem.java
|
||||
+++ b/net/minecraft/world/item/ShovelItem.java
|
||||
@@ -46,9 +_,12 @@
|
||||
BlockState newState = FLATTENABLES.get(blockState.getBlock());
|
||||
BlockState updatedState = null;
|
||||
Runnable afterAction = null; // Paper
|
||||
+ org.purpurmc.purpur.tool.Flattenable flattenable = level.purpurConfig.shovelFlattenables.get(blockState.getBlock()); // Purpur - Tool actionable options
|
||||
if (newState != null && level.getBlockState(pos.above()).isAir()) {
|
||||
- afterAction = () -> level.playSound(player, pos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F); // Paper
|
||||
- updatedState = newState;
|
||||
@@ -47,9 +_,12 @@
|
||||
BlockState newState = FLATTENABLES.get(blockState.getBlock());
|
||||
BlockState updatedState = null;
|
||||
Runnable afterAction = null; // Paper
|
||||
- if (newState != null && level.getBlockState(pos.above()).isAir()) {
|
||||
- afterAction = () -> level.playSound(player, pos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F); // Paper
|
||||
- updatedState = newState;
|
||||
+ org.purpurmc.purpur.tool.Flattenable flattenable = level.purpurConfig.shovelFlattenables.get(blockState.getBlock()); // Purpur - Tool actionable options
|
||||
+ if (newState != null && level.getBlockState(pos.above()).isAir()) {
|
||||
+ // Purpur start - Tool actionable options
|
||||
+ afterAction = () -> {if (!FLATTENABLES.containsKey(blockState.getBlock())) level.playSound(player, pos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F);}; // Paper
|
||||
+ updatedState = flattenable.into().defaultBlockState();
|
||||
+ afterAction = () -> {if (!FLATTENABLES.containsKey(blockState.getBlock())) level.playSound(player, pos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F);}; // Paper
|
||||
+ updatedState = flattenable.into().defaultBlockState();
|
||||
+ // Purpur end - Tool actionable options
|
||||
} else if (blockState.getBlock() instanceof CampfireBlock && blockState.getValue(CampfireBlock.LIT)) {
|
||||
afterAction = () -> { // Paper
|
||||
if (!level.isClientSide()) {
|
||||
} else if (blockState.getBlock() instanceof CampfireBlock && blockState.getValue(CampfireBlock.LIT)) {
|
||||
afterAction = () -> { // Paper
|
||||
if (!level.isClientSide()) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/item/SpawnEggItem.java
|
||||
+++ b/net/minecraft/world/item/SpawnEggItem.java
|
||||
@@ -62,6 +_,23 @@
|
||||
@@ -64,6 +_,23 @@
|
||||
return InteractionResult.FAIL;
|
||||
} else {
|
||||
if (level.paperConfig().entities.spawning.disableMobSpawnerSpawnEggTransformation) return InteractionResult.FAIL; // Paper - Allow disabling mob spawner spawn egg transformation
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
--- a/net/minecraft/world/item/TridentItem.java
|
||||
+++ b/net/minecraft/world/item/TridentItem.java
|
||||
@@ -82,7 +_,7 @@
|
||||
if (riptideStrength == 0.0F) {
|
||||
ItemStack thrownItemStack = itemStack.copyWithCount(1); // Paper
|
||||
Projectile.Delayed<ThrownTrident> tridentDelayed = Projectile.spawnProjectileFromRotationDelayed( // Paper - PlayerLaunchProjectileEvent(
|
||||
- ThrownTrident::new, serverLevel, thrownItemStack, player, 0.0F, 2.5F, 1.0F
|
||||
+ ThrownTrident::new, serverLevel, thrownItemStack, player, 0.0F, 2.5F, (float) serverLevel.purpurConfig.tridentProjectileOffset // Purpur - Projectile offset config
|
||||
);
|
||||
// Paper start - PlayerLaunchProjectileEvent
|
||||
com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) tridentDelayed.projectile().getBukkitEntity());
|
||||
@@ -92,6 +_,7 @@
|
||||
return false;
|
||||
}
|
||||
ThrownTrident trident = tridentDelayed.projectile(); // Paper - PlayerLaunchProjectileEvent
|
||||
+ trident.setActualEnchantments(itemStack.getEnchantments()); // Purpur - Add an option to fix MC-3304 projectile looting
|
||||
if (event.shouldConsume()) {
|
||||
thrownItemStack.hurtWithoutBreaking(1, player); // Paper - PlayerLaunchProjectileEvent - use thrownItemStack; pickup item damage
|
||||
}
|
||||
@@ -84,7 +_,7 @@
|
||||
if (riptideStrength == 0.0F) {
|
||||
ItemStack thrownItemStack = itemStack.copyWithCount(1); // Paper
|
||||
Projectile.Delayed<ThrownTrident> tridentDelayed = Projectile.spawnProjectileFromRotationDelayed( // Paper - PlayerLaunchProjectileEvent(
|
||||
- ThrownTrident::new, serverLevel, thrownItemStack, player, 0.0F, 2.5F, 1.0F
|
||||
+ ThrownTrident::new, serverLevel, thrownItemStack, player, 0.0F, 2.5F, (float) serverLevel.purpurConfig.tridentProjectileOffset // Purpur - Projectile offset config
|
||||
);
|
||||
// Paper start - PlayerLaunchProjectileEvent
|
||||
com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) tridentDelayed.projectile().getBukkitEntity());
|
||||
@@ -94,6 +_,7 @@
|
||||
return false;
|
||||
}
|
||||
ThrownTrident trident = tridentDelayed.projectile(); // Paper - PlayerLaunchProjectileEvent
|
||||
+ trident.setActualEnchantments(itemStack.getEnchantments()); // Purpur - Add an option to fix MC-3304 projectile looting
|
||||
if (event.shouldConsume()) {
|
||||
thrownItemStack.hurtWithoutBreaking(1, player); // Paper - PlayerLaunchProjectileEvent - use thrownItemStack; pickup item damage
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
public boolean isExact() {
|
||||
return this.itemStacks != null;
|
||||
@@ -86,6 +_,11 @@
|
||||
@@ -88,6 +_,11 @@
|
||||
return this.itemStacks.contains(input); // Paper - Improve exact choice recipe ingredients (hashing FTW!)
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
this.generator = generator;
|
||||
this.world = new CraftWorld((ServerLevel) this, worldKey, biomeProvider, environment);
|
||||
|
||||
@@ -2194,4 +_,14 @@
|
||||
@@ -2197,4 +_,14 @@
|
||||
return this.moonrise$getEntityLookup().getEntityCount(); // Paper - rewrite chunk system
|
||||
}
|
||||
// Paper end - allow patching this logic
|
||||
|
||||
@@ -7,4 +7,4 @@
|
||||
+ if (!((net.minecraft.world.level.LevelAccessor) level).getMinecraftWorld().purpurConfig.coralDieOutsideWater) return true; // Purpur - Config to not let coral die
|
||||
if (state.getValue(WATERLOGGED)) {
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
--- a/net/minecraft/world/level/block/BaseFireBlock.java
|
||||
+++ b/net/minecraft/world/level/block/BaseFireBlock.java
|
||||
@@ -215,7 +_,7 @@
|
||||
boolean hasObsidian = false;
|
||||
@@ -216,7 +_,7 @@
|
||||
boolean hasObsidian = false;
|
||||
|
||||
for (Direction face : Direction.values()) {
|
||||
- if (level.getBlockState(testPos.set(pos).move(face)).is(Blocks.OBSIDIAN)) {
|
||||
+ if (PortalShape.FRAME.test(level.getBlockState(testPos.set(pos).move(face)), level, testPos)) { // Purpur - Crying obsidian valid for portal frames
|
||||
hasObsidian = true;
|
||||
break;
|
||||
}
|
||||
for (Direction face : Direction.values()) {
|
||||
- if (level.getBlockState(testPos.set(pos).move(face)).is(Blocks.OBSIDIAN)) {
|
||||
+ if (PortalShape.FRAME.test(level.getBlockState(testPos.set(pos).move(face)), level, testPos)) { // Purpur - Crying obsidian valid for portal frames
|
||||
hasObsidian = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
--- a/net/minecraft/world/level/block/BedBlock.java
|
||||
+++ b/net/minecraft/world/level/block/BedBlock.java
|
||||
@@ -100,7 +_,7 @@
|
||||
}
|
||||
@@ -101,7 +_,7 @@
|
||||
}
|
||||
|
||||
Vec3 boomPos = pos.getCenter();
|
||||
- level.explode(null, level.damageSources().badRespawnPointExplosion(boomPos), null, boomPos, 5.0F, true, Level.ExplosionInteraction.BLOCK);
|
||||
+ if (level.purpurConfig.bedExplode) level.explode(null, level.damageSources().badRespawnPointExplosion(boomPos), null, boomPos, (float) level.purpurConfig.bedExplosionPower, level.purpurConfig.bedExplosionFire, level.purpurConfig.bedExplosionEffect); // Purpur - Implement bed explosion options
|
||||
return InteractionResult.SUCCESS_SERVER;
|
||||
} else if (state.getValue(OCCUPIED)) {
|
||||
if (bedRule.explodes()) return this.explodeBed(state, level, pos); // Paper - check explode first
|
||||
Vec3 boomPos = pos.getCenter();
|
||||
- level.explode(null, level.damageSources().badRespawnPointExplosion(boomPos), null, boomPos, 5.0F, true, Level.ExplosionInteraction.BLOCK);
|
||||
+ if (level.purpurConfig.bedExplode) level.explode(null, level.damageSources().badRespawnPointExplosion(boomPos), null, boomPos, (float) level.purpurConfig.bedExplosionPower, level.purpurConfig.bedExplosionFire, level.purpurConfig.bedExplosionEffect); // Purpur - Implement bed explosion options
|
||||
return InteractionResult.SUCCESS_SERVER;
|
||||
} else if (state.getValue(OCCUPIED)) {
|
||||
if (bedRule.explodes()) return this.explodeBed(state, level, pos); // Paper - check explode first
|
||||
@@ -153,7 +_,7 @@
|
||||
}
|
||||
|
||||
Vec3 center = pos.getCenter();
|
||||
- level.explode(null, level.damageSources().badRespawnPointExplosion(center).causingBlockSnapshot(blockState), null, center, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state
|
||||
+ if (level.purpurConfig.bedExplode) level.explode(null, level.damageSources().badRespawnPointExplosion(center).causingBlockSnapshot(blockState), null, center, (float) level.purpurConfig.bedExplosionPower, level.purpurConfig.bedExplosionFire, level.purpurConfig.bedExplosionEffect); // CraftBukkit - add state // Purpur - Implement bed explosion options
|
||||
Vec3 boomPos = pos.getCenter();
|
||||
- level.explode(null, level.damageSources().badRespawnPointExplosion(boomPos).causingBlockSnapshot(blockState), null, boomPos, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state
|
||||
+ if (level.purpurConfig.bedExplode) level.explode(null, level.damageSources().badRespawnPointExplosion(boomPos).causingBlockSnapshot(blockState), null, boomPos, (float) level.purpurConfig.bedExplosionPower, level.purpurConfig.bedExplosionFire, level.purpurConfig.bedExplosionEffect); // CraftBukkit - add state // Purpur - Implement bed explosion options
|
||||
return InteractionResult.SUCCESS_SERVER;
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
// Paper start - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
public final boolean isDestroyable() {
|
||||
return io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits ||
|
||||
@@ -411,7 +_,7 @@
|
||||
@@ -415,7 +_,7 @@
|
||||
event.setExpToDrop(block.getExpDrop(state, serverLevel, pos, net.minecraft.world.item.ItemStack.EMPTY, true)); // Paper - Properly handle xp dropping
|
||||
event.callEvent();
|
||||
for (org.bukkit.inventory.ItemStack drop : event.getDrops()) {
|
||||
@@ -20,7 +20,7 @@
|
||||
}
|
||||
state.spawnAfterBreak(serverLevel, pos, ItemStack.EMPTY, false); // Paper - Properly handle xp dropping
|
||||
block.popExperience(serverLevel, pos, event.getExpToDrop()); // Paper - Properly handle xp dropping
|
||||
@@ -429,7 +_,7 @@
|
||||
@@ -433,7 +_,7 @@
|
||||
|
||||
public static void dropResources(final BlockState state, final LevelAccessor level, final BlockPos pos, final @Nullable BlockEntity blockEntity) {
|
||||
if (level instanceof ServerLevel serverLevel) {
|
||||
@@ -29,7 +29,7 @@
|
||||
state.spawnAfterBreak(serverLevel, pos, ItemStack.EMPTY, true);
|
||||
}
|
||||
}
|
||||
@@ -450,11 +_,30 @@
|
||||
@@ -454,11 +_,30 @@
|
||||
, final boolean dropExperience // Paper - Properly handle xp dropping
|
||||
) {
|
||||
if (level instanceof ServerLevel serverLevel) {
|
||||
@@ -61,7 +61,7 @@
|
||||
public static void popResource(final Level level, final BlockPos pos, final ItemStack itemStack) {
|
||||
double halfHeight = EntityType.ITEM.getHeight() / 2.0;
|
||||
RandomSource random = level.getRandom();
|
||||
@@ -544,7 +_,15 @@
|
||||
@@ -548,7 +_,15 @@
|
||||
}
|
||||
|
||||
public void setPlacedBy(final Level level, final BlockPos pos, final BlockState state, final @Nullable LivingEntity by, final ItemStack itemStack) {
|
||||
@@ -78,7 +78,7 @@
|
||||
|
||||
public boolean isPossibleToRespawnInThis(final BlockState state) {
|
||||
return !state.isSolid() && !state.liquid();
|
||||
@@ -555,7 +_,7 @@
|
||||
@@ -559,7 +_,7 @@
|
||||
}
|
||||
|
||||
public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
--- a/net/minecraft/world/level/block/CakeBlock.java
|
||||
+++ b/net/minecraft/world/level/block/CakeBlock.java
|
||||
@@ -118,6 +_,7 @@
|
||||
org.bukkit.event.entity.FoodLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFoodLevelChangeEvent(player, 2 + oldFoodLevel);
|
||||
@@ -119,6 +_,7 @@
|
||||
org.bukkit.event.entity.FoodLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFoodLevelChangeEvent(player, 2 + oldFoodLevel);
|
||||
|
||||
if (!event.isCancelled()) {
|
||||
+ if (player.level().purpurConfig.playerBurpWhenFull && event.getFoodLevel() == 20 && oldFoodLevel < 20) player.burpDelay = player.level().purpurConfig.playerBurpDelay; // Purpur - Burp after eating food fills hunger bar completely
|
||||
player.getFoodData().eat(event.getFoodLevel() - oldFoodLevel, 0.1F);
|
||||
}
|
||||
if (!event.isCancelled()) {
|
||||
+ if (player.level().purpurConfig.playerBurpWhenFull && event.getFoodLevel() == 20 && oldFoodLevel < 20) player.burpDelay = player.level().purpurConfig.playerBurpDelay; // Purpur - Burp after eating food fills hunger bar completely
|
||||
player.getFoodData().eat(event.getFoodLevel() - oldFoodLevel, 0.1F);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/level/block/ChestBlock.java
|
||||
+++ b/net/minecraft/world/level/block/ChestBlock.java
|
||||
@@ -352,6 +_,7 @@
|
||||
@@ -347,6 +_,7 @@
|
||||
}
|
||||
|
||||
public static boolean isBlockedChestByBlock(final BlockGetter level, final BlockPos pos) {
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
--- a/net/minecraft/world/level/block/DoorBlock.java
|
||||
+++ b/net/minecraft/world/level/block/DoorBlock.java
|
||||
@@ -200,6 +_,7 @@
|
||||
@@ -200,7 +_,7 @@
|
||||
protected InteractionResult useWithoutItem(BlockState state, final Level level, final BlockPos pos, final Player player, final BlockHitResult hitResult) {
|
||||
if (!this.type.canOpenByHand()) {
|
||||
return InteractionResult.PASS;
|
||||
+ } else if (requiresRedstone(level, state, pos)) { return InteractionResult.CONSUME; // Purpur - Option to make doors require redstone
|
||||
} else {
|
||||
state = state.cycle(OPEN);
|
||||
level.setBlock(pos, state, Block.UPDATE_CLIENTS | Block.UPDATE_IMMEDIATE);
|
||||
- }
|
||||
+ } else if (requiresRedstone(level, state, pos)) { return InteractionResult.CONSUME; } // Purpur - Option to make doors require redstone
|
||||
|
||||
state = state.cycle(OPEN);
|
||||
level.setBlock(pos, state, Block.UPDATE_CLIENTS | Block.UPDATE_IMMEDIATE);
|
||||
@@ -280,4 +_,18 @@
|
||||
public static boolean isWoodenDoor(final BlockState state) {
|
||||
return state.getBlock() instanceof DoorBlock door && door.type().canOpenByHand();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/level/block/PointedDripstoneBlock.java
|
||||
+++ b/net/minecraft/world/level/block/PointedDripstoneBlock.java
|
||||
@@ -194,20 +_,20 @@
|
||||
@@ -196,20 +_,20 @@
|
||||
|
||||
@VisibleForTesting
|
||||
public static void maybeTransferFluid(final BlockState state, final ServerLevel level, final BlockPos pos, final float randomValue) {
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
- if (searchDepth >= 8) {
|
||||
+ if (searchDepth >= level.purpurConfig.railActivationRange) { // Purpur - Config for powered rail activation distance
|
||||
return false;
|
||||
} else {
|
||||
int x = pos.getX();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/level/block/RespawnAnchorBlock.java
|
||||
+++ b/net/minecraft/world/level/block/RespawnAnchorBlock.java
|
||||
@@ -180,7 +_,7 @@
|
||||
@@ -176,7 +_,7 @@
|
||||
}
|
||||
};
|
||||
Vec3 boomPos = pos.getCenter();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
@@ -195,6 +_,21 @@
|
||||
@@ -190,6 +_,21 @@
|
||||
}
|
||||
|
||||
ItemStack fuel = entity.items.get(1);
|
||||
@@ -22,7 +22,7 @@
|
||||
ItemStack ingredient = entity.items.get(0);
|
||||
boolean hasIngredient = !ingredient.isEmpty();
|
||||
boolean hasFuel = !fuel.isEmpty();
|
||||
@@ -273,6 +_,8 @@
|
||||
@@ -268,6 +_,8 @@
|
||||
if (changed) {
|
||||
setChanged(level, pos, state);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
|
||||
@@ -142,6 +_,16 @@
|
||||
@@ -138,6 +_,16 @@
|
||||
|
||||
public double getEffectRange() {
|
||||
if (this.effectRange < 0) {
|
||||
@@ -17,7 +17,7 @@
|
||||
return this.levels * 10 + 10;
|
||||
} else {
|
||||
return effectRange;
|
||||
@@ -170,6 +_,7 @@
|
||||
@@ -166,6 +_,7 @@
|
||||
int y = pos.getY();
|
||||
int z = pos.getZ();
|
||||
BlockPos checkPos;
|
||||
@@ -25,7 +25,7 @@
|
||||
if (entity.lastCheckY < y) {
|
||||
checkPos = pos;
|
||||
entity.checkingBeamSections = Lists.newArrayList();
|
||||
@@ -199,11 +_,15 @@
|
||||
@@ -195,11 +_,15 @@
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
lastBeamSection.increaseHeight();
|
||||
}
|
||||
@@ -214,11 +_,11 @@
|
||||
@@ -210,11 +_,11 @@
|
||||
|
||||
int previousLevels = entity.levels;
|
||||
if (level.getGameTime() % 80L == 0L) {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
private static final int MIN_TICKS_BEFORE_REENTERING_HIVE = 400;
|
||||
private static final int MIN_OCCUPATION_TICKS_NECTAR = 2400;
|
||||
public static final int MIN_OCCUPATION_TICKS_NECTARLESS = 600;
|
||||
@@ -157,11 +_,33 @@
|
||||
@@ -157,10 +_,32 @@
|
||||
return spawned;
|
||||
}
|
||||
|
||||
@@ -33,24 +33,12 @@
|
||||
public int getOccupantCount() {
|
||||
return this.stored.size();
|
||||
}
|
||||
|
||||
+
|
||||
+ // Purpur start - Stored Bee API
|
||||
+ public List<BeeData> getStored() {
|
||||
+ return stored;
|
||||
+ }
|
||||
+ // Purpur end - Stored Bee API
|
||||
+
|
||||
|
||||
// Paper start - Add EntityBlockStorage clearEntities
|
||||
public void clearBees() {
|
||||
this.stored.clear();
|
||||
@@ -400,8 +_,8 @@
|
||||
registration.register(DebugSubscriptions.BEE_HIVES, () -> DebugHiveInfo.pack(this));
|
||||
}
|
||||
|
||||
- private static class BeeData {
|
||||
- private final BeehiveBlockEntity.Occupant occupant;
|
||||
+ public static class BeeData { // Purpur - make public - Stored Bee API
|
||||
+ public final BeehiveBlockEntity.Occupant occupant; // Purpur - make public - Stored Bee API
|
||||
private int exitTickCounter; // Paper - Fix bees aging inside hives; separate counter for checking if bee should exit to reduce exit attempts
|
||||
private int ticksInHive;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
@@ -108,6 +_,10 @@
|
||||
@@ -107,6 +_,10 @@
|
||||
input.read("PublicBukkitValues", CompoundTag.CODEC)
|
||||
.ifPresent(this.persistentDataContainer::putAll);
|
||||
// Paper end - read persistent data container
|
||||
@@ -11,7 +11,7 @@
|
||||
}
|
||||
|
||||
public final void loadWithComponents(final ValueInput input) {
|
||||
@@ -120,6 +_,11 @@
|
||||
@@ -119,6 +_,11 @@
|
||||
}
|
||||
|
||||
protected void saveAdditional(final ValueOutput output) {
|
||||
@@ -23,7 +23,7 @@
|
||||
}
|
||||
|
||||
public final CompoundTag saveWithFullMetadata(final HolderLookup.Provider registries) {
|
||||
@@ -414,4 +_,16 @@
|
||||
@@ -395,4 +_,16 @@
|
||||
return this.blockEntity.getNameForReporting() + "@" + this.blockEntity.getBlockPos();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
--- a/net/minecraft/world/level/block/entity/ConduitBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/ConduitBlockEntity.java
|
||||
@@ -150,7 +_,7 @@
|
||||
BlockPos testPos = worldPosition.offset(ox, oy, ozx);
|
||||
@@ -151,7 +_,7 @@
|
||||
BlockPos testPos = worldPosition.offset(ox, oy, oz);
|
||||
BlockState testBlock = level.getBlockState(testPos);
|
||||
|
||||
- for (Block type : VALID_BLOCKS) {
|
||||
@@ -9,7 +9,7 @@
|
||||
if (testBlock.is(type)) {
|
||||
effectBlocks.add(testPos);
|
||||
}
|
||||
@@ -165,13 +_,13 @@
|
||||
@@ -166,13 +_,13 @@
|
||||
|
||||
private static void applyEffects(final Level level, final BlockPos worldPosition, final List<BlockPos> effectBlocks) {
|
||||
// CraftBukkit start
|
||||
@@ -26,7 +26,7 @@
|
||||
// CraftBukkit start
|
||||
return effectRange;
|
||||
}
|
||||
@@ -204,7 +_,7 @@
|
||||
@@ -205,7 +_,7 @@
|
||||
EntityReference<LivingEntity> newDestroyTarget = updateDestroyTarget(entity.destroyTarget, level, worldPosition, isActive);
|
||||
LivingEntity targetEntity = EntityReference.getLivingEntity(newDestroyTarget, level);
|
||||
if (damageTarget && targetEntity != null) { // CraftBukkit
|
||||
@@ -35,13 +35,12 @@
|
||||
level.playSound(
|
||||
null, targetEntity.getX(), targetEntity.getY(), targetEntity.getZ(), SoundEvents.CONDUIT_ATTACK_TARGET, SoundSource.BLOCKS, 1.0F, 1.0F
|
||||
);
|
||||
@@ -225,19 +_,25 @@
|
||||
return selectNewTarget(level, pos);
|
||||
} else {
|
||||
LivingEntity targetEntity = EntityReference.getLivingEntity(target, level);
|
||||
- return targetEntity != null && targetEntity.isAlive() && pos.closerThan(targetEntity.blockPosition(), 8.0) ? target : null;
|
||||
+ return targetEntity != null && targetEntity.isAlive() && pos.closerThan(targetEntity.blockPosition(), level.purpurConfig.conduitDamageDistance) ? target : null; // Purpur - Conduit behavior configuration
|
||||
@@ -229,18 +_,24 @@
|
||||
}
|
||||
|
||||
LivingEntity targetEntity = EntityReference.getLivingEntity(target, level);
|
||||
- return targetEntity != null && targetEntity.isAlive() && pos.closerThan(targetEntity.blockPosition(), 8.0) ? target : null;
|
||||
+ return targetEntity != null && targetEntity.isAlive() && pos.closerThan(targetEntity.blockPosition(), level.purpurConfig.conduitDamageDistance) ? target : null; // Purpur - Conduit behavior configuration
|
||||
}
|
||||
|
||||
private static @Nullable EntityReference<LivingEntity> selectNewTarget(final ServerLevel level, final BlockPos pos) {
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -309,6 +_,27 @@
|
||||
@@ -310,6 +_,27 @@
|
||||
commandSource, Vec3.atCenterOf(pos), Vec2.ZERO, level, LevelBasedPermissionSet.GAMEMASTER, textName, displayName, level.getServer(), player // Paper - Fix commands from signs not firing command events
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
--- a/net/minecraft/world/level/block/piston/PistonStructureResolver.java
|
||||
+++ b/net/minecraft/world/level/block/piston/PistonStructureResolver.java
|
||||
@@ -81,7 +_,7 @@
|
||||
return true;
|
||||
} else {
|
||||
int blockCount = 1;
|
||||
- if (blockCount + this.toPush.size() > 12) {
|
||||
+ if (blockCount + this.toPush.size() > this.level.purpurConfig.pistonBlockPushLimit) { // Purpur - Configurable piston push limit
|
||||
@@ -90,7 +_,7 @@
|
||||
}
|
||||
|
||||
int blockCount = 1;
|
||||
- if (blockCount + this.toPush.size() > 12) {
|
||||
+ if (blockCount + this.toPush.size() > this.level.purpurConfig.pistonBlockPushLimit) { // Purpur - Configurable piston push limit
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -105,7 +_,7 @@
|
||||
break;
|
||||
}
|
||||
|
||||
- if (++blockCount + this.toPush.size() > 12) {
|
||||
+ if (++blockCount + this.toPush.size() > this.level.purpurConfig.pistonBlockPushLimit) { // Purpur - Configurable piston push limit
|
||||
return false;
|
||||
} else {
|
||||
while (isSticky(nextState)) {
|
||||
@@ -95,7 +_,7 @@
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -149,7 +_,7 @@
|
||||
return true;
|
||||
}
|
||||
|
||||
- if (++blockCount + this.toPush.size() > 12) {
|
||||
+ if (++blockCount + this.toPush.size() > this.level.purpurConfig.pistonBlockPushLimit) { // Purpur - Configurable piston push limit
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -139,7 +_,7 @@
|
||||
return true;
|
||||
}
|
||||
|
||||
- if (this.toPush.size() >= 12) {
|
||||
+ if (this.toPush.size() >= this.level.purpurConfig.pistonBlockPushLimit) { // Purpur - Configurable piston push limit
|
||||
return false;
|
||||
}
|
||||
- if (this.toPush.size() >= 12) {
|
||||
+ if (this.toPush.size() >= this.level.purpurConfig.pistonBlockPushLimit) { // Purpur - Configurable piston push limit
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/level/chunk/storage/EntityStorage.java
|
||||
+++ b/net/minecraft/world/level/chunk/storage/EntityStorage.java
|
||||
@@ -108,6 +_,7 @@
|
||||
@@ -105,6 +_,7 @@
|
||||
}
|
||||
// Paper end - Entity load/save limit per chunk
|
||||
TagValueOutput output = TagValueOutput.createWithContext(reporter.forChild(e.problemPath()), e.registryAccess());
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
// Paper start
|
||||
private static void printOversizedLog(String msg, Path file, int x, int z) {
|
||||
- org.apache.logging.log4j.LogManager.getLogger().fatal(msg + " (" + file.toString().replaceAll(".+[\\\\/]", "") + " - " + x + "," + z + ") Go clean it up to remove this message. /minecraft:tp " + (x<<4)+" 128 "+(z<<4) + " - DO NOT REPORT THIS TO PAPER - You may ask for help on Discord, but do not file an issue. These error messages can not be removed.");
|
||||
+ org.apache.logging.log4j.LogManager.getLogger().fatal(msg + " (" + file.toString().replaceAll(".+[\\\\/]", "") + " - " + x + "," + z + ") Go clean it up to remove this message. /minecraft:tp " + (x<<4)+" 128 "+(z<<4) + " - DO NOT REPORT THIS TO PURPUR - You may ask for help on Discord, but do not file an issue. These error messages can not be removed."); // Purpur - Rebrand
|
||||
- LOGGER.error("{} ({} - {},{}) Go clean it up to remove this message. /minecraft:tp {} 128 {} - DO NOT REPORT THIS TO PAPER - You may ask for help on Discord, but do not file an issue. These error messages can not be removed.", msg, file.toString().replaceAll(".+[\\\\/]", ""), x, z, x << 4, z << 4);
|
||||
+ LOGGER.error("{} ({} - {},{}) Go clean it up to remove this message. /minecraft:tp {} 128 {} - DO NOT REPORT THIS TO PURPUR - You may ask for help on Discord, but do not file an issue. These error messages can not be removed.", msg, file.toString().replaceAll(".+[\\\\/]", ""), x, z, x << 4, z << 4); // Purpur - Rebrand
|
||||
}
|
||||
|
||||
private static CompoundTag readOversizedChunk(RegionFile regionfile, ChunkPos chunkCoordinate) throws IOException {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/level/material/FlowingFluid.java
|
||||
+++ b/net/minecraft/world/level/material/FlowingFluid.java
|
||||
@@ -235,7 +_,7 @@
|
||||
@@ -234,7 +_,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
BlockState belowState = level.getBlockState(mutablePos.setWithOffset(pos, Direction.DOWN));
|
||||
FluidState belowFluid = belowState.getFluidState();
|
||||
if (belowState.isSolid() || this.isSourceBlockOfThisType(belowFluid)) {
|
||||
@@ -321,6 +_,12 @@
|
||||
@@ -320,6 +_,12 @@
|
||||
}
|
||||
|
||||
protected abstract boolean canConvertToSource(ServerLevel level);
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
--- a/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java
|
||||
+++ b/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java
|
||||
@@ -249,7 +_,7 @@
|
||||
if ((best == null || best.costMalus < 0.0F)
|
||||
&& jumpSize > 0
|
||||
&& (pathType != PathType.FENCE || this.canWalkOverFences())
|
||||
- && pathType != PathType.UNPASSABLE_RAIL
|
||||
+ && (this.mob.level().purpurConfig.mobsIgnoreRails || pathType != PathType.UNPASSABLE_RAIL) // Purpur - Config to allow mobs to pathfind over rails
|
||||
&& pathType != PathType.TRAPDOOR
|
||||
&& pathType != PathType.POWDER_SNOW) {
|
||||
best = this.tryJumpOn(x, y, z, jumpSize, nodeHeight, travelDirection, blockPathTypeCurrent, reusablePos);
|
||||
@@ -517,7 +_,7 @@
|
||||
return PathType.TRAPDOOR;
|
||||
} else if (blockState.is(Blocks.POWDER_SNOW)) {
|
||||
@@ -252,7 +_,7 @@
|
||||
if ((best == null || best.costMalus < 0.0F)
|
||||
&& jumpSize > 0
|
||||
&& (pathType != PathType.FENCE || this.canWalkOverFences())
|
||||
- && pathType != PathType.UNPASSABLE_RAIL
|
||||
+ && (this.mob.level().purpurConfig.mobsIgnoreRails || pathType != PathType.UNPASSABLE_RAIL) // Purpur - Config to allow mobs to pathfind over rails
|
||||
&& pathType != PathType.TRAPDOOR
|
||||
&& pathType != PathType.POWDER_SNOW) {
|
||||
best = this.tryJumpOn(x, y, z, jumpSize, nodeHeight, travelDirection, blockPathTypeCurrent, reusablePos);
|
||||
@@ -533,7 +_,7 @@
|
||||
return PathType.POWDER_SNOW;
|
||||
- } else if (blockState.is(Blocks.CACTUS) || blockState.is(Blocks.SWEET_BERRY_BUSH)) {
|
||||
+ } else if (blockState.is(Blocks.CACTUS) || blockState.is(Blocks.SWEET_BERRY_BUSH) || blockState.is(Blocks.STONECUTTER)) { // Purpur - Stonecutter damage
|
||||
}
|
||||
|
||||
- if (blockState.is(Blocks.CACTUS) || blockState.is(Blocks.SWEET_BERRY_BUSH)) {
|
||||
+ if (blockState.is(Blocks.CACTUS) || blockState.is(Blocks.SWEET_BERRY_BUSH) || blockState.is(Blocks.STONECUTTER)) { // Purpur - Stonecutter damage
|
||||
return PathType.DAMAGING;
|
||||
} else if (blockState.is(Blocks.HONEY_BLOCK)) {
|
||||
return PathType.STICKY_HONEY;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
--- a/net/minecraft/world/phys/AABB.java
|
||||
+++ b/net/minecraft/world/phys/AABB.java
|
||||
@@ -485,5 +_,11 @@
|
||||
return new AABB(this.minX, this.minY, this.minZ, this.maxX, this.maxY, this.maxZ);
|
||||
@@ -486,4 +_,9 @@
|
||||
}
|
||||
}
|
||||
- }
|
||||
+
|
||||
+ }
|
||||
}
|
||||
+ // Purpur start - Stop squids floating on top of water - tuinity added method
|
||||
+ public final AABB offsetY(double dy) {
|
||||
+ return new AABB(this.minX, this.minY + dy, this.minZ, this.maxX, this.maxY + dy, this.maxZ);
|
||||
|
||||
Reference in New Issue
Block a user