mirror of
https://github.com/PurpurMC/Purpur.git
synced 2026-04-21 02:38:16 +02:00
99/103 rejected minecraft source files applied
This commit is contained in:
@@ -1,114 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index ca2caace6aab0dfcb0ab7a0fd28e66555c62fdc5..7a54f6bc2a364c1d3ac1ed58b33ecf720a305840 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -290,6 +290,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
public joptsimple.OptionSet options;
|
||||
public org.bukkit.command.ConsoleCommandSender console;
|
||||
public static int currentTick; // Paper - improve tick loop
|
||||
+ public static final long startTimeMillis = System.currentTimeMillis(); // Purpur - Add uptime command
|
||||
public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
|
||||
public int autosavePeriod;
|
||||
// Paper - don't store the vanilla dispatcher
|
||||
@@ -306,6 +307,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
public boolean isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked
|
||||
private final Set<String> pluginsBlockingSleep = new java.util.HashSet<>(); // Paper - API to allow/disallow tick sleeping
|
||||
public static final long SERVER_INIT = System.nanoTime(); // Paper - Lag compensation
|
||||
+ public boolean lagging = false; // Purpur - Lagging threshold
|
||||
+ protected boolean upnp = false; // Purpur - UPnP Port Forwarding
|
||||
// Paper start - improve tick loop
|
||||
public final ca.spottedleaf.moonrise.common.time.TickData tickTimes1s = new ca.spottedleaf.moonrise.common.time.TickData(java.util.concurrent.TimeUnit.SECONDS.toNanos(1L));
|
||||
public final ca.spottedleaf.moonrise.common.time.TickData tickTimes5s = new ca.spottedleaf.moonrise.common.time.TickData(java.util.concurrent.TimeUnit.SECONDS.toNanos(5L));
|
||||
@@ -375,6 +378,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
public double[] computeTPS() {
|
||||
final long interval = this.tickRateManager().nanosecondsPerTick();
|
||||
return new double[] {
|
||||
+ getTPS(this.tickTimes5s, interval), // Purpur - Add 5 second tps average in /tps
|
||||
getTPS(this.tickTimes1m, interval),
|
||||
getTPS(this.tickTimes5m, interval),
|
||||
getTPS(this.tickTimes15m, interval)
|
||||
@@ -1014,6 +1018,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
LOGGER.info("Stopping server");
|
||||
Commands.COMMAND_SENDING_POOL.shutdownNow(); // Paper - Perf: Async command map building; Shutdown and don't bother finishing
|
||||
+ // Purpur start - UPnP Port Forwarding
|
||||
+ if (upnp) {
|
||||
+ if (dev.omega24.upnp4j.UPnP4J.close(this.getPort(), dev.omega24.upnp4j.util.Protocol.TCP)) {
|
||||
+ LOGGER.info("[UPnP] Port {} closed", this.getPort());
|
||||
+ } else {
|
||||
+ LOGGER.error("[UPnP] Failed to close port {}", this.getPort());
|
||||
+ }
|
||||
+ }
|
||||
+ // Purpur end - UPnP Port Forwarding
|
||||
// CraftBukkit start
|
||||
if (this.server != null) {
|
||||
this.server.spark.disable(); // Paper - spark
|
||||
@@ -1107,6 +1120,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.safeShutdown(waitForShutdown, false);
|
||||
}
|
||||
public void safeShutdown(boolean waitForShutdown, boolean isRestarting) {
|
||||
+ org.purpurmc.purpur.task.BossBarTask.stopAll(); // Purpur - Implement TPSBar
|
||||
+ org.purpurmc.purpur.task.BeehiveTask.instance().unregister(); // Purpur - Give bee counts in beehives to Purpur clients
|
||||
this.isRestarting = isRestarting;
|
||||
this.hasLoggedStop = true; // Paper - Debugging
|
||||
if (isDebugging()) io.papermc.paper.util.TraceUtil.dumpTraceForThread("Server stopped"); // Paper - Debugging
|
||||
@@ -1284,11 +1299,21 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
// Paper end - Add onboarding message for initial server start
|
||||
// Paper start - Improve outdated version checking
|
||||
- if (System.getProperty("paper.disableStartupVersionCheck") == null && io.papermc.paper.configuration.GlobalConfiguration.get().updateChecker.enabled) {
|
||||
+ if (false && System.getProperty("paper.disableStartupVersionCheck") == null && io.papermc.paper.configuration.GlobalConfiguration.get().updateChecker.enabled) { // Purpur - disable paper startup check
|
||||
CompletableFuture.runAsync(com.destroystokyo.paper.PaperVersionFetcher::getUpdateStatusStartupMessage, io.papermc.paper.util.MCUtil.ASYNC_EXECUTOR);
|
||||
}
|
||||
// Paper end - Improve outdated version checking
|
||||
|
||||
+ // Purpur start - config for startup commands
|
||||
+ if (!Boolean.getBoolean("Purpur.IReallyDontWantStartupCommands") && !org.purpurmc.purpur.PurpurConfig.startupCommands.isEmpty()) {
|
||||
+ LOGGER.info("Purpur: Running startup commands specified in purpur.yml.");
|
||||
+ for (final String startupCommand : org.purpurmc.purpur.PurpurConfig.startupCommands) {
|
||||
+ LOGGER.info("Purpur: Running the following command: \"{}\"", startupCommand);
|
||||
+ ((net.minecraft.server.dedicated.DedicatedServer) this).handleConsoleInput(startupCommand, this.createCommandSourceStack());
|
||||
+ }
|
||||
+ }
|
||||
+ // Purpur end - config for startup commands
|
||||
+
|
||||
while (this.running) {
|
||||
final long tickStart = System.nanoTime(); // Paper - improve tick loop
|
||||
long l; // Paper - improve tick loop - diff on change, expect this to be tick interval
|
||||
@@ -1302,9 +1327,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
final long ticksBehind = Math.max(1L, this.tickSchedule.getPeriodsAhead(l, tickStart));
|
||||
final long catchup = (long)Math.max(
|
||||
1,
|
||||
- 5 //ConfigHolder.getConfig().tickLoop.catchupTicks.getOrDefault(MoonriseConfig.TickLoop.DEFAULT_CATCHUP_TICKS).intValue()
|
||||
+ org.purpurmc.purpur.PurpurConfig.tpsCatchup ? 5 : 1 //ConfigHolder.getConfig().tickLoop.catchupTicks.getOrDefault(MoonriseConfig.TickLoop.DEFAULT_CATCHUP_TICKS).intValue() // Purpur - Configurable TPS Catchup
|
||||
);
|
||||
|
||||
+ lagging = getTPS()[0] < org.purpurmc.purpur.PurpurConfig.laggingThreshold; // Purpur - Lagging threshold
|
||||
+
|
||||
// adjust ticksBehind so that it is not greater-than catchup
|
||||
if (ticksBehind > catchup) {
|
||||
final long difference = ticksBehind - catchup;
|
||||
@@ -1785,7 +1812,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
long worldTime = level.getGameTime();
|
||||
final ClientboundSetTimePacket worldPacket = new ClientboundSetTimePacket(worldTime, dayTime, doDaylight);
|
||||
for (Player entityhuman : level.players()) {
|
||||
- if (!(entityhuman instanceof ServerPlayer) || (tickCount + entityhuman.getId()) % 20 != 0) {
|
||||
+ if (!(entityhuman instanceof ServerPlayer) || (!level.isForceTime() && (tickCount + entityhuman.getId()) % 20 != 0)) { // Purpur - Configurable daylight cycle
|
||||
continue;
|
||||
}
|
||||
ServerPlayer entityplayer = (ServerPlayer) entityhuman;
|
||||
@@ -1952,7 +1979,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
@DontObfuscate
|
||||
public String getServerModName() {
|
||||
- return io.papermc.paper.ServerBuildInfo.buildInfo().brandName(); // Paper
|
||||
+ return org.purpurmc.purpur.PurpurConfig.serverModName; // Paper // Purpur - Configurable server mod name
|
||||
}
|
||||
|
||||
public SystemReport fillSystemReport(SystemReport systemReport) {
|
||||
@@ -1,224 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index dc65503a2d785d64d37b76b0303f51cf66d9769a..5130c0067f01eec31c69b9e71d904f932943b922 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -218,6 +218,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
private final StructureManager structureManager;
|
||||
private final StructureCheck structureCheck;
|
||||
private final boolean tickTime;
|
||||
+ private double preciseTime; // Purpur - Configurable daylight cycle
|
||||
+ private boolean forceTime; // Purpur - Configurable daylight cycle
|
||||
private final RandomSequences randomSequences;
|
||||
final LevelDebugSynchronizers debugSynchronizers = new LevelDebugSynchronizers(this);
|
||||
|
||||
@@ -622,8 +624,25 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
// CraftBukkit end
|
||||
this.tickTime = tickTime;
|
||||
this.server = server;
|
||||
- this.customSpawners = customSpawners;
|
||||
+ this.customSpawners = new ArrayList<>(); // Purpur - Allow toggling special MobSpawners per world
|
||||
this.serverLevelData = serverLevelData;
|
||||
+ // Purpur start - Allow toggling special MobSpawners per world
|
||||
+ if (purpurConfig.phantomSpawning) {
|
||||
+ this.customSpawners.add(new net.minecraft.world.level.levelgen.PhantomSpawner());
|
||||
+ }
|
||||
+ if (purpurConfig.patrolSpawning) {
|
||||
+ this.customSpawners.add(new net.minecraft.world.level.levelgen.PatrolSpawner());
|
||||
+ }
|
||||
+ if (purpurConfig.catSpawning) {
|
||||
+ this.customSpawners.add(new net.minecraft.world.entity.npc.CatSpawner());
|
||||
+ }
|
||||
+ if (purpurConfig.villageSiegeSpawning) {
|
||||
+ this.customSpawners.add(new net.minecraft.world.entity.ai.village.VillageSiege());
|
||||
+ }
|
||||
+ if (purpurConfig.villagerTraderSpawning) {
|
||||
+ this.customSpawners.add(new net.minecraft.world.entity.npc.wanderingtrader.WanderingTraderSpawner(serverLevelData));
|
||||
+ }
|
||||
+ // Purpur end - Allow toggling special MobSpawners per world
|
||||
ChunkGenerator chunkGenerator = levelStem.generator();
|
||||
// CraftBukkit start
|
||||
this.serverLevelData.setWorld(this);
|
||||
@@ -709,6 +728,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
this.chunkDataController = new ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.ChunkDataController((ServerLevel)(Object)this, this.chunkTaskScheduler);
|
||||
// Paper end - rewrite chunk system
|
||||
this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit
|
||||
+ this.preciseTime = this.serverLevelData.getDayTime(); // Purpur - Configurable daylight cycle
|
||||
}
|
||||
|
||||
// Paper start
|
||||
@@ -760,7 +780,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
}
|
||||
|
||||
int i = this.getGameRules().get(GameRules.PLAYERS_SLEEPING_PERCENTAGE);
|
||||
- if (this.sleepStatus.areEnoughSleeping(i) && this.sleepStatus.areEnoughDeepSleeping(i, this.players)) {
|
||||
+ if (this.purpurConfig.playersSkipNight && this.sleepStatus.areEnoughSleeping(i) && this.sleepStatus.areEnoughDeepSleeping(i, this.players)) { // Purpur - Config for skipping night
|
||||
// Paper start - create time skip event - move up calculations
|
||||
final long newDayTime = this.levelData.getDayTime() + 24000L;
|
||||
org.bukkit.event.world.TimeSkipEvent event = new org.bukkit.event.world.TimeSkipEvent(
|
||||
@@ -895,6 +915,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
this.serverLevelData.getScheduledEvents().tick(this.server, l);
|
||||
Profiler.get().pop();
|
||||
if (this.getGameRules().get(GameRules.ADVANCE_TIME)) {
|
||||
+ // Purpur start - Configurable daylight cycle
|
||||
+ int incrementTicks = isBrightOutside() ? this.purpurConfig.daytimeTicks : this.purpurConfig.nighttimeTicks;
|
||||
+ if (incrementTicks != 12000) {
|
||||
+ this.preciseTime += 12000 / (double) incrementTicks;
|
||||
+ this.setDayTime(this.preciseTime);
|
||||
+ } else
|
||||
+ // Purpur end - Configurable daylight cycle
|
||||
this.setDayTime(this.levelData.getDayTime() + 1L);
|
||||
}
|
||||
}
|
||||
@@ -902,6 +929,20 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
|
||||
public void setDayTime(long time) {
|
||||
this.serverLevelData.setDayTime(time);
|
||||
+ // Purpur start - Configurable daylight cycle
|
||||
+ this.preciseTime = time;
|
||||
+ this.forceTime = false;
|
||||
+ }
|
||||
+ public void setDayTime(double i) {
|
||||
+ this.serverLevelData.setDayTime((long) i);
|
||||
+ this.forceTime = true;
|
||||
+ // Purpur end - Configurable daylight cycle
|
||||
+ }
|
||||
+
|
||||
+ // Purpur start - Configurable daylight cycle
|
||||
+ public boolean isForceTime() {
|
||||
+ return this.forceTime;
|
||||
+ // Purpur end - Configurable daylight cycle
|
||||
}
|
||||
|
||||
public long getDayCount() {
|
||||
@@ -1010,9 +1051,17 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
&& this.random.nextDouble() < currentDifficultyAt.getEffectiveDifficulty() * this.paperConfig().entities.spawning.skeletonHorseThunderSpawnChance.or(0.01) // Paper - Configurable spawn chances for skeleton horses
|
||||
&& !this.getBlockState(blockPos.below()).is(BlockTags.LIGHTNING_RODS);
|
||||
if (flag) {
|
||||
- SkeletonHorse skeletonHorse = EntityType.SKELETON_HORSE.create(this, EntitySpawnReason.EVENT);
|
||||
+ // Purpur start - Special mobs naturally spawn
|
||||
+ net.minecraft.world.entity.animal.equine.AbstractHorse skeletonHorse;
|
||||
+ if (purpurConfig.zombieHorseSpawnChance > 0D && random.nextDouble() <= purpurConfig.zombieHorseSpawnChance) {
|
||||
+ skeletonHorse = EntityType.ZOMBIE_HORSE.create(this, EntitySpawnReason.EVENT);
|
||||
+ } else {
|
||||
+ skeletonHorse = EntityType.SKELETON_HORSE.create(this, EntitySpawnReason.EVENT);
|
||||
+ if (skeletonHorse != null) ((SkeletonHorse) skeletonHorse).setTrap(true);
|
||||
+ }
|
||||
+ // Purpur end - Special mobs naturally spawn
|
||||
if (skeletonHorse != null) {
|
||||
- skeletonHorse.setTrap(true);
|
||||
+ //skeletonHorse.setTrap(true); // Purpur - Special mobs naturally spawn - moved up
|
||||
skeletonHorse.setAge(0);
|
||||
skeletonHorse.setPos(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
||||
this.addFreshEntity(skeletonHorse, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); // CraftBukkit
|
||||
@@ -1047,9 +1096,35 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
if (blockState.is(Blocks.SNOW)) {
|
||||
int layersValue = blockState.getValue(SnowLayerBlock.LAYERS);
|
||||
if (layersValue < Math.min(i, 8)) {
|
||||
+ // Purpur start - Smooth snow accumulation
|
||||
+ boolean canSnow = true;
|
||||
+ // Ensure snow doesn't get more than N layers taller than its neighbors
|
||||
+ // We only need to check blocks that are taller than the minimum step height
|
||||
+ if (org.purpurmc.purpur.PurpurConfig.smoothSnowAccumulationStep > 0 && layersValue >= org.purpurmc.purpur.PurpurConfig.smoothSnowAccumulationStep) {
|
||||
+ int layersValueMin = layersValue - org.purpurmc.purpur.PurpurConfig.smoothSnowAccumulationStep;
|
||||
+ for (Direction direction : Direction.Plane.HORIZONTAL) {
|
||||
+ BlockPos blockPosNeighbor = heightmapPos.relative(direction);
|
||||
+ BlockState blockStateNeighbor = this.getBlockState(blockPosNeighbor);
|
||||
+ if (blockStateNeighbor.is(Blocks.SNOW)) {
|
||||
+ // Special check for snow layers, if neighbors are too short, don't accumulate
|
||||
+ int layersValueNeighbor = blockStateNeighbor.getValue(SnowLayerBlock.LAYERS);
|
||||
+ if (layersValueNeighbor <= layersValueMin) {
|
||||
+ canSnow = false;
|
||||
+ break;
|
||||
+ }
|
||||
+ } else if (!Block.isFaceFull(blockStateNeighbor.getCollisionShape(this, blockPosNeighbor), direction.getOpposite())) {
|
||||
+ // Since our layer is tall enough already, if we have a non-full neighbor block, don't accumulate
|
||||
+ canSnow = false;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if (canSnow) {
|
||||
+ // Purpur end - Smooth snow accumulation
|
||||
BlockState blockState1 = blockState.setValue(SnowLayerBlock.LAYERS, layersValue + 1);
|
||||
Block.pushEntitiesUp(blockState, blockState1, this, heightmapPos);
|
||||
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, heightmapPos, blockState1, Block.UPDATE_ALL, null); // CraftBukkit
|
||||
+ } // Purpur - Smooth snow accumulation
|
||||
}
|
||||
} else {
|
||||
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, heightmapPos, Blocks.SNOW.defaultBlockState(), Block.UPDATE_ALL, null); // CraftBukkit
|
||||
@@ -1070,7 +1145,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
poiType -> poiType.is(PoiTypes.LIGHTNING_ROD),
|
||||
blockPos -> blockPos.getY() == this.getHeight(Heightmap.Types.WORLD_SURFACE, blockPos.getX(), blockPos.getZ()) - 1,
|
||||
pos,
|
||||
- 128,
|
||||
+ org.purpurmc.purpur.PurpurConfig.lightningRodRange, // Purpur - Make lightning rod range configurable
|
||||
PoiManager.Occupancy.ANY
|
||||
);
|
||||
return optional.map(blockPos -> blockPos.above(1));
|
||||
@@ -1119,8 +1194,26 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
int i = this.getGameRules().get(GameRules.PLAYERS_SLEEPING_PERCENTAGE);
|
||||
Component component;
|
||||
if (this.sleepStatus.areEnoughSleeping(i)) {
|
||||
+ // Purpur start - Customizable sleeping actionbar messages
|
||||
+ if (org.purpurmc.purpur.PurpurConfig.sleepSkippingNight.isBlank()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ if (!org.purpurmc.purpur.PurpurConfig.sleepSkippingNight.equalsIgnoreCase("default")) {
|
||||
+ component = io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.sleepSkippingNight));
|
||||
+ } else
|
||||
+ // Purpur end - Customizable sleeping actionbar messages
|
||||
component = Component.translatable("sleep.skipping_night");
|
||||
} else {
|
||||
+ // Purpur start - Customizable sleeping actionbar messages
|
||||
+ if (org.purpurmc.purpur.PurpurConfig.sleepingPlayersPercent.isBlank()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ if (!org.purpurmc.purpur.PurpurConfig.sleepingPlayersPercent.equalsIgnoreCase("default")) {
|
||||
+ component = io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.sleepingPlayersPercent,
|
||||
+ net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.parsed("count", Integer.toString(this.sleepStatus.amountSleeping())),
|
||||
+ net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.parsed("total", Integer.toString(this.sleepStatus.sleepersNeeded(i)))));
|
||||
+ } else
|
||||
+ // Purpur end - Customizable sleeping actionbar messages
|
||||
component = Component.translatable("sleep.players_sleeping", this.sleepStatus.amountSleeping(), this.sleepStatus.sleepersNeeded(i));
|
||||
}
|
||||
|
||||
@@ -1275,6 +1368,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@VisibleForTesting
|
||||
public void resetWeatherCycle() {
|
||||
// CraftBukkit start
|
||||
+ if (this.purpurConfig.rainStopsAfterSleep) // Purpur - Option for if rain and thunder should stop on sleep
|
||||
this.serverLevelData.setRaining(false, org.bukkit.event.weather.WeatherChangeEvent.Cause.SLEEP); // Paper - Add cause to Weather/ThunderChangeEvents
|
||||
// If we stop due to everyone sleeping we should reset the weather duration to some other random value.
|
||||
// Not that everyone ever manages to get the whole server to sleep at the same time....
|
||||
@@ -1282,6 +1376,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
this.serverLevelData.setRainTime(0);
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ if (this.purpurConfig.thunderStopsAfterSleep) // Purpur - Option for if rain and thunder should stop on sleep
|
||||
this.serverLevelData.setThundering(false, org.bukkit.event.weather.ThunderChangeEvent.Cause.SLEEP); // Paper - Add cause to Weather/ThunderChangeEvents
|
||||
// CraftBukkit start
|
||||
// If we stop due to everyone sleeping we should reset the weather duration to some other random value.
|
||||
@@ -1954,7 +2049,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
Explosion.BlockInteraction blockInteraction = switch (explosionInteraction) {
|
||||
case NONE -> Explosion.BlockInteraction.KEEP;
|
||||
case BLOCK -> this.getDestroyType(GameRules.BLOCK_EXPLOSION_DROP_DECAY);
|
||||
- case MOB -> this.getGameRules().get(GameRules.MOB_GRIEFING)
|
||||
+ case MOB -> ((source instanceof net.minecraft.world.entity.projectile.hurtingprojectile.LargeFireball) ? this.getGameRules().get(GameRules.MOB_GRIEFING, this.purpurConfig.fireballsMobGriefingOverride) : this.getGameRules().get(GameRules.MOB_GRIEFING)) // Purpur - Add mobGriefing override to everything affected
|
||||
? this.getDestroyType(GameRules.MOB_EXPLOSION_DROP_DECAY)
|
||||
: Explosion.BlockInteraction.KEEP;
|
||||
case TNT -> this.getDestroyType(GameRules.TNT_EXPLOSION_DROP_DECAY);
|
||||
@@ -2846,7 +2941,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
// 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
|
||||
- if (entity.getBukkitEntity() instanceof org.bukkit.inventory.Merchant merchant && merchant.getTrader() != null) {
|
||||
+ if (!entity.level().purpurConfig.playerVoidTrading && entity.getBukkitEntity() instanceof org.bukkit.inventory.Merchant merchant && merchant.getTrader() != null) { // Purpur - Allow void trading
|
||||
merchant.getTrader().closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED);
|
||||
}
|
||||
// Paper end - Fix merchant inventory not closing on entity removal
|
||||
@@ -1,18 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/ai/attributes/RangedAttribute.java b/net/minecraft/world/entity/ai/attributes/RangedAttribute.java
|
||||
index 0a0e5d9fd64182c1bed4c0aa6a40d8b2cdf8bc9d..353d571b4a2bf18414a08239abe2b079e3750d89 100644
|
||||
--- a/net/minecraft/world/entity/ai/attributes/RangedAttribute.java
|
||||
+++ b/net/minecraft/world/entity/ai/attributes/RangedAttribute.java
|
||||
@@ -29,6 +29,7 @@ public class RangedAttribute extends Attribute {
|
||||
|
||||
@Override
|
||||
public double sanitizeValue(double value) {
|
||||
+ if (!org.purpurmc.purpur.PurpurConfig.clampAttributes) return Double.isNaN(value) ? this.minValue : value; // Purpur - Add attribute clamping and armor limit config
|
||||
return Double.isNaN(value) ? this.minValue : Mth.clamp(value, this.minValue, this.maxValue);
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/ai/behavior/AcquirePoi.java b/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
|
||||
index 278addb7dbe4f57e99fb91ce1cd1bf3559e239a3..3e0fd09a0c0047cfe100e878186471090f8909a0 100644
|
||||
--- a/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
|
||||
+++ b/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
|
||||
@@ -85,7 +85,7 @@ public class AcquirePoi {
|
||||
};
|
||||
// Paper start - optimise POI access
|
||||
final java.util.List<Pair<Holder<PoiType>, BlockPos>> poiposes = new java.util.ArrayList<>();
|
||||
- io.papermc.paper.util.PoiAccess.findNearestPoiPositions(poiManager, acquirablePois, predicate1, mob.blockPosition(), 48, 48*48, PoiManager.Occupancy.HAS_SPACE, false, 5, poiposes);
|
||||
+ io.papermc.paper.util.PoiAccess.findNearestPoiPositions(poiManager, acquirablePois, predicate1, mob.blockPosition(), level.purpurConfig.villagerAcquirePoiSearchRadius, level.purpurConfig.villagerAcquirePoiSearchRadius*level.purpurConfig.villagerAcquirePoiSearchRadius, PoiManager.Occupancy.HAS_SPACE, false, 5, poiposes); // Purpur - Configurable villager search radius
|
||||
final Set<Pair<Holder<PoiType>, BlockPos>> set = new java.util.HashSet<>(poiposes.size());
|
||||
for (final Pair<Holder<PoiType>, BlockPos> poiPose : poiposes) {
|
||||
if (predicate.test(level, poiPose.getSecond())) {
|
||||
@@ -1,37 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java b/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java
|
||||
index df185d375658d765b07648dfb42ea56c84be671e..5c845d78e8baee41809e0678e3d99523368a2882 100644
|
||||
--- a/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java
|
||||
+++ b/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java
|
||||
@@ -55,7 +55,7 @@ public class InteractWithDoor {
|
||||
Node nextNode = path.getNextNode();
|
||||
BlockPos blockPos = previousNode.asBlockPos();
|
||||
BlockState blockState = level.getBlockState(blockPos);
|
||||
- if (blockState.is(BlockTags.MOB_INTERACTABLE_DOORS, state -> state.getBlock() instanceof DoorBlock)) {
|
||||
+ if (blockState.is(BlockTags.MOB_INTERACTABLE_DOORS, state -> state.getBlock() instanceof DoorBlock)&& !DoorBlock.requiresRedstone(entity.level(), blockState, blockPos)) { // Purpur - Option to make doors require redstone
|
||||
DoorBlock doorBlock = (DoorBlock)blockState.getBlock();
|
||||
if (!doorBlock.isOpen(blockState)) {
|
||||
// CraftBukkit start - entities opening doors
|
||||
@@ -72,7 +72,7 @@ public class InteractWithDoor {
|
||||
|
||||
BlockPos blockPos1 = nextNode.asBlockPos();
|
||||
BlockState blockState1 = level.getBlockState(blockPos1);
|
||||
- if (blockState1.is(BlockTags.MOB_INTERACTABLE_DOORS, state -> state.getBlock() instanceof DoorBlock)) {
|
||||
+ if (blockState1.is(BlockTags.MOB_INTERACTABLE_DOORS, state -> state.getBlock() instanceof DoorBlock) && !DoorBlock.requiresRedstone(entity.level(), blockState1, blockPos1)) { // Purpur - Option to make doors require redstone
|
||||
DoorBlock doorBlock1 = (DoorBlock)blockState1.getBlock();
|
||||
if (!doorBlock1.isOpen(blockState1)) {
|
||||
// CraftBukkit start - entities opening doors
|
||||
@@ -118,7 +118,7 @@ public class InteractWithDoor {
|
||||
iterator.remove();
|
||||
} else {
|
||||
BlockState blockState = level.getBlockState(blockPos);
|
||||
- if (!blockState.is(BlockTags.MOB_INTERACTABLE_DOORS, state -> state.getBlock() instanceof DoorBlock)) {
|
||||
+ if (!blockState.is(BlockTags.MOB_INTERACTABLE_DOORS, state -> state.getBlock() instanceof DoorBlock) || DoorBlock.requiresRedstone(entity.level(), blockState, blockPos)) { // Purpur - Option to make doors require redstone
|
||||
iterator.remove();
|
||||
} else {
|
||||
DoorBlock doorBlock = (DoorBlock)blockState.getBlock();
|
||||
@@ -1,18 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/ai/behavior/ShowTradesToPlayer.java b/net/minecraft/world/entity/ai/behavior/ShowTradesToPlayer.java
|
||||
index 338f9850a9ee968ade1a5554936a10b8a3786fe5..8cac46b6fd025f7f10b17903579f021482ed4b18 100644
|
||||
--- a/net/minecraft/world/entity/ai/behavior/ShowTradesToPlayer.java
|
||||
+++ b/net/minecraft/world/entity/ai/behavior/ShowTradesToPlayer.java
|
||||
@@ -45,6 +45,7 @@ public class ShowTradesToPlayer extends Behavior<Villager> {
|
||||
|
||||
@Override
|
||||
public boolean canStillUse(ServerLevel level, Villager entity, long gameTime) {
|
||||
+ if (!entity.level().purpurConfig.villagerDisplayTradeItem) return false; // Purpur - Option for villager display trade item
|
||||
return this.checkExtraStartConditions(level, entity)
|
||||
&& this.lookTime > 0
|
||||
&& entity.getBrain().getMemory(MemoryModuleType.INTERACTION_TARGET).isPresent();
|
||||
@@ -1,62 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/ai/behavior/TransportItemsBetweenContainers.java b/net/minecraft/world/entity/ai/behavior/TransportItemsBetweenContainers.java
|
||||
index 3741e32fa1aa85e3b5b45c3b05fcb3a0a807a6e7..2a7cda7fbc400a13e7ab71a6a82496068d9c7ae6 100644
|
||||
--- a/net/minecraft/world/entity/ai/behavior/TransportItemsBetweenContainers.java
|
||||
+++ b/net/minecraft/world/entity/ai/behavior/TransportItemsBetweenContainers.java
|
||||
@@ -285,7 +285,7 @@ public class TransportItemsBetweenContainers extends Behavior<PathfinderMob> {
|
||||
LevelChunk chunkNow = level.getChunkSource().getChunkNow(chunkPos.x, chunkPos.z);
|
||||
if (chunkNow != null) {
|
||||
for (BlockEntity blockEntity : chunkNow.getBlockEntities().values()) {
|
||||
- if (blockEntity instanceof ChestBlockEntity chestBlockEntity) {
|
||||
+ if (blockEntity instanceof net.minecraft.world.level.block.entity.BaseContainerBlockEntity chestBlockEntity) { // Purpur - copper golem can place items in barrels or shulkers option
|
||||
double d1 = chestBlockEntity.getBlockPos().distToCenterSqr(mob.position());
|
||||
if (d1 < d) {
|
||||
TransportItemsBetweenContainers.TransportItemTarget transportItemTarget1 = this.isTargetValidToPick(
|
||||
@@ -369,7 +369,11 @@ public class TransportItemsBetweenContainers extends Behavior<PathfinderMob> {
|
||||
}
|
||||
|
||||
private boolean isTargetBlocked(Level level, TransportItemsBetweenContainers.TransportItemTarget target) {
|
||||
- return ChestBlock.isChestBlockedAt(level, target.pos);
|
||||
+ // Purpur start - copper golem can place items in barrels or shulkers option
|
||||
+ boolean isBarrelBlocked = !level.purpurConfig.copperGolemCanOpenBarrel && target.state.is(net.minecraft.world.level.block.Blocks.BARREL);
|
||||
+ boolean isShulkerBlocked = !level.purpurConfig.copperGolemCanOpenShulker && target.blockEntity instanceof net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity shulkerBoxBlockEntity && !net.minecraft.world.level.block.ShulkerBoxBlock.canOpen(target.state, level, target.pos, shulkerBoxBlockEntity);
|
||||
+ return target.state.is(net.minecraft.world.level.block.Blocks.BARREL) ? isBarrelBlocked : isShulkerBlocked || net.minecraft.world.level.block.ChestBlock.isChestBlockedAt(level, target.pos);
|
||||
+ // Purpur end - copper golem can place items in barrels or shulkers option
|
||||
}
|
||||
|
||||
private boolean targetHasNotChanged(Level level, TransportItemsBetweenContainers.TransportItemTarget target) {
|
||||
@@ -446,7 +450,7 @@ public class TransportItemsBetweenContainers extends Behavior<PathfinderMob> {
|
||||
}
|
||||
|
||||
private boolean isWantedBlock(PathfinderMob mob, BlockState state) {
|
||||
- return isPickingUpItems(mob) ? this.sourceBlockType.test(state) : this.destinationBlockType.test(state);
|
||||
+ return isPickingUpItems(mob) ? this.sourceBlockType.test(state) : (mob.level().purpurConfig.copperGolemCanOpenBarrel && state.is(net.minecraft.world.level.block.Blocks.BARREL)) || (mob.level().purpurConfig.copperGolemCanOpenShulker && state.is(net.minecraft.tags.BlockTags.SHULKER_BOXES)) || this.destinationBlockType.test(state); // Purpur - copper golem can place items in barrels or shulkers option
|
||||
}
|
||||
|
||||
private static double getInteractionRange(PathfinderMob mob) {
|
||||
@@ -488,6 +492,11 @@ public class TransportItemsBetweenContainers extends Behavior<PathfinderMob> {
|
||||
}
|
||||
|
||||
private static boolean matchesLeavingItemsRequirement(PathfinderMob mob, Container container) {
|
||||
+ // Purpur start - copper golem can place items in barrels or shulkers option
|
||||
+ if (mob.level().purpurConfig.copperGolemCanOpenShulker && container instanceof net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity && mob.getMainHandItem().is(net.minecraft.tags.ItemTags.SHULKER_BOXES)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Purpur end - copper golem can place items in barrels or shulkers option
|
||||
return container.isEmpty() || hasItemMatchingHandItem(mob, container);
|
||||
}
|
||||
|
||||
@@ -525,7 +534,7 @@ public class TransportItemsBetweenContainers extends Behavior<PathfinderMob> {
|
||||
int i = 0;
|
||||
|
||||
for (ItemStack itemStack : container) {
|
||||
- if (!itemStack.isEmpty()) {
|
||||
+ if (!itemStack.isEmpty() && (!(container instanceof net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity) || !itemStack.is(net.minecraft.tags.ItemTags.SHULKER_BOXES))) { // Purpur - copper golem can place items in barrels or shulkers option
|
||||
int min = Math.min(itemStack.getCount(), 16);
|
||||
return container.removeItem(i, min);
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/ai/goal/SwellGoal.java b/net/minecraft/world/entity/ai/goal/SwellGoal.java
|
||||
index 2bc0c7f5973d5d5695ec291f404a836a78e8348e..ccbd344a49a568e97606c364082ab3f74ad5e6ed 100644
|
||||
--- a/net/minecraft/world/entity/ai/goal/SwellGoal.java
|
||||
+++ b/net/minecraft/world/entity/ai/goal/SwellGoal.java
|
||||
@@ -47,6 +47,14 @@ public class SwellGoal extends Goal {
|
||||
this.creeper.setSwellDir(-1);
|
||||
} else {
|
||||
this.creeper.setSwellDir(1);
|
||||
+ // Purpur start - option to allow creeper to encircle target when fusing
|
||||
+ if (this.creeper.level().purpurConfig.creeperEncircleTarget) {
|
||||
+ net.minecraft.world.phys.Vec3 relative = this.creeper.position().subtract(this.target.position());
|
||||
+ relative = relative.yRot((float) Math.PI / 3).normalize().multiply(2, 2, 2);
|
||||
+ net.minecraft.world.phys.Vec3 destination = this.target.position().add(relative);
|
||||
+ this.creeper.getNavigation().moveTo(destination.x, destination.y, destination.z, 1);
|
||||
+ }
|
||||
+ // Purpur end - option to allow creeper to encircle target when fusing
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java b/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java
|
||||
index 066faa704338c573472381e1ebd063e0d52aaaa4..1f96fd5085bacb4c584576c7cb9f51e7898e9b03 100644
|
||||
--- a/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java
|
||||
+++ b/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java
|
||||
@@ -56,7 +56,7 @@ public class NearestBedSensor extends Sensor<Mob> {
|
||||
// Paper start - optimise POI access
|
||||
java.util.List<Pair<Holder<PoiType>, BlockPos>> poiposes = new java.util.ArrayList<>();
|
||||
// don't ask me why it's unbounded. ask mojang.
|
||||
- io.papermc.paper.util.PoiAccess.findAnyPoiPositions(poiManager, type -> type.is(PoiTypes.HOME), predicate, entity.blockPosition(), 48, PoiManager.Occupancy.ANY, false, Integer.MAX_VALUE, poiposes);
|
||||
+ io.papermc.paper.util.PoiAccess.findAnyPoiPositions(poiManager, type -> type.is(PoiTypes.HOME), predicate, entity.blockPosition(), level.purpurConfig.villagerNearestBedSensorSearchRadius, PoiManager.Occupancy.ANY, false, Integer.MAX_VALUE, poiposes); // Purpur - Configurable villager search radius
|
||||
Path path = AcquirePoi.findPathToPois(entity, new java.util.HashSet<>(poiposes));
|
||||
// Paper end - optimise POI access
|
||||
if (path != null && path.canReach()) {
|
||||
@@ -1,42 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/animal/Animal.java b/net/minecraft/world/entity/animal/Animal.java
|
||||
index 023b68549e3b185d8ad2f505f34bb59556bbf961..2e7e7c1913f5cbc20ce116c5ae3e185fc83094c0 100644
|
||||
--- a/net/minecraft/world/entity/animal/Animal.java
|
||||
+++ b/net/minecraft/world/entity/animal/Animal.java
|
||||
@@ -146,7 +146,7 @@ public abstract class Animal extends AgeableMob {
|
||||
ItemStack itemInHand = player.getItemInHand(hand);
|
||||
if (this.isFood(itemInHand)) {
|
||||
int age = this.getAge();
|
||||
- if (player instanceof ServerPlayer serverPlayer && age == 0 && this.canFallInLove()) {
|
||||
+ if (player instanceof ServerPlayer serverPlayer && age == 0 && this.canFallInLove() && (this.level().purpurConfig.animalBreedingCooldownSeconds <= 0 || !this.level().hasBreedingCooldown(player.getUUID(), this.getClass()))) { // Purpur - Add adjustable breeding cooldown to config
|
||||
final ItemStack breedCopy = itemInHand.copy(); // Paper - Fix EntityBreedEvent copying
|
||||
this.usePlayerItem(player, hand, itemInHand);
|
||||
this.setInLove(serverPlayer, breedCopy); // Paper - Fix EntityBreedEvent copying
|
||||
@@ -227,10 +227,20 @@ public abstract class Animal extends AgeableMob {
|
||||
public void spawnChildFromBreeding(ServerLevel level, Animal partner) {
|
||||
AgeableMob breedOffspring = this.getBreedOffspring(level, partner);
|
||||
if (breedOffspring != null) {
|
||||
- breedOffspring.setBaby(true);
|
||||
- breedOffspring.snapTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F);
|
||||
+ //breedOffspring.setBaby(true); // Purpur - Add adjustable breeding cooldown to config - moved down
|
||||
+ //breedOffspring.snapTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F); // Purpur - Add adjustable breeding cooldown to config - moved down
|
||||
// CraftBukkit start - Call EntityBreedEvent
|
||||
ServerPlayer breeder = Optional.ofNullable(this.getLoveCause()).or(() -> Optional.ofNullable(partner.getLoveCause())).orElse(null);
|
||||
+ // Purpur start - Add adjustable breeding cooldown to config
|
||||
+ if (breeder != null && level.purpurConfig.animalBreedingCooldownSeconds > 0) {
|
||||
+ if (level.hasBreedingCooldown(breeder.getUUID(), this.getClass())) {
|
||||
+ return;
|
||||
+ }
|
||||
+ level.addBreedingCooldown(breeder.getUUID(), this.getClass());
|
||||
+ }
|
||||
+ breedOffspring.setBaby(true);
|
||||
+ breedOffspring.snapTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F);
|
||||
+ // Purpur end - Add adjustable breeding cooldown to config
|
||||
int experience = this.getRandom().nextInt(7) + 1;
|
||||
org.bukkit.event.entity.EntityBreedEvent entityBreedEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreedEvent(breedOffspring, this, partner, breeder, this.breedItem, experience);
|
||||
if (entityBreedEvent.isCancelled()) {
|
||||
@@ -1,81 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/animal/bee/Bee.java b/net/minecraft/world/entity/animal/bee/Bee.java
|
||||
index 0cbcf23b6edba2305dfbbc95abb06a90a6edd42b..7b9280526af353c3ab1f32e5195499e773731352 100644
|
||||
--- a/net/minecraft/world/entity/animal/bee/Bee.java
|
||||
+++ b/net/minecraft/world/entity/animal/bee/Bee.java
|
||||
@@ -171,7 +171,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
||||
// Paper end - Fix MC-167279
|
||||
this.lookControl = new Bee.BeeLookControl(this);
|
||||
this.setPathfindingMalus(PathType.DANGER_FIRE, -1.0F);
|
||||
- this.setPathfindingMalus(PathType.WATER, -1.0F);
|
||||
+ if (this.level().purpurConfig.beeCanInstantlyStartDrowning) this.setPathfindingMalus(PathType.WATER, -1.0F); // Purpur - bee can instantly start drowning in water option
|
||||
this.setPathfindingMalus(PathType.WATER_BORDER, 16.0F);
|
||||
this.setPathfindingMalus(PathType.COCOA, -1.0F);
|
||||
this.setPathfindingMalus(PathType.FENCE, -1.0F);
|
||||
@@ -360,13 +360,19 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
||||
if (this.stayOutOfHiveCountdown <= 0 && !this.beePollinateGoal.isPollinating() && !this.hasStung() && this.getTarget() == null) {
|
||||
boolean flag = this.hasNectar()
|
||||
|| this.isTiredOfLookingForNectar()
|
||||
- || this.level().environmentAttributes().getValue(EnvironmentAttributes.BEES_STAY_IN_HIVE, this.position());
|
||||
+ || this.level().environmentAttributes().getValue(EnvironmentAttributes.BEES_STAY_IN_HIVE, this.position()) || isNightOrRaining(this.level()); // Purpur - Bee can work when raining or at night
|
||||
return flag && !this.isHiveNearFire();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+ // Purpur start - Bee can work when raining or at night
|
||||
+ public static boolean isNightOrRaining(Level level) {
|
||||
+ return level.dimensionType().hasSkyLight() && (level.isDarkOutside() && !level.purpurConfig.beeCanWorkAtNight || level.isRaining() && !level.purpurConfig.beeCanWorkInRain); // Purpur - Bee can work when raining or at night
|
||||
+ }
|
||||
+ // Purpur end - Bee can work when raining or at night
|
||||
+
|
||||
public void setStayOutOfHiveCountdown(int stayOutOfHiveCountdown) {
|
||||
this.stayOutOfHiveCountdown = stayOutOfHiveCountdown;
|
||||
}
|
||||
@@ -387,7 +393,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
||||
@Override
|
||||
protected void customServerAiStep(ServerLevel level) {
|
||||
boolean hasStung = this.hasStung();
|
||||
- if (this.isInWater()) {
|
||||
+ if (this.level().purpurConfig.beeCanInstantlyStartDrowning && this.isInWater()) { // Purpur - bee can instantly start drowning in water option
|
||||
this.underWaterTicks++;
|
||||
} else {
|
||||
this.underWaterTicks = 0;
|
||||
@@ -397,6 +403,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
||||
this.hurtServer(level, this.damageSources().drown(), 1.0F);
|
||||
}
|
||||
|
||||
+ if (hasStung && !this.level().purpurConfig.beeDiesAfterSting) setHasStung(false); else // Purpur - Stop bees from dying after stinging
|
||||
if (hasStung) {
|
||||
this.timeSinceSting++;
|
||||
if (this.timeSinceSting % 5 == 0 && this.random.nextInt(Mth.clamp(1200 - this.timeSinceSting, 1, 1200)) == 0) {
|
||||
@@ -1130,6 +1137,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
||||
Bee.this.savedFlowerPos = optional.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);
|
||||
+ new org.purpurmc.purpur.event.entity.BeeFoundFlowerEvent((org.bukkit.entity.Bee) Bee.this.getBukkitEntity(), org.bukkit.craftbukkit.util.CraftLocation.toBukkit(Bee.this.savedFlowerPos, Bee.this.level())).callEvent(); // Purpur - Bee API
|
||||
return true;
|
||||
} else {
|
||||
Bee.this.remainingCooldownBeforeLocatingNewFlower = Mth.nextInt(Bee.this.random, 20, 60);
|
||||
@@ -1176,6 +1184,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
||||
this.pollinating = false;
|
||||
Bee.this.navigation.stop();
|
||||
Bee.this.remainingCooldownBeforeLocatingNewFlower = 200;
|
||||
+ new org.purpurmc.purpur.event.entity.BeeStopPollinatingEvent((org.bukkit.entity.Bee) Bee.this.getBukkitEntity(), Bee.this.savedFlowerPos == null ? null : org.bukkit.craftbukkit.util.CraftLocation.toBukkit(Bee.this.savedFlowerPos, Bee.this.level()), Bee.this.hasNectar()).callEvent(); // Purpur - Bee API
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1222,6 +1231,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
||||
this.setWantedPos();
|
||||
}
|
||||
|
||||
+ if (this.successfulPollinatingTicks == 0) new org.purpurmc.purpur.event.entity.BeeStartedPollinatingEvent((org.bukkit.entity.Bee) Bee.this.getBukkitEntity(), org.bukkit.craftbukkit.util.CraftLocation.toBukkit(Bee.this.savedFlowerPos, Bee.this.level())).callEvent(); // Purpur - Bee API
|
||||
this.successfulPollinatingTicks++;
|
||||
if (Bee.this.random.nextFloat() < 0.05F && this.successfulPollinatingTicks > this.lastSoundPlayedTick + 60) {
|
||||
this.lastSoundPlayedTick = this.successfulPollinatingTicks;
|
||||
@@ -1,98 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/animal/cow/AbstractCow.java b/net/minecraft/world/entity/animal/cow/AbstractCow.java
|
||||
index e10f7d1b264a85798de063b4387bab62621bf54b..f6f251227db315b58bee45f8011624a347eb8fea 100644
|
||||
--- a/net/minecraft/world/entity/animal/cow/AbstractCow.java
|
||||
+++ b/net/minecraft/world/entity/animal/cow/AbstractCow.java
|
||||
@@ -40,7 +40,7 @@ public abstract class AbstractCow extends Animal {
|
||||
this.goalSelector.addGoal(0, new FloatGoal(this));
|
||||
this.goalSelector.addGoal(1, new PanicGoal(this, 2.0));
|
||||
this.goalSelector.addGoal(2, new BreedGoal(this, 1.0));
|
||||
- this.goalSelector.addGoal(3, new TemptGoal(this, 1.25, itemStack -> itemStack.is(ItemTags.COW_FOOD), false));
|
||||
+ this.goalSelector.addGoal(3, new TemptGoal(this, 1.25, itemStack -> level().purpurConfig.cowFeedMushrooms > 0 && (itemStack.is(net.minecraft.world.level.block.Blocks.RED_MUSHROOM.asItem()) || itemStack.is(net.minecraft.world.level.block.Blocks.BROWN_MUSHROOM.asItem())) || itemStack.is(ItemTags.COW_FOOD), false)); // Purpur - Cows eat mushrooms
|
||||
this.goalSelector.addGoal(4, new FollowParentGoal(this, 1.25));
|
||||
this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 1.0));
|
||||
this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 6.0F));
|
||||
@@ -96,6 +96,10 @@ public abstract class AbstractCow extends Animal {
|
||||
ItemStack itemStack = ItemUtils.createFilledResult(itemInHand, player, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItemStack())); // CraftBukkit
|
||||
player.setItemInHand(hand, itemStack);
|
||||
return InteractionResult.SUCCESS;
|
||||
+ // Purpur start - Cows eat mushrooms - feed mushroom to change to mooshroom
|
||||
+ } else if (level().purpurConfig.cowFeedMushrooms > 0 && this.getType() != EntityType.MOOSHROOM && isMushroom(itemInHand)) {
|
||||
+ return this.feedMushroom(player, itemInHand);
|
||||
+ // Purpur end - Cows eat mushrooms
|
||||
} else {
|
||||
return super.mobInteract(player, hand);
|
||||
}
|
||||
@@ -105,4 +109,67 @@ public abstract class AbstractCow extends Animal {
|
||||
public EntityDimensions getDefaultDimensions(Pose pose) {
|
||||
return this.isBaby() ? BABY_DIMENSIONS : super.getDefaultDimensions(pose);
|
||||
}
|
||||
+
|
||||
+ // Purpur start - Cows eat mushrooms - feed mushroom to change to mooshroom
|
||||
+ private int redMushroomsFed = 0;
|
||||
+ private int brownMushroomsFed = 0;
|
||||
+
|
||||
+ private boolean isMushroom(ItemStack stack) {
|
||||
+ return stack.getItem() == net.minecraft.world.level.block.Blocks.RED_MUSHROOM.asItem() || stack.getItem() == net.minecraft.world.level.block.Blocks.BROWN_MUSHROOM.asItem();
|
||||
+ }
|
||||
+
|
||||
+ private int incrementFeedCount(ItemStack stack) {
|
||||
+ if (stack.getItem() == net.minecraft.world.level.block.Blocks.RED_MUSHROOM.asItem()) {
|
||||
+ return ++redMushroomsFed;
|
||||
+ } else {
|
||||
+ return ++brownMushroomsFed;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private InteractionResult feedMushroom(Player player, ItemStack stack) {
|
||||
+ level().broadcastEntityEvent(this, (byte) 18); // hearts
|
||||
+ playSound(SoundEvents.COW_MILK, 1.0F, 1.0F);
|
||||
+ if (incrementFeedCount(stack) < level().purpurConfig.cowFeedMushrooms) {
|
||||
+ if (!player.getAbilities().instabuild) {
|
||||
+ stack.shrink(1);
|
||||
+ }
|
||||
+ return InteractionResult.CONSUME; // require 5 mushrooms to transform (prevents mushroom duping)
|
||||
+ }
|
||||
+ MushroomCow mooshroom = EntityType.MOOSHROOM.create(level(), net.minecraft.world.entity.EntitySpawnReason.CONVERSION);
|
||||
+ if (mooshroom == null) {
|
||||
+ return InteractionResult.PASS;
|
||||
+ }
|
||||
+ if (stack.getItem() == net.minecraft.world.level.block.Blocks.BROWN_MUSHROOM.asItem()) {
|
||||
+ mooshroom.setVariant(MushroomCow.Variant.BROWN);
|
||||
+ } else {
|
||||
+ mooshroom.setVariant(MushroomCow.Variant.RED);
|
||||
+ }
|
||||
+ mooshroom.snapTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot());
|
||||
+ mooshroom.setHealth(this.getHealth());
|
||||
+ mooshroom.setAge(getAge());
|
||||
+ mooshroom.copyPosition(this);
|
||||
+ mooshroom.setYBodyRot(this.yBodyRot);
|
||||
+ mooshroom.setYHeadRot(this.getYHeadRot());
|
||||
+ mooshroom.yRotO = this.yRotO;
|
||||
+ mooshroom.xRotO = this.xRotO;
|
||||
+ if (this.hasCustomName()) {
|
||||
+ mooshroom.setCustomName(this.getCustomName());
|
||||
+ }
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTransformEvent(this, mooshroom, org.bukkit.event.entity.EntityTransformEvent.TransformReason.INFECTION).isCancelled()) {
|
||||
+ return InteractionResult.PASS;
|
||||
+ }
|
||||
+ this.level().addFreshEntity(mooshroom);
|
||||
+ this.remove(RemovalReason.DISCARDED, org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD);
|
||||
+ if (!player.getAbilities().instabuild) {
|
||||
+ stack.shrink(1);
|
||||
+ }
|
||||
+ for (int i = 0; i < 15; ++i) {
|
||||
+ ((net.minecraft.server.level.ServerLevel) level()).sendParticlesSource(((net.minecraft.server.level.ServerLevel) level()).players(), null, net.minecraft.core.particles.ParticleTypes.HAPPY_VILLAGER,
|
||||
+ false, true,
|
||||
+ getX() + random.nextFloat(), getY() + (random.nextFloat() * 2), getZ() + random.nextFloat(), 1,
|
||||
+ random.nextGaussian() * 0.05D, random.nextGaussian() * 0.05D, random.nextGaussian() * 0.05D, 0);
|
||||
+ }
|
||||
+ return InteractionResult.SUCCESS;
|
||||
+ }
|
||||
+ // Purpur end - Cows eat mushrooms
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/animal/dolphin/Dolphin.java b/net/minecraft/world/entity/animal/dolphin/Dolphin.java
|
||||
index 3a3c9694d3a704aaaa241bd8601c7fd2439436cc..50b8abff1e20855ba8c8acb225c251a1223b8b58 100644
|
||||
--- a/net/minecraft/world/entity/animal/dolphin/Dolphin.java
|
||||
+++ b/net/minecraft/world/entity/animal/dolphin/Dolphin.java
|
||||
@@ -75,6 +75,7 @@ public class Dolphin extends AgeableWaterCreature {
|
||||
public static final float BABY_SCALE = 0.65F;
|
||||
private static final boolean DEFAULT_GOT_FISH = false;
|
||||
@Nullable public BlockPos treasurePos;
|
||||
+ private boolean isNaturallyAggressiveToPlayers; // Purpur - Dolphins naturally aggressive to players chance
|
||||
|
||||
public Dolphin(EntityType<? extends Dolphin> type, Level level) {
|
||||
super(type, level);
|
||||
@@ -90,6 +91,7 @@ public class Dolphin extends AgeableWaterCreature {
|
||||
this.setAirSupply(this.getMaxAirSupply());
|
||||
this.setXRot(0.0F);
|
||||
SpawnGroupData spawnGroupData1 = Objects.requireNonNullElseGet(spawnGroupData, () -> new AgeableMob.AgeableMobGroupData(0.1F));
|
||||
+ this.isNaturallyAggressiveToPlayers = level.getLevel().purpurConfig.dolphinNaturallyAggressiveToPlayersChance > 0.0D && random.nextDouble() <= level.getLevel().purpurConfig.dolphinNaturallyAggressiveToPlayersChance; // Purpur - Dolphins naturally aggressive to players chance
|
||||
return super.finalizeSpawn(level, difficulty, spawnReason, spawnGroupData1);
|
||||
}
|
||||
|
||||
@@ -155,17 +157,19 @@ public class Dolphin extends AgeableWaterCreature {
|
||||
protected void registerGoals() {
|
||||
this.goalSelector.addGoal(0, new BreathAirGoal(this));
|
||||
this.goalSelector.addGoal(0, new TryFindWaterGoal(this));
|
||||
+ this.goalSelector.addGoal(1, new MeleeAttackGoal(this, 1.2000000476837158D, true)); // Purpur - Dolphins naturally aggressive to players chance
|
||||
this.goalSelector.addGoal(1, new Dolphin.DolphinSwimToTreasureGoal(this));
|
||||
this.goalSelector.addGoal(2, new Dolphin.DolphinSwimWithPlayerGoal(this, 4.0));
|
||||
this.goalSelector.addGoal(4, new RandomSwimmingGoal(this, 1.0, 10));
|
||||
this.goalSelector.addGoal(4, new RandomLookAroundGoal(this));
|
||||
this.goalSelector.addGoal(5, new LookAtPlayerGoal(this, Player.class, 6.0F));
|
||||
this.goalSelector.addGoal(5, new DolphinJumpGoal(this, 10));
|
||||
- this.goalSelector.addGoal(6, new MeleeAttackGoal(this, 1.2F, true));
|
||||
+ //this.goalSelector.addGoal(6, new MeleeAttackGoal(this, 1.2F, true)); // Purpur - moved up - Dolphins naturally aggressive to players chance
|
||||
this.goalSelector.addGoal(8, new Dolphin.PlayWithItemsGoal());
|
||||
this.goalSelector.addGoal(8, new FollowBoatGoal(this));
|
||||
this.goalSelector.addGoal(9, new AvoidEntityGoal<>(this, Guardian.class, 8.0F, 1.0, 1.0));
|
||||
this.targetSelector.addGoal(1, new HurtByTargetGoal(this, Guardian.class).setAlertOthers());
|
||||
+ this.targetSelector.addGoal(2, new net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (ignored, ignored2) -> isNaturallyAggressiveToPlayers)); // Purpur - Dolphins naturally aggressive to players chance
|
||||
}
|
||||
|
||||
public static AttributeSupplier.Builder createAttributes() {
|
||||
@@ -392,6 +396,7 @@ public class Dolphin extends AgeableWaterCreature {
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
+ if (this.dolphin.level().purpurConfig.dolphinDisableTreasureSearching) return false; // Purpur - Add option to disable dolphin treasure searching
|
||||
return this.dolphin.gotFish() && this.dolphin.getAirSupply() >= 100;
|
||||
}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/animal/equine/Llama.java b/net/minecraft/world/entity/animal/equine/Llama.java
|
||||
index 1522efc1e6937bc8a24a2df77d5421ae04a6642b..cceb66525a4d017b2db21bd301e63670c639223f 100644
|
||||
--- a/net/minecraft/world/entity/animal/equine/Llama.java
|
||||
+++ b/net/minecraft/world/entity/animal/equine/Llama.java
|
||||
@@ -76,6 +76,7 @@ public class Llama extends AbstractChestedHorse implements RangedAttackMob {
|
||||
boolean didSpit;
|
||||
private @Nullable Llama caravanHead;
|
||||
public @Nullable Llama caravanTail; // Paper - public
|
||||
+ public boolean shouldJoinCaravan = true; // Purpur - Llama API
|
||||
|
||||
public Llama(EntityType<? extends Llama> type, Level level) {
|
||||
super(type, level);
|
||||
@@ -105,6 +106,7 @@ public class Llama extends AbstractChestedHorse implements RangedAttackMob {
|
||||
super.addAdditionalSaveData(output);
|
||||
output.store("Variant", Llama.Variant.LEGACY_CODEC, this.getVariant());
|
||||
output.putInt("Strength", this.getStrength());
|
||||
+ output.putBoolean("Purpur.ShouldJoinCaravan", shouldJoinCaravan); // Purpur - Llama API
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -112,6 +114,7 @@ public class Llama extends AbstractChestedHorse implements RangedAttackMob {
|
||||
this.setStrength(input.getIntOr("Strength", 0));
|
||||
super.readAdditionalSaveData(input);
|
||||
this.setVariant(input.read("Variant", Llama.Variant.LEGACY_CODEC).orElse(Llama.Variant.DEFAULT));
|
||||
+ this.shouldJoinCaravan = input.getBooleanOr("Purpur.ShouldJoinCaravan", true); // Purpur - Llama API
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -388,6 +391,7 @@ public class Llama extends AbstractChestedHorse implements RangedAttackMob {
|
||||
|
||||
public void leaveCaravan() {
|
||||
if (this.caravanHead != null) {
|
||||
+ new org.purpurmc.purpur.event.entity.LlamaLeaveCaravanEvent((org.bukkit.entity.Llama) getBukkitEntity()).callEvent(); // Purpur - Llama API
|
||||
this.caravanHead.caravanTail = null;
|
||||
}
|
||||
|
||||
@@ -395,6 +399,7 @@ public class Llama extends AbstractChestedHorse implements RangedAttackMob {
|
||||
}
|
||||
|
||||
public void joinCaravan(Llama caravanHead) {
|
||||
+ if (!this.level().purpurConfig.llamaJoinCaravans || !shouldJoinCaravan || !new org.purpurmc.purpur.event.entity.LlamaJoinCaravanEvent((org.bukkit.entity.Llama) getBukkitEntity(), (org.bukkit.entity.Llama) caravanHead.getBukkitEntity()).callEvent()) return; // Purpur - Llama API // Purpur - Config to disable Llama caravans
|
||||
this.caravanHead = caravanHead;
|
||||
this.caravanHead.caravanTail = this;
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/animal/feline/Cat.java b/net/minecraft/world/entity/animal/feline/Cat.java
|
||||
index f17d7a4ef7061d6ede9a755b5a77324a28c3eeaa..6acd39413ab4fed1eaf251d3b6d9b9e184060e5c 100644
|
||||
--- a/net/minecraft/world/entity/animal/feline/Cat.java
|
||||
+++ b/net/minecraft/world/entity/animal/feline/Cat.java
|
||||
@@ -354,6 +354,14 @@ public class Cat extends TamableAnimal {
|
||||
return this.isTame() && otherAnimal instanceof Cat cat && cat.isTame() && super.canMate(otherAnimal);
|
||||
}
|
||||
|
||||
+ // Purpur start - Configurable default collar color
|
||||
+ @Override
|
||||
+ public void tame(Player player) {
|
||||
+ setCollarColor(level().purpurConfig.catDefaultCollarColor);
|
||||
+ super.tame(player);
|
||||
+ }
|
||||
+ // Purpur end - Configurable default collar color
|
||||
+
|
||||
@Override
|
||||
public @Nullable SpawnGroupData finalizeSpawn(
|
||||
ServerLevelAccessor level, DifficultyInstance difficulty, EntitySpawnReason spawnReason, @Nullable SpawnGroupData spawnGroupData
|
||||
@@ -451,7 +459,7 @@ public class Cat extends TamableAnimal {
|
||||
}
|
||||
|
||||
private void tryToTame(Player player) {
|
||||
- if (this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit
|
||||
+ if (((this.level().purpurConfig.alwaysTameInCreative && player.hasInfiniteMaterials()) || this.random.nextInt(3) == 0) && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit // Purpur - Config to always tame in Creative
|
||||
this.tame(player);
|
||||
this.setOrderedToSit(true);
|
||||
this.level().broadcastEntityEvent(this, EntityEvent.TAMING_SUCCEEDED);
|
||||
@@ -1,19 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/animal/feline/Ocelot.java b/net/minecraft/world/entity/animal/feline/Ocelot.java
|
||||
index cf940de8767df6d07551d7a221a0e87df4e41785..94fdbae92dabf7505a7c7b518d4c07b4f68c8e9c 100644
|
||||
--- a/net/minecraft/world/entity/animal/feline/Ocelot.java
|
||||
+++ b/net/minecraft/world/entity/animal/feline/Ocelot.java
|
||||
@@ -234,7 +234,7 @@ public class Ocelot extends Animal {
|
||||
public boolean checkSpawnObstruction(LevelReader level) {
|
||||
if (level.isUnobstructed(this) && !level.containsAnyLiquid(this.getBoundingBox())) {
|
||||
BlockPos blockPos = this.blockPosition();
|
||||
- if (blockPos.getY() < level.getSeaLevel()) {
|
||||
+ if (!level().purpurConfig.ocelotSpawnUnderSeaLevel && blockPos.getY() < level.getSeaLevel()) { // Purpur - Option Ocelot Spawn Under Sea Level
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/animal/fish/WaterAnimal.java b/net/minecraft/world/entity/animal/fish/WaterAnimal.java
|
||||
index 3965cb8ae6fdd8d9d0135e6695463e6bef624fe2..9ff11eb96bc8d0c9bd611c8d45d8799c67f1fb61 100644
|
||||
--- a/net/minecraft/world/entity/animal/fish/WaterAnimal.java
|
||||
+++ b/net/minecraft/world/entity/animal/fish/WaterAnimal.java
|
||||
@@ -76,8 +76,7 @@ public abstract class WaterAnimal extends PathfinderMob {
|
||||
seaLevel = level.getMinecraftWorld().paperConfig().entities.spawning.wateranimalSpawnHeight.maximum.or(seaLevel);
|
||||
i = level.getMinecraftWorld().paperConfig().entities.spawning.wateranimalSpawnHeight.minimum.or(i);
|
||||
// Paper end - Make water animal spawn height configurable
|
||||
- return pos.getY() >= i
|
||||
- && pos.getY() <= seaLevel
|
||||
+ return ((spawnReason == EntitySpawnReason.SPAWNER && level.getMinecraftWorld().purpurConfig.spawnerFixMC238526) || (pos.getY() >= i && pos.getY() <= seaLevel)) // Purpur - MC-238526 - Fix spawner not spawning water animals correctly
|
||||
&& level.getFluidState(pos.below()).is(FluidTags.WATER)
|
||||
&& level.getBlockState(pos.above()).is(Blocks.WATER);
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/animal/golem/CopperGolemAi.java b/net/minecraft/world/entity/animal/golem/CopperGolemAi.java
|
||||
index 56872b4674ae4ce0ebcb6c28ae606265384777cd..fd556e10ff87eac5e965a5eef31cfe0c0f8fbd66 100644
|
||||
--- a/net/minecraft/world/entity/animal/golem/CopperGolemAi.java
|
||||
+++ b/net/minecraft/world/entity/animal/golem/CopperGolemAi.java
|
||||
@@ -43,7 +43,7 @@ public class CopperGolemAi {
|
||||
private static final int TICK_TO_START_ON_REACHED_INTERACTION = 1;
|
||||
private static final int TICK_TO_PLAY_ON_REACHED_SOUND = 9;
|
||||
private static final Predicate<BlockState> TRANSPORT_ITEM_SOURCE_BLOCK = state -> state.is(BlockTags.COPPER_CHESTS);
|
||||
- private static final Predicate<BlockState> TRANSPORT_ITEM_DESTINATION_BLOCK = state -> state.is(Blocks.CHEST) || state.is(Blocks.TRAPPED_CHEST);
|
||||
+ private static final Predicate<BlockState> TRANSPORT_ITEM_DESTINATION_BLOCK = state -> state.is(Blocks.CHEST) || state.is(Blocks.TRAPPED_CHEST); // Purpur - copper golem can place items in barrels or shulkers option - diff on change
|
||||
private static final ImmutableList<SensorType<? extends Sensor<? super CopperGolem>>> SENSOR_TYPES = ImmutableList.of(
|
||||
SensorType.NEAREST_LIVING_ENTITIES, SensorType.HURT_BY
|
||||
);
|
||||
@@ -158,6 +158,11 @@ public class CopperGolemAi {
|
||||
}
|
||||
|
||||
if (integer == 60) {
|
||||
+ // Purpur start - copper golem can place items in barrels or shulkers option
|
||||
+ if (container instanceof net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity shulkerBoxBlockEntity && shulkerBoxBlockEntity.openCount > 0) {
|
||||
+ container.stopOpen(copperGolem);
|
||||
+ }
|
||||
+ // Purpur end - copper golem can place items in barrels or shulkers option
|
||||
if (container.getEntitiesWithContainerOpen().contains(pathfinderMob)) {
|
||||
container.stopOpen(copperGolem);
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/animal/golem/IronGolem.java b/net/minecraft/world/entity/animal/golem/IronGolem.java
|
||||
index b2c4e93f6063ded665b18ba3b4eaa0eb4cd98732..32425f0aaa748c7f80f2e5cf95ef27238fe50489 100644
|
||||
--- a/net/minecraft/world/entity/animal/golem/IronGolem.java
|
||||
+++ b/net/minecraft/world/entity/animal/golem/IronGolem.java
|
||||
@@ -58,13 +58,25 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
|
||||
private static final UniformInt PERSISTENT_ANGER_TIME = TimeUtil.rangeOfSeconds(20, 39);
|
||||
private long persistentAngerEndTime;
|
||||
private @Nullable EntityReference<LivingEntity> persistentAngerTarget;
|
||||
+ private java.util.@Nullable UUID summoner; // Purpur - Summoner API
|
||||
|
||||
public IronGolem(EntityType<? extends IronGolem> type, Level level) {
|
||||
super(type, level);
|
||||
}
|
||||
|
||||
+ // Purpur start - Summoner API
|
||||
+ public java.util.@Nullable UUID getSummoner() {
|
||||
+ return summoner;
|
||||
+ }
|
||||
+
|
||||
+ public void setSummoner(java.util.@Nullable UUID summoner) {
|
||||
+ this.summoner = summoner;
|
||||
+ }
|
||||
+ // Purpur end - Summoner API
|
||||
+
|
||||
@Override
|
||||
protected void registerGoals() {
|
||||
+ if (this.level().purpurConfig.ironGolemPoppyCalm) this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.ReceiveFlower(this)); // Purpur - Iron golem calm anger options
|
||||
this.goalSelector.addGoal(1, new MeleeAttackGoal(this, 1.0, true));
|
||||
this.goalSelector.addGoal(2, new MoveTowardsTargetGoal(this, 0.9, 32.0F));
|
||||
this.goalSelector.addGoal(2, new MoveBackToVillageGoal(this, 0.6, false));
|
||||
@@ -142,6 +154,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
|
||||
protected void addAdditionalSaveData(ValueOutput output) {
|
||||
super.addAdditionalSaveData(output);
|
||||
output.putBoolean("PlayerCreated", this.isPlayerCreated());
|
||||
+ output.storeNullable("Purpur.Summoner", net.minecraft.core.UUIDUtil.CODEC, getSummoner()); // Purpur - Summoner API
|
||||
this.addPersistentAngerSaveData(output);
|
||||
}
|
||||
|
||||
@@ -149,6 +162,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
|
||||
protected void readAdditionalSaveData(ValueInput input) {
|
||||
super.readAdditionalSaveData(input);
|
||||
this.setPlayerCreated(input.getBooleanOr("PlayerCreated", false));
|
||||
+ this.setSummoner(input.read("Purpur.Summoner", net.minecraft.core.UUIDUtil.CODEC).orElse(null)); // Purpur - Summoner API
|
||||
this.readPersistentAngerSaveData(this.level(), input);
|
||||
}
|
||||
|
||||
@@ -267,6 +281,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
|
||||
float f = 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F;
|
||||
this.playSound(SoundEvents.IRON_GOLEM_REPAIR, 1.0F, f);
|
||||
itemInHand.consume(1, player);
|
||||
+ if (this.level().purpurConfig.ironGolemHealCalm && isAngry() && getHealth() == getMaxHealth()) stopBeingAngry(); // Purpur - Iron golem calm anger options
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/animal/parrot/Parrot.java b/net/minecraft/world/entity/animal/parrot/Parrot.java
|
||||
index 62a26395ee0c3ee450ad3b1ac88bc85523dd27b4..0337ddcd664cd0329d98286214d1aa4daf83e1ea 100644
|
||||
--- a/net/minecraft/world/entity/animal/parrot/Parrot.java
|
||||
+++ b/net/minecraft/world/entity/animal/parrot/Parrot.java
|
||||
@@ -164,6 +164,7 @@ public class Parrot extends ShoulderRidingEntity implements FlyingAnimal {
|
||||
protected void registerGoals() {
|
||||
this.goalSelector.addGoal(0, new TamableAnimal.TamableAnimalPanicGoal(1.25));
|
||||
this.goalSelector.addGoal(0, new FloatGoal(this));
|
||||
+ if (this.level().purpurConfig.parrotBreedable) this.goalSelector.addGoal(1, new net.minecraft.world.entity.ai.goal.BreedGoal(this, 1.0D)); // Purpur - Breedable parrots
|
||||
this.goalSelector.addGoal(1, new LookAtPlayerGoal(this, Player.class, 8.0F));
|
||||
this.goalSelector.addGoal(2, new SitWhenOrderedToGoal(this));
|
||||
this.goalSelector.addGoal(2, new FollowOwnerGoal(this, 1.0, 5.0F, 1.0F));
|
||||
@@ -269,7 +270,7 @@ public class Parrot extends ShoulderRidingEntity implements FlyingAnimal {
|
||||
}
|
||||
|
||||
if (!this.level().isClientSide()) {
|
||||
- if (this.random.nextInt(10) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit
|
||||
+ if (((this.level().purpurConfig.alwaysTameInCreative && player.hasInfiniteMaterials()) || this.random.nextInt(10) == 0) && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit // Purpur - Config to always tame in Creative
|
||||
this.tame(player);
|
||||
this.level().broadcastEntityEvent(this, EntityEvent.TAMING_SUCCEEDED);
|
||||
} else {
|
||||
@@ -277,6 +278,7 @@ public class Parrot extends ShoulderRidingEntity implements FlyingAnimal {
|
||||
}
|
||||
}
|
||||
|
||||
+ if (this.level().purpurConfig.parrotBreedable) return super.mobInteract(player, hand); // Purpur - Breedable parrots
|
||||
return InteractionResult.SUCCESS;
|
||||
} else if (!itemInHand.is(ItemTags.PARROT_POISONOUS_FOOD)) {
|
||||
if (!this.isFlying() && this.isTame() && this.isOwnedBy(player)) {
|
||||
@@ -301,7 +303,7 @@ public class Parrot extends ShoulderRidingEntity implements FlyingAnimal {
|
||||
|
||||
@Override
|
||||
public boolean isFood(ItemStack stack) {
|
||||
- return false;
|
||||
+ return this.level().purpurConfig.parrotBreedable && stack.is(ItemTags.PARROT_FOOD); // Purpur - Breedable parrots
|
||||
}
|
||||
|
||||
public static boolean checkParrotSpawnRules(
|
||||
@@ -316,12 +318,12 @@ public class Parrot extends ShoulderRidingEntity implements FlyingAnimal {
|
||||
|
||||
@Override
|
||||
public boolean canMate(Animal otherAnimal) {
|
||||
- return false;
|
||||
+ return super.canMate(otherAnimal); // Purpur - Breedable parrots
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable AgeableMob getBreedOffspring(ServerLevel level, AgeableMob partner) {
|
||||
- return null;
|
||||
+ return level.purpurConfig.parrotBreedable ? EntityType.PARROT.create(level, EntitySpawnReason.BREEDING) : null; // Purpur - Breedable parrots
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,30 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/animal/pig/Pig.java b/net/minecraft/world/entity/animal/pig/Pig.java
|
||||
index 8f5d1e2d98472e8e313fad285bd1629aea4173a9..943bd459554e9f3374978e595ba369a479d44941 100644
|
||||
--- a/net/minecraft/world/entity/animal/pig/Pig.java
|
||||
+++ b/net/minecraft/world/entity/animal/pig/Pig.java
|
||||
@@ -138,6 +138,19 @@ public class Pig extends Animal implements ItemSteerable {
|
||||
@Override
|
||||
public InteractionResult mobInteract(Player player, InteractionHand hand) {
|
||||
boolean isFood = this.isFood(player.getItemInHand(hand));
|
||||
+ // Purpur start - Pigs give saddle back
|
||||
+ if (level().purpurConfig.pigGiveSaddleBack && player.isSecondaryUseActive() && !isFood && isSaddled() && !isVehicle()) {
|
||||
+ this.setItemSlot(EquipmentSlot.SADDLE, ItemStack.EMPTY);
|
||||
+ if (!player.getAbilities().instabuild) {
|
||||
+ ItemStack saddle = new ItemStack(Items.SADDLE);
|
||||
+ if (!player.getInventory().add(saddle)) {
|
||||
+ player.drop(saddle, false);
|
||||
+ }
|
||||
+ }
|
||||
+ return InteractionResult.SUCCESS;
|
||||
+ }
|
||||
+ // Purpur end - Pigs give saddle back
|
||||
+
|
||||
if (!isFood && this.isSaddled() && !this.isVehicle() && !player.isSecondaryUseActive()) {
|
||||
if (!this.level().isClientSide()) {
|
||||
player.startRiding(this);
|
||||
@@ -1,62 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/animal/polarbear/PolarBear.java b/net/minecraft/world/entity/animal/polarbear/PolarBear.java
|
||||
index 8fd0d632e7c6fc7fcb7e9cf141638b5171800799..df4b4a4d32019ef3a667841a0ce4485a8325e897 100644
|
||||
--- a/net/minecraft/world/entity/animal/polarbear/PolarBear.java
|
||||
+++ b/net/minecraft/world/entity/animal/polarbear/PolarBear.java
|
||||
@@ -66,6 +66,29 @@ public class PolarBear extends Animal implements NeutralMob {
|
||||
super(type, level);
|
||||
}
|
||||
|
||||
+ // Purpur start - Breedable Polar Bears
|
||||
+ public boolean canMate(Animal other) {
|
||||
+ if (other == this) {
|
||||
+ return false;
|
||||
+ } else if (this.isStanding()) {
|
||||
+ return false;
|
||||
+ } else if (this.getTarget() != null) {
|
||||
+ return false;
|
||||
+ } else if (!(other instanceof PolarBear)) {
|
||||
+ return false;
|
||||
+ } else {
|
||||
+ PolarBear bear = (PolarBear) other;
|
||||
+ if (bear.isStanding()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (bear.getTarget() != null) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ return this.isInLove() && bear.isInLove();
|
||||
+ }
|
||||
+ }
|
||||
+ // Purpur end - Breedable Polar Bears
|
||||
+
|
||||
@Override
|
||||
public @Nullable AgeableMob getBreedOffspring(ServerLevel level, AgeableMob partner) {
|
||||
return EntityType.POLAR_BEAR.create(level, EntitySpawnReason.BREEDING);
|
||||
@@ -73,7 +96,7 @@ public class PolarBear extends Animal implements NeutralMob {
|
||||
|
||||
@Override
|
||||
public boolean isFood(ItemStack stack) {
|
||||
- return false;
|
||||
+ return level().purpurConfig.polarBearBreedableItem != null && stack.getItem() == level().purpurConfig.polarBearBreedableItem; // Purpur - Breedable Polar Bears
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,6 +105,12 @@ public class PolarBear extends Animal implements NeutralMob {
|
||||
this.goalSelector.addGoal(0, new FloatGoal(this));
|
||||
this.goalSelector.addGoal(1, new PolarBear.PolarBearMeleeAttackGoal());
|
||||
this.goalSelector.addGoal(1, new PanicGoal(this, 2.0, mob -> mob.isBaby() ? DamageTypeTags.PANIC_CAUSES : DamageTypeTags.PANIC_ENVIRONMENTAL_CAUSES));
|
||||
+ // Purpur start - Breedable Polar Bears
|
||||
+ if (level().purpurConfig.polarBearBreedableItem != null) {
|
||||
+ this.goalSelector.addGoal(2, new net.minecraft.world.entity.ai.goal.BreedGoal(this, 1.0D));
|
||||
+ this.goalSelector.addGoal(3, new net.minecraft.world.entity.ai.goal.TemptGoal(this, 1.0D, net.minecraft.world.item.crafting.Ingredient.of(level().purpurConfig.polarBearBreedableItem), false));
|
||||
+ }
|
||||
+ // Purpur end - Breedable Polar Bears
|
||||
this.goalSelector.addGoal(4, new FollowParentGoal(this, 1.25));
|
||||
this.goalSelector.addGoal(5, new RandomStrollGoal(this, 1.0));
|
||||
this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 6.0F));
|
||||
@@ -1,34 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/animal/rabbit/Rabbit.java b/net/minecraft/world/entity/animal/rabbit/Rabbit.java
|
||||
index 17e58836d18afc7cfcc1cf7a8ac5b9e66ceb5f0d..d5e7599c23405eb5a4519e2dfd93ddbe2853fa3b 100644
|
||||
--- a/net/minecraft/world/entity/animal/rabbit/Rabbit.java
|
||||
+++ b/net/minecraft/world/entity/animal/rabbit/Rabbit.java
|
||||
@@ -404,10 +404,23 @@ public class Rabbit extends Animal {
|
||||
}
|
||||
|
||||
this.setVariant(randomRabbitVariant);
|
||||
+
|
||||
+ // Purpur start - Special mobs naturally spawn
|
||||
+ if (randomRabbitVariant != Variant.EVIL && level.getLevel().purpurConfig.rabbitNaturalToast > 0D && random.nextDouble() <= level.getLevel().purpurConfig.rabbitNaturalToast) {
|
||||
+ setCustomName(Component.translatable("Toast"));
|
||||
+ }
|
||||
+ // Purpur end - Special mobs naturally spawn
|
||||
+
|
||||
return super.finalizeSpawn(level, difficulty, spawnReason, spawnGroupData);
|
||||
}
|
||||
|
||||
private static Rabbit.Variant getRandomRabbitVariant(LevelAccessor level, BlockPos pos) {
|
||||
+ // Purpur start - Special mobs naturally spawn
|
||||
+ Level world = level.getMinecraftWorld();
|
||||
+ if (world.purpurConfig.rabbitNaturalKiller > 0D && world.getRandom().nextDouble() <= world.purpurConfig.rabbitNaturalKiller) {
|
||||
+ return Rabbit.Variant.EVIL;
|
||||
+ }
|
||||
+ // Purpur end - Special mobs naturally spawn
|
||||
Holder<Biome> biome = level.getBiome(pos);
|
||||
int randomInt = level.getRandom().nextInt(100);
|
||||
if (biome.is(BiomeTags.SPAWNS_WHITE_RABBITS)) {
|
||||
@@ -1,58 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/animal/squid/Squid.java b/net/minecraft/world/entity/animal/squid/Squid.java
|
||||
index 0e13879ce2802ff8ef0ee9b745a23396727c3e30..504573bf4cbdf1debfa9f9bd071fa40d443b860d 100644
|
||||
--- a/net/minecraft/world/entity/animal/squid/Squid.java
|
||||
+++ b/net/minecraft/world/entity/animal/squid/Squid.java
|
||||
@@ -48,10 +48,29 @@ public class Squid extends AgeableWaterCreature {
|
||||
|
||||
public Squid(EntityType<? extends Squid> type, Level level) {
|
||||
super(type, level);
|
||||
- // this.random.setSeed(this.getId()); // Paper - Share random for entities to make them more random
|
||||
+ if (!level.purpurConfig.entitySharedRandom) this.random.setSeed(this.getId()); // Paper - Share random for entities to make them more random // Purpur - Add toggle for RNG manipulation
|
||||
this.tentacleSpeed = 1.0F / (this.random.nextFloat() + 1.0F) * 0.2F;
|
||||
}
|
||||
|
||||
+ // Purpur start - Stop squids floating on top of water
|
||||
+ @Override
|
||||
+ public net.minecraft.world.phys.AABB getAxisForFluidCheck() {
|
||||
+ // Stops squids from floating just over the water
|
||||
+ return super.getAxisForFluidCheck().offsetY(level().purpurConfig.squidOffsetWaterCheck);
|
||||
+ }
|
||||
+ // Purpur end - Stop squids floating on top of water
|
||||
+
|
||||
+ // Purpur start - Flying squids! Oh my!
|
||||
+ public boolean canFly() {
|
||||
+ return this.level().purpurConfig.squidsCanFly;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isInWater() {
|
||||
+ return this.wasTouchingWater || canFly();
|
||||
+ }
|
||||
+ // Purpur end - Flying squids! Oh my!
|
||||
+
|
||||
@Override
|
||||
protected void registerGoals() {
|
||||
this.goalSelector.addGoal(0, new Squid.SquidRandomMovementGoal(this));
|
||||
@@ -128,6 +147,7 @@ public class Squid extends AgeableWaterCreature {
|
||||
}
|
||||
|
||||
if (this.isInWater()) {
|
||||
+ if (canFly()) setNoGravity(!wasTouchingWater); // Purpur - Flying squids! Oh my!
|
||||
if (this.tentacleMovement < (float) Math.PI) {
|
||||
float f = this.tentacleMovement / (float) Math.PI;
|
||||
this.tentacleAngle = Mth.sin(f * f * (float) Math.PI) * (float) Math.PI * 0.25F;
|
||||
@@ -308,7 +328,7 @@ public class Squid extends AgeableWaterCreature {
|
||||
int noActionTime = this.squid.getNoActionTime();
|
||||
if (noActionTime > 100) {
|
||||
this.squid.movementVector = Vec3.ZERO;
|
||||
- } else if (this.squid.getRandom().nextInt(reducedTickDelay(50)) == 0 || !this.squid.wasTouchingWater || !this.squid.hasMovementVector()) {
|
||||
+ } else if (this.squid.getRandom().nextInt(reducedTickDelay(50)) == 0 || !this.squid.isInWater() || !this.squid.hasMovementVector()) { // Purpur - Flying squids! Oh my!
|
||||
float f = this.squid.getRandom().nextFloat() * (float) (Math.PI * 2);
|
||||
this.squid.movementVector = new Vec3(Mth.cos(f) * 0.2F, -0.1F + this.squid.getRandom().nextFloat() * 0.2F, Mth.sin(f) * 0.2F);
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/animal/wolf/Wolf.java b/net/minecraft/world/entity/animal/wolf/Wolf.java
|
||||
index ffad6072280fb4d02f0a37a97d8c83fba85d3bc2..725624f63a2fbf0bd489a92e2c5862c82d72556c 100644
|
||||
--- a/net/minecraft/world/entity/animal/wolf/Wolf.java
|
||||
+++ b/net/minecraft/world/entity/animal/wolf/Wolf.java
|
||||
@@ -100,6 +100,37 @@ public class Wolf extends TamableAnimal implements NeutralMob {
|
||||
EntityType<?> type = entity.getType();
|
||||
return type == EntityType.SHEEP || type == EntityType.RABBIT || type == EntityType.FOX;
|
||||
};
|
||||
+ // Purpur start - Configurable chance for wolves to spawn rabid
|
||||
+ private boolean isRabid = false;
|
||||
+ private static final TargetingConditions.Selector RABID_PREDICATE = (entity, ignored) -> entity instanceof net.minecraft.server.level.ServerPlayer || entity instanceof net.minecraft.world.entity.Mob;
|
||||
+ private final net.minecraft.world.entity.ai.goal.Goal PATHFINDER_VANILLA = new NonTameRandomTargetGoal<>(this, Animal.class, false, PREY_SELECTOR);
|
||||
+ private final net.minecraft.world.entity.ai.goal.Goal PATHFINDER_RABID = new NonTameRandomTargetGoal<>(this, LivingEntity.class, false, RABID_PREDICATE);
|
||||
+ private static final class AvoidRabidWolfGoal extends AvoidEntityGoal<Wolf> {
|
||||
+ private final Wolf wolf;
|
||||
+
|
||||
+ public AvoidRabidWolfGoal(Wolf wolf, float distance, double minSpeed, double maxSpeed) {
|
||||
+ super(wolf, Wolf.class, distance, minSpeed, maxSpeed);
|
||||
+ this.wolf = wolf;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean canUse() {
|
||||
+ return super.canUse() && !this.wolf.isRabid() && this.toAvoid != null && this.toAvoid.isRabid(); // wolves which are not rabid run away from rabid wolves
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void start() {
|
||||
+ this.wolf.setTarget(null);
|
||||
+ super.start();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void tick() {
|
||||
+ this.wolf.setTarget(null);
|
||||
+ super.tick();
|
||||
+ }
|
||||
+ }
|
||||
+ // Purpur end - Configurable chance for wolves to spawn rabid
|
||||
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;
|
||||
@@ -121,12 +152,47 @@ public class Wolf extends TamableAnimal implements NeutralMob {
|
||||
this.setPathfindingMalus(PathType.DANGER_POWDER_SNOW, -1.0F);
|
||||
}
|
||||
|
||||
+ // Purpur start - Configurable chance for wolves to spawn rabid
|
||||
+ public boolean isRabid() {
|
||||
+ return this.isRabid;
|
||||
+ }
|
||||
+
|
||||
+ public void setRabid(boolean isRabid) {
|
||||
+ this.isRabid = isRabid;
|
||||
+ updatePathfinders(true);
|
||||
+ }
|
||||
+
|
||||
+ public void updatePathfinders(boolean modifyEffects) {
|
||||
+ this.targetSelector.removeGoal(PATHFINDER_VANILLA);
|
||||
+ this.targetSelector.removeGoal(PATHFINDER_RABID);
|
||||
+ if (this.isRabid) {
|
||||
+ this.setOwnerReference(null);
|
||||
+ setTame(false, true);
|
||||
+ this.targetSelector.addGoal(5, PATHFINDER_RABID);
|
||||
+ if (modifyEffects) this.addEffect(new net.minecraft.world.effect.MobEffectInstance(net.minecraft.world.effect.MobEffects.NAUSEA, 1200));
|
||||
+ } else {
|
||||
+ this.targetSelector.addGoal(5, PATHFINDER_VANILLA);
|
||||
+ this.stopBeingAngry();
|
||||
+ if (modifyEffects) this.removeEffect(net.minecraft.world.effect.MobEffects.NAUSEA);
|
||||
+ }
|
||||
+ }
|
||||
+ // Purpur end - Configurable chance for wolves to spawn rabid
|
||||
+
|
||||
+ // Purpur start - Configurable default collar color
|
||||
+ @Override
|
||||
+ public void tame(Player player) {
|
||||
+ setCollarColor(level().purpurConfig.wolfDefaultCollarColor);
|
||||
+ super.tame(player);
|
||||
+ }
|
||||
+ // Purpur end - Configurable default collar color
|
||||
+
|
||||
@Override
|
||||
protected void registerGoals() {
|
||||
this.goalSelector.addGoal(1, new FloatGoal(this));
|
||||
this.goalSelector.addGoal(1, new TamableAnimal.TamableAnimalPanicGoal(1.5, DamageTypeTags.PANIC_ENVIRONMENTAL_CAUSES));
|
||||
this.goalSelector.addGoal(2, new SitWhenOrderedToGoal(this));
|
||||
this.goalSelector.addGoal(3, new Wolf.WolfAvoidEntityGoal<>(this, Llama.class, 24.0F, 1.5, 1.5));
|
||||
+ this.goalSelector.addGoal(3, new AvoidRabidWolfGoal(this, 24.0F, 1.5D, 1.5D)); // Purpur - Configurable chance for wolves to spawn rabid
|
||||
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));
|
||||
@@ -139,7 +205,7 @@ public class Wolf extends TamableAnimal implements NeutralMob {
|
||||
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));
|
||||
- this.targetSelector.addGoal(5, new NonTameRandomTargetGoal<>(this, Animal.class, false, PREY_SELECTOR));
|
||||
+ //this.targetSelector.addGoal(5, new NonTameRandomTargetGoal<>(this, Animal.class, false, PREY_SELECTOR)); // Purpur - Configurable chance for wolves to spawn rabid - moved to updatePathfinders()
|
||||
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));
|
||||
@@ -229,6 +295,7 @@ public class Wolf extends TamableAnimal implements NeutralMob {
|
||||
protected void addAdditionalSaveData(ValueOutput output) {
|
||||
super.addAdditionalSaveData(output);
|
||||
output.store("CollarColor", DyeColor.LEGACY_ID_CODEC, this.getCollarColor());
|
||||
+ output.putBoolean("Purpur.IsRabid", this.isRabid); // Purpur - Configurable chance for wolves to spawn rabid
|
||||
VariantUtils.writeVariant(output, this.getVariant());
|
||||
this.addPersistentAngerSaveData(output);
|
||||
this.getSoundVariant()
|
||||
@@ -243,6 +310,10 @@ public class Wolf extends TamableAnimal implements NeutralMob {
|
||||
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));
|
||||
+ // Purpur start - Configurable chance for wolves to spawn rabid
|
||||
+ this.isRabid = input.getBooleanOr("Purpur.IsRabid", false);
|
||||
+ this.updatePathfinders(false);
|
||||
+ // Purpur end - Configurable chance for wolves to spawn rabid
|
||||
this.readPersistentAngerSaveData(this.level(), input);
|
||||
input.read("sound_variant", ResourceKey.codec(Registries.WOLF_SOUND_VARIANT))
|
||||
.flatMap(resourceKey -> this.registryAccess().lookupOrThrow(Registries.WOLF_SOUND_VARIANT).get((ResourceKey<WolfSoundVariant>)resourceKey))
|
||||
@@ -266,6 +337,10 @@ public class Wolf extends TamableAnimal implements NeutralMob {
|
||||
}
|
||||
|
||||
this.setSoundVariant(WolfSoundVariants.pickRandomSoundVariant(this.registryAccess(), level.getRandom()));
|
||||
+ // Purpur start - Configurable chance for wolves to spawn rabid
|
||||
+ this.isRabid = level.getLevel().purpurConfig.wolfNaturalRabid > 0.0D && random.nextDouble() <= level.getLevel().purpurConfig.wolfNaturalRabid;
|
||||
+ this.updatePathfinders(false);
|
||||
+ // Purpur end - Configurable chance for wolves to spawn rabid
|
||||
return super.finalizeSpawn(level, difficulty, spawnReason, spawnGroupData);
|
||||
}
|
||||
|
||||
@@ -316,6 +391,11 @@ public class Wolf extends TamableAnimal implements NeutralMob {
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (this.isAlive()) {
|
||||
+ // Purpur start - Configurable chance for wolves to spawn rabid
|
||||
+ if (this.age % 300 == 0 && this.isRabid()) {
|
||||
+ this.addEffect(new net.minecraft.world.effect.MobEffectInstance(net.minecraft.world.effect.MobEffects.NAUSEA, 400));
|
||||
+ }
|
||||
+ // Purpur end - Configurable chance for wolves to spawn rabid
|
||||
this.interestedAngleO = this.interestedAngle;
|
||||
if (this.isInterested()) {
|
||||
this.interestedAngle = this.interestedAngle + (1.0F - this.interestedAngle) * 0.4F;
|
||||
@@ -517,13 +597,27 @@ public class Wolf extends TamableAnimal implements NeutralMob {
|
||||
itemInHand.consume(1, player);
|
||||
this.tryToTame(player);
|
||||
return InteractionResult.SUCCESS_SERVER;
|
||||
+ // Purpur start - Configurable chance for wolves to spawn rabid
|
||||
+ } else if (this.level().purpurConfig.wolfMilkCuresRabies && itemInHand.getItem() == Items.MILK_BUCKET && this.isRabid()) {
|
||||
+ if (!player.isCreative()) {
|
||||
+ player.setItemInHand(hand, new ItemStack(Items.BUCKET));
|
||||
+ }
|
||||
+ this.setRabid(false);
|
||||
+ for (int i = 0; i < 10; ++i) {
|
||||
+ ((ServerLevel) level()).sendParticlesSource(((ServerLevel) level()).players(), null, ParticleTypes.HAPPY_VILLAGER,
|
||||
+ false, true,
|
||||
+ getX() + random.nextFloat(), getY() + (random.nextFloat() * 1.5), getZ() + random.nextFloat(), 1,
|
||||
+ random.nextGaussian() * 0.05D, random.nextGaussian() * 0.05D, random.nextGaussian() * 0.05D, 0);
|
||||
+ }
|
||||
+ return InteractionResult.SUCCESS_SERVER;
|
||||
+ // Purpur end - Configurable chance for wolves to spawn rabid
|
||||
}
|
||||
|
||||
return super.mobInteract(player, hand);
|
||||
}
|
||||
|
||||
private void tryToTame(Player player) {
|
||||
- if (this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit - added event call
|
||||
+ if (((this.level().purpurConfig.alwaysTameInCreative && player.hasInfiniteMaterials()) || this.random.nextInt(3) == 0) && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit - added event call // Purpur - Config to always tame in Creative
|
||||
this.tame(player);
|
||||
this.navigation.stop();
|
||||
this.setTarget(null);
|
||||
@@ -1,64 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java b/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
|
||||
index c095f42aa103b7874fb5d8dcece1b1484c2e2968..d1c593ccfab7bee4366ee7c56606a230964e3fb7 100644
|
||||
--- a/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
|
||||
+++ b/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
|
||||
@@ -39,6 +39,24 @@ public class EndCrystal extends Entity {
|
||||
this.setPos(x, y, z);
|
||||
}
|
||||
|
||||
+ // Purpur start - End crystal explosion options
|
||||
+ public boolean shouldExplode() {
|
||||
+ return showsBottom() ? level().purpurConfig.basedEndCrystalExplode : level().purpurConfig.baselessEndCrystalExplode;
|
||||
+ }
|
||||
+
|
||||
+ public float getExplosionPower() {
|
||||
+ return (float) (showsBottom() ? level().purpurConfig.basedEndCrystalExplosionPower : level().purpurConfig.baselessEndCrystalExplosionPower);
|
||||
+ }
|
||||
+
|
||||
+ public boolean hasExplosionFire() {
|
||||
+ return showsBottom() ? level().purpurConfig.basedEndCrystalExplosionFire : level().purpurConfig.baselessEndCrystalExplosionFire;
|
||||
+ }
|
||||
+
|
||||
+ public Level.ExplosionInteraction getExplosionEffect() {
|
||||
+ return showsBottom() ? level().purpurConfig.basedEndCrystalExplosionEffect : level().purpurConfig.baselessEndCrystalExplosionEffect;
|
||||
+ }
|
||||
+ // Purpur end - End crystal explosion options
|
||||
+
|
||||
@Override
|
||||
protected Entity.MovementEmission getMovementEmission() {
|
||||
return Entity.MovementEmission.NONE;
|
||||
@@ -75,6 +93,8 @@ public class EndCrystal extends Entity {
|
||||
}
|
||||
}
|
||||
// Paper end - Fix invulnerable end crystals
|
||||
+ if (this.level().purpurConfig.endCrystalCramming > 0 && this.level().getEntitiesOfClass(EndCrystal.class, getBoundingBox()).size() > this.level().purpurConfig.endCrystalCramming) this.hurt(this.damageSources().cramming(), 6.0F); // Purpur - End Crystal Cramming
|
||||
+
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -115,15 +135,17 @@ public class EndCrystal extends Entity {
|
||||
}
|
||||
// CraftBukkit end
|
||||
if (!damageSource.is(DamageTypeTags.IS_EXPLOSION)) {
|
||||
+ if (shouldExplode()) {// Purpur - End crystal explosion options
|
||||
DamageSource damageSource1 = damageSource.getEntity() != null ? this.damageSources().explosion(this, damageSource.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, damageSource1, null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.BLOCK);
|
||||
+ level.explode(this, damageSource1, 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,27 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
index 1daf8f52148043339f723aaebdf6135763dd805b..9c38e3b8c09caa2701a207b91761f344c5e53385 100644
|
||||
--- a/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
+++ b/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
@@ -957,6 +957,7 @@ public class EnderDragon extends Mob implements Enemy {
|
||||
|
||||
@Override
|
||||
protected boolean canRide(Entity entity) {
|
||||
+ if (this.level().purpurConfig.enderDragonCanRideVehicles) return this.boardingCooldown <= 0; // Purpur - Configs for if Wither/Ender Dragon can ride vehicles
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -992,7 +993,7 @@ public class EnderDragon extends Mob implements Enemy {
|
||||
boolean flag = level.getGameRules().get(GameRules.MOB_DROPS);
|
||||
int i = 500;
|
||||
|
||||
- if (this.dragonFight != null && !this.dragonFight.hasPreviouslyKilledDragon()) {
|
||||
+ if (this.dragonFight != null && (level().purpurConfig.enderDragonAlwaysDropsFullExp || !this.dragonFight.hasPreviouslyKilledDragon())) { // Purpur - Ender dragon always drop full exp
|
||||
i = 12000;
|
||||
}
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/boss/wither/WitherBoss.java b/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
||||
index 86b6b94c3e63bb52917fe0f708d24aa813f433c7..be74b2f6e21e9adb1e5c96414854a5c4f07655fc 100644
|
||||
--- a/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
||||
+++ b/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
||||
@@ -80,6 +80,7 @@ public class WitherBoss extends Monster implements RangedAttackMob {
|
||||
private static final TargetingConditions.Selector LIVING_ENTITY_SELECTOR = (entity, level) -> !entity.getType().is(EntityTypeTags.WITHER_FRIENDS)
|
||||
&& entity.attackable();
|
||||
private static final TargetingConditions TARGETING_CONDITIONS = TargetingConditions.forCombat().range(20.0).selector(LIVING_ENTITY_SELECTOR);
|
||||
+ private java.util.@Nullable UUID summoner; // Purpur - Summoner API
|
||||
|
||||
public WitherBoss(EntityType<? extends WitherBoss> type, Level level) {
|
||||
super(type, level);
|
||||
@@ -88,6 +89,16 @@ public class WitherBoss extends Monster implements RangedAttackMob {
|
||||
this.xpReward = 50;
|
||||
}
|
||||
|
||||
+ // Purpur start - Summoner API
|
||||
+ public java.util.@Nullable UUID getSummoner() {
|
||||
+ return summoner;
|
||||
+ }
|
||||
+
|
||||
+ public void setSummoner(java.util.@Nullable UUID summoner) {
|
||||
+ this.summoner = summoner;
|
||||
+ }
|
||||
+ // Purpur end - Summoner API
|
||||
+
|
||||
@Override
|
||||
protected PathNavigation createNavigation(Level level) {
|
||||
FlyingPathNavigation flyingPathNavigation = new FlyingPathNavigation(this, level);
|
||||
@@ -120,6 +131,7 @@ public class WitherBoss extends Monster implements RangedAttackMob {
|
||||
protected void addAdditionalSaveData(ValueOutput output) {
|
||||
super.addAdditionalSaveData(output);
|
||||
output.putInt("Invul", this.getInvulnerableTicks());
|
||||
+ output.storeNullable("Purpur.Summoner", net.minecraft.core.UUIDUtil.CODEC, getSummoner()); // Purpur - Summoner API
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -129,6 +141,7 @@ public class WitherBoss extends Monster implements RangedAttackMob {
|
||||
if (this.hasCustomName()) {
|
||||
this.bossEvent.setName(this.getDisplayName());
|
||||
}
|
||||
+ this.setSummoner(input.read("Purpur.Summoner", net.minecraft.core.UUIDUtil.CODEC).orElse(null)); // Purpur - Summoner API
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -272,7 +285,7 @@ public class WitherBoss extends Monster implements RangedAttackMob {
|
||||
level.explode(this, this.getX(), this.getEyeY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB);
|
||||
}
|
||||
// CraftBukkit end
|
||||
- if (!this.isSilent()) {
|
||||
+ if (!this.isSilent() && level.purpurConfig.witherPlaySpawnSound) { // Purpur - Toggle for Wither's spawn sound
|
||||
// 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;
|
||||
@@ -379,8 +392,10 @@ public class WitherBoss extends Monster implements RangedAttackMob {
|
||||
}
|
||||
}
|
||||
|
||||
- if (this.tickCount % 20 == 0) {
|
||||
- this.heal(1.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.REGEN); // CraftBukkit
|
||||
+ // Purpur start - Customizable wither health and healing - customizable heal rate and amount
|
||||
+ if (this.tickCount % level().purpurConfig.witherHealthRegenDelay == 0) {
|
||||
+ this.heal(level().purpurConfig.witherHealthRegenAmount, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.REGEN); // CraftBukkit
|
||||
+ // Purpur end - Customizable wither health and healing
|
||||
}
|
||||
|
||||
this.bossEvent.setProgress(this.getHealth() / this.getMaxHealth());
|
||||
@@ -577,6 +592,7 @@ public class WitherBoss extends Monster implements RangedAttackMob {
|
||||
|
||||
@Override
|
||||
protected boolean canRide(Entity entity) {
|
||||
+ if (this.level().purpurConfig.witherCanRideVehicles) return this.boardingCooldown <= 0; // Purpur - Configs for if Wither/Ender Dragon can ride vehicles
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java
|
||||
index e82bb8f2d2b0e771dc371fd7e709116e1f5f204f..ddf7fa8e67440beb102b6bf91b30f2b340b52a8e 100644
|
||||
--- a/net/minecraft/world/entity/item/ItemEntity.java
|
||||
+++ b/net/minecraft/world/entity/item/ItemEntity.java
|
||||
@@ -54,6 +54,12 @@ public class ItemEntity extends Entity implements TraceableEntity {
|
||||
public boolean canMobPickup = true; // Paper - Item#canEntityPickup
|
||||
private int despawnRate = -1; // Paper - Alternative item-despawn-rate
|
||||
public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API
|
||||
+ // Purpur start - Item entity immunities
|
||||
+ public boolean immuneToCactus = false;
|
||||
+ public boolean immuneToExplosion = false;
|
||||
+ public boolean immuneToFire = false;
|
||||
+ public boolean immuneToLightning = false;
|
||||
+ // Purpur end - Item entity immunities
|
||||
|
||||
public ItemEntity(EntityType<? extends ItemEntity> type, Level level) {
|
||||
super(type, level);
|
||||
@@ -330,7 +336,16 @@ public class ItemEntity extends Entity implements TraceableEntity {
|
||||
|
||||
@Override
|
||||
public final boolean hurtServer(ServerLevel level, DamageSource damageSource, float amount) {
|
||||
- if (this.isInvulnerableToBase(damageSource)) {
|
||||
+ // Purpur start - Item entity immunities
|
||||
+ if (
|
||||
+ (immuneToCactus && damageSource.is(net.minecraft.world.damagesource.DamageTypes.CACTUS)) ||
|
||||
+ (immuneToFire && (damageSource.is(net.minecraft.tags.DamageTypeTags.IS_FIRE) || damageSource.is(net.minecraft.world.damagesource.DamageTypes.ON_FIRE) || damageSource.is(net.minecraft.world.damagesource.DamageTypes.IN_FIRE))) ||
|
||||
+ (immuneToLightning && damageSource.is(net.minecraft.world.damagesource.DamageTypes.LIGHTNING_BOLT)) ||
|
||||
+ (immuneToExplosion && damageSource.is(net.minecraft.tags.DamageTypeTags.IS_EXPLOSION))
|
||||
+ ) {
|
||||
+ return false;
|
||||
+ } else if (this.isInvulnerableToBase(damageSource)) {
|
||||
+ // Purpur end - Item entity immunities
|
||||
return false;
|
||||
} else if (!level.getGameRules().get(GameRules.MOB_GRIEFING) && damageSource.getEntity() instanceof Mob) {
|
||||
return false;
|
||||
@@ -508,6 +523,12 @@ public class ItemEntity extends Entity implements TraceableEntity {
|
||||
public void setItem(ItemStack stack) {
|
||||
this.getEntityData().set(DATA_ITEM, stack);
|
||||
this.despawnRate = this.level().paperConfig().entities.spawning.altItemDespawnRate.enabled ? this.level().paperConfig().entities.spawning.altItemDespawnRate.items.getOrDefault(stack.getItem(), this.level().spigotConfig.itemDespawnRate) : this.level().spigotConfig.itemDespawnRate; // Paper - Alternative item-despawn-rate
|
||||
+ // Purpur start - Item entity immunities
|
||||
+ if (level().purpurConfig.itemImmuneToCactus.contains(stack.getItem())) immuneToCactus = true;
|
||||
+ if (level().purpurConfig.itemImmuneToExplosion.contains(stack.getItem())) immuneToExplosion = true;
|
||||
+ if (level().purpurConfig.itemImmuneToFire.contains(stack.getItem())) immuneToFire = true;
|
||||
+ if (level().purpurConfig.itemImmuneToLightning.contains(stack.getItem())) immuneToLightning = true;
|
||||
+ // level end - Item entity immunities
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,73 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/monster/Creeper.java b/net/minecraft/world/entity/monster/Creeper.java
|
||||
index e6d93c7a339f06c40b78f554f4e7070fb7fcad02..168003b7159b5e9ea3e3ca19d0b939ed1cfd2311 100644
|
||||
--- a/net/minecraft/world/entity/monster/Creeper.java
|
||||
+++ b/net/minecraft/world/entity/monster/Creeper.java
|
||||
@@ -56,6 +56,7 @@ public class Creeper extends Monster {
|
||||
public int explosionRadius = 3;
|
||||
public boolean droppedSkulls;
|
||||
public @Nullable Entity entityIgniter; // CraftBukkit
|
||||
+ private boolean exploding = false; // Purpur - Config to make Creepers explode on death
|
||||
|
||||
public Creeper(EntityType<? extends Creeper> type, Level level) {
|
||||
super(type, level);
|
||||
@@ -159,6 +160,27 @@ public class Creeper extends Monster {
|
||||
return false; // CraftBukkit
|
||||
}
|
||||
|
||||
+ // Purpur start - Special mobs naturally spawn
|
||||
+ @Override
|
||||
+ public net.minecraft.world.entity.SpawnGroupData finalizeSpawn(net.minecraft.world.level.ServerLevelAccessor world, net.minecraft.world.DifficultyInstance difficulty, net.minecraft.world.entity.EntitySpawnReason spawnReason, net.minecraft.world.entity.@Nullable SpawnGroupData entityData) {
|
||||
+ double chance = world.getLevel().purpurConfig.creeperChargedChance;
|
||||
+ if (chance > 0D && random.nextDouble() <= chance) {
|
||||
+ setPowered(true);
|
||||
+ }
|
||||
+ return super.finalizeSpawn(world, difficulty, spawnReason, entityData);
|
||||
+ }
|
||||
+ // Purpur end - Special mobs naturally spawn
|
||||
+
|
||||
+ // Purpur start - Config to make Creepers explode on death
|
||||
+ @Override
|
||||
+ protected org.bukkit.event.entity.EntityDeathEvent dropAllDeathLoot(ServerLevel world, DamageSource damageSource) {
|
||||
+ if (!this.exploding && this.level().purpurConfig.creeperExplodeWhenKilled && damageSource.getEntity() instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ this.explodeCreeper();
|
||||
+ }
|
||||
+ return super.dropAllDeathLoot(world, damageSource);
|
||||
+ }
|
||||
+ // Purpur end - Config to make Creepers explode on death
|
||||
+
|
||||
@Override
|
||||
public SoundEvent getHurtSound(DamageSource damageSource) {
|
||||
return SoundEvents.CREEPER_HURT;
|
||||
@@ -243,14 +265,16 @@ public class Creeper extends Monster {
|
||||
}
|
||||
|
||||
public void explodeCreeper() {
|
||||
+ this.exploding = true; // Purpur - Config to make Creepers explode on death
|
||||
if (this.level() instanceof ServerLevel serverLevel) {
|
||||
float f = this.isPowered() ? 2.0F : 1.0F;
|
||||
+ float multiplier = serverLevel.purpurConfig.creeperHealthRadius ? this.getHealth() / this.getMaxHealth() : 1; // Purpur - Config for health to impact Creeper explosion radius
|
||||
// CraftBukkit start
|
||||
- org.bukkit.event.entity.ExplosionPrimeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callExplosionPrimeEvent(this, this.explosionRadius * f, false);
|
||||
+ org.bukkit.event.entity.ExplosionPrimeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callExplosionPrimeEvent(this, (this.explosionRadius * f) * multiplier, false); // Purpur - Config for health to impact Creeper explosion radius
|
||||
if (!event.isCancelled()) {
|
||||
// CraftBukkit end
|
||||
this.dead = true;
|
||||
- serverLevel.explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB); // CraftBukkit // Paper - fix DamageSource API (revert to vanilla, no, just no, don't change this)
|
||||
+ serverLevel.explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), serverLevel.getGameRules().get(net.minecraft.world.level.gamerules.GameRules.MOB_GRIEFING) && level().purpurConfig.creeperAllowGriefing ? Level.ExplosionInteraction.MOB : Level.ExplosionInteraction.NONE); // CraftBukkit // Paper - fix DamageSource API (revert to vanilla, no, just no, don't change this) // Purpur - Add enderman and creeper griefing controls
|
||||
this.spawnLingeringCloud();
|
||||
this.triggerOnDeathMobEffects(serverLevel, Entity.RemovalReason.KILLED);
|
||||
this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause
|
||||
@@ -261,6 +285,7 @@ public class Creeper extends Monster {
|
||||
}
|
||||
// CraftBukkit end
|
||||
}
|
||||
+ this.exploding = false; // Purpur - Config to make Creepers explode on death
|
||||
}
|
||||
|
||||
private void spawnLingeringCloud() {
|
||||
@@ -1,22 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/monster/Ghast.java b/net/minecraft/world/entity/monster/Ghast.java
|
||||
index 605c47f3bd5c4e72389587d50e70fcd57f2a2b27..b8774eb91d21e9f154cc70c5d3bd26de25be41c4 100644
|
||||
--- a/net/minecraft/world/entity/monster/Ghast.java
|
||||
+++ b/net/minecraft/world/entity/monster/Ghast.java
|
||||
@@ -156,6 +156,11 @@ public class Ghast extends Mob implements Enemy {
|
||||
public static boolean checkGhastSpawnRules(
|
||||
EntityType<Ghast> entityType, LevelAccessor level, EntitySpawnReason spawnReason, BlockPos pos, RandomSource random
|
||||
) {
|
||||
+ // Purpur start - Config to disable hostile mob spawn on ice
|
||||
+ if (net.minecraft.world.entity.monster.Monster.canSpawnInBlueAndPackedIce(level, pos)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Purpur end - Config to disable hostile mob spawn on ice
|
||||
return level.getDifficulty() != Difficulty.PEACEFUL && random.nextInt(20) == 0 && checkMobSpawnRules(entityType, level, spawnReason, pos, random);
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/monster/Monster.java b/net/minecraft/world/entity/monster/Monster.java
|
||||
index 07293a33c45a0834f3b623a47a1bd25f3e059f54..54033572e325f8486a438e31dde34f8407f9180a 100644
|
||||
--- a/net/minecraft/world/entity/monster/Monster.java
|
||||
+++ b/net/minecraft/world/entity/monster/Monster.java
|
||||
@@ -84,6 +84,11 @@ public abstract class Monster extends PathfinderMob implements Enemy {
|
||||
}
|
||||
|
||||
public static boolean isDarkEnoughToSpawn(ServerLevelAccessor level, BlockPos pos, RandomSource random) {
|
||||
+ // Purpur start - Config to disable hostile mob spawn on ice
|
||||
+ if (canSpawnInBlueAndPackedIce(level, pos)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Purpur end - Config to disable hostile mob spawn on ice
|
||||
if (level.getBrightness(LightLayer.SKY, pos) > random.nextInt(32)) {
|
||||
return false;
|
||||
} else {
|
||||
@@ -109,6 +114,11 @@ public abstract class Monster extends PathfinderMob implements Enemy {
|
||||
public static boolean checkAnyLightMonsterSpawnRules(
|
||||
EntityType<? extends Monster> entityType, LevelAccessor level, EntitySpawnReason spawnReason, BlockPos pos, RandomSource random
|
||||
) {
|
||||
+ // Purpur start - Config to disable hostile mob spawn on ice
|
||||
+ if (canSpawnInBlueAndPackedIce(level, pos)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Purpur end - Config to disable hostile mob spawn on ice
|
||||
return level.getDifficulty() != Difficulty.PEACEFUL && checkMobSpawnRules(entityType, level, spawnReason, pos, random);
|
||||
}
|
||||
|
||||
@@ -146,4 +156,12 @@ public abstract class Monster extends PathfinderMob implements Enemy {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Purpur start - Config to disable hostile mob spawn on ice
|
||||
+ public static boolean canSpawnInBlueAndPackedIce(LevelAccessor level, BlockPos pos) {
|
||||
+ net.minecraft.world.level.block.state.BlockState spawnBlock = level.getBlockState(pos.below());
|
||||
+
|
||||
+ return (!level.getMinecraftWorld().purpurConfig.mobsSpawnOnPackedIce && spawnBlock.is(net.minecraft.world.level.block.Blocks.PACKED_ICE)) || (!level.getMinecraftWorld().purpurConfig.mobsSpawnOnBlueIce && spawnBlock.is(net.minecraft.world.level.block.Blocks.BLUE_ICE));
|
||||
+ }
|
||||
+ // Purpur end - Config to disable hostile mob spawn on ice
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/monster/Phantom.java b/net/minecraft/world/entity/monster/Phantom.java
|
||||
index 62c40a04a105eff471599c4535239fee9726dbd1..d26b7970490a2a108affee11c3fb74e38509d92b 100644
|
||||
--- a/net/minecraft/world/entity/monster/Phantom.java
|
||||
+++ b/net/minecraft/world/entity/monster/Phantom.java
|
||||
@@ -166,7 +166,11 @@ public class Phantom extends Mob implements Enemy {
|
||||
ServerLevelAccessor level, DifficultyInstance difficulty, EntitySpawnReason spawnReason, @Nullable SpawnGroupData spawnGroupData
|
||||
) {
|
||||
this.anchorPoint = this.blockPosition().above(5);
|
||||
- this.setPhantomSize(0);
|
||||
+ // Purpur start - Configurable phantom size
|
||||
+ int min = level.getLevel().purpurConfig.phantomMinSize;
|
||||
+ int max = level.getLevel().purpurConfig.phantomMaxSize;
|
||||
+ this.setPhantomSize(min == max ? min : level.getRandom().nextInt(max + 1 - min) + min);
|
||||
+ // Purpur end - Configurable phantom size
|
||||
return super.finalizeSpawn(level, difficulty, spawnReason, spawnGroupData);
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/monster/Ravager.java b/net/minecraft/world/entity/monster/Ravager.java
|
||||
index 631092f088355be45f598bb91bd5d38a39a55d5b..a10c693a8948d1b7c4bd06b957a08a9cea9170ad 100644
|
||||
--- a/net/minecraft/world/entity/monster/Ravager.java
|
||||
+++ b/net/minecraft/world/entity/monster/Ravager.java
|
||||
@@ -76,6 +76,7 @@ public class Ravager extends Raider {
|
||||
protected void registerGoals() {
|
||||
super.registerGoals();
|
||||
this.goalSelector.addGoal(0, new FloatGoal(this));
|
||||
+ if (level().purpurConfig.ravagerAvoidRabbits) this.goalSelector.addGoal(3, new net.minecraft.world.entity.ai.goal.AvoidEntityGoal<>(this, net.minecraft.world.entity.animal.rabbit.Rabbit.class, 6.0F, 1.0D, 1.2D)); // Purpur - option to make ravagers afraid of rabbits
|
||||
this.goalSelector.addGoal(4, new MeleeAttackGoal(this, 1.0, true));
|
||||
this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 0.4));
|
||||
this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 6.0F));
|
||||
@@ -154,7 +155,7 @@ public class Ravager extends Raider {
|
||||
)) {
|
||||
BlockState blockState = serverLevel.getBlockState(blockPos);
|
||||
Block block = blockState.getBlock();
|
||||
- if (block instanceof LeavesBlock) {
|
||||
+ if (this.level().purpurConfig.ravagerGriefableBlocks.contains(block)) { // Purpur - Configurable ravager griefable blocks list
|
||||
// CraftBukkit start
|
||||
if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, blockPos, blockState.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state
|
||||
continue;
|
||||
@@ -1,67 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/monster/Shulker.java b/net/minecraft/world/entity/monster/Shulker.java
|
||||
index 935c608ba0fc2246a3f79bf4865cfeb6fe68b0f4..6e8400c4d523da8799d586c5c9019ae78710fbcb 100644
|
||||
--- a/net/minecraft/world/entity/monster/Shulker.java
|
||||
+++ b/net/minecraft/world/entity/monster/Shulker.java
|
||||
@@ -93,6 +93,21 @@ public class Shulker extends AbstractGolem implements Enemy {
|
||||
this.lookControl = new Shulker.ShulkerLookControl(this);
|
||||
}
|
||||
|
||||
+ // Purpur start - Shulker change color with dye
|
||||
+ @Override
|
||||
+ protected net.minecraft.world.InteractionResult mobInteract(Player player, net.minecraft.world.InteractionHand hand) {
|
||||
+ net.minecraft.world.item.ItemStack itemstack = player.getItemInHand(hand);
|
||||
+ if (player.level().purpurConfig.shulkerChangeColorWithDye && itemstack.getItem() instanceof net.minecraft.world.item.DyeItem dye && dye.getDyeColor() != this.getColor()) {
|
||||
+ this.setVariant(Optional.of(dye.getDyeColor()));
|
||||
+ if (!player.getAbilities().instabuild) {
|
||||
+ itemstack.shrink(1);
|
||||
+ }
|
||||
+ return net.minecraft.world.InteractionResult.SUCCESS;
|
||||
+ }
|
||||
+ return super.mobInteract(player, hand);
|
||||
+ }
|
||||
+ // Purpur end - Shulker change color with dye
|
||||
+
|
||||
@Override
|
||||
protected void registerGoals() {
|
||||
this.goalSelector.addGoal(1, new LookAtPlayerGoal(this, Player.class, 8.0F, 0.02F, true));
|
||||
@@ -454,11 +469,21 @@ public class Shulker extends AbstractGolem implements Enemy {
|
||||
private void hitByShulkerBullet() {
|
||||
Vec3 vec3 = this.position();
|
||||
AABB boundingBox = this.getBoundingBox();
|
||||
- if (!this.isClosed() && this.teleportSomewhere()) {
|
||||
- int size = this.level().getEntities(EntityType.SHULKER, boundingBox.inflate(8.0), Entity::isAlive).size();
|
||||
- float f = (size - 1) / 5.0F;
|
||||
- if (!(this.level().random.nextFloat() < f)) {
|
||||
+ // Purpur start - Shulker spawn from bullet options
|
||||
+ if ((!this.level().purpurConfig.shulkerSpawnFromBulletRequireOpenLid || !this.isClosed()) && this.teleportSomewhere()) {
|
||||
+ float chance = this.level().purpurConfig.shulkerSpawnFromBulletBaseChance;
|
||||
+ if (!this.level().purpurConfig.shulkerSpawnFromBulletNearbyEquation.isBlank()) {
|
||||
+ int nearby = this.level().getEntities((net.minecraft.world.level.entity.EntityTypeTest) EntityType.SHULKER, boundingBox.inflate(this.level().purpurConfig.shulkerSpawnFromBulletNearbyRange), Entity::isAlive).size();
|
||||
+ try {
|
||||
+ chance -= ((Number) scriptEngine.eval("let nearby = " + nearby + "; " + this.level().purpurConfig.shulkerSpawnFromBulletNearbyEquation)).floatValue();
|
||||
+ } catch (javax.script.ScriptException e) {
|
||||
+ e.printStackTrace();
|
||||
+ chance -= (nearby - 1) / 5.0F;
|
||||
+ }
|
||||
+ }
|
||||
+ if (this.level().random.nextFloat() <= chance) {
|
||||
Shulker shulker = EntityType.SHULKER.create(this.level(), EntitySpawnReason.BREEDING);
|
||||
+ // Purpur end - Shulker spawn from bullet options
|
||||
if (shulker != null) {
|
||||
shulker.setVariant(this.getVariant());
|
||||
shulker.snapTo(vec3);
|
||||
@@ -565,7 +590,7 @@ public class Shulker extends AbstractGolem implements Enemy {
|
||||
}
|
||||
|
||||
public Optional<DyeColor> getVariant() {
|
||||
- return Optional.ofNullable(this.getColor());
|
||||
+ return Optional.ofNullable(this.level().purpurConfig.shulkerSpawnFromBulletRandomColor ? DyeColor.random(this.level().random) : this.getColor()); // Purpur - Shulker spawn from bullet options
|
||||
}
|
||||
|
||||
public @Nullable DyeColor getColor() {
|
||||
@@ -1,29 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/monster/Strider.java b/net/minecraft/world/entity/monster/Strider.java
|
||||
index b451566378401e471a98db63df502b7c4cd20f42..beaffb771e6c8d4b992437997ab27be218425c5a 100644
|
||||
--- a/net/minecraft/world/entity/monster/Strider.java
|
||||
+++ b/net/minecraft/world/entity/monster/Strider.java
|
||||
@@ -390,6 +390,18 @@ public class Strider extends Animal implements ItemSteerable {
|
||||
@Override
|
||||
public InteractionResult mobInteract(Player player, InteractionHand hand) {
|
||||
boolean isFood = this.isFood(player.getItemInHand(hand));
|
||||
+ // Purpur start
|
||||
+ if (level().purpurConfig.striderGiveSaddleBack && player.isSecondaryUseActive() && !isFood && isSaddled() && !isVehicle()) {
|
||||
+ this.setItemSlot(EquipmentSlot.SADDLE, ItemStack.EMPTY);
|
||||
+ if (!player.getAbilities().instabuild) {
|
||||
+ ItemStack saddle = new ItemStack(Items.SADDLE);
|
||||
+ if (!player.getInventory().add(saddle)) {
|
||||
+ player.drop(saddle, false);
|
||||
+ }
|
||||
+ }
|
||||
+ return InteractionResult.SUCCESS;
|
||||
+ }
|
||||
+ // Purpur end
|
||||
if (!isFood && this.isSaddled() && !this.isVehicle() && !player.isSecondaryUseActive()) {
|
||||
if (!this.level().isClientSide()) {
|
||||
player.startRiding(this);
|
||||
@@ -1,22 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/monster/illager/Vindicator.java b/net/minecraft/world/entity/monster/illager/Vindicator.java
|
||||
index bfad794ff21e2f97654fbb1207b14fd088aec721..0cdc52cf3b1bb9c00e6ca8c8e564de60e195d6fc 100644
|
||||
--- a/net/minecraft/world/entity/monster/illager/Vindicator.java
|
||||
+++ b/net/minecraft/world/entity/monster/illager/Vindicator.java
|
||||
@@ -131,6 +131,11 @@ public class Vindicator extends AbstractIllager {
|
||||
RandomSource random = level.getRandom();
|
||||
this.populateDefaultEquipmentSlots(random, difficulty);
|
||||
this.populateDefaultEquipmentEnchantments(level, random, difficulty);
|
||||
+ // Purpur start - Special mobs naturally spawn
|
||||
+ if (level().purpurConfig.vindicatorJohnnySpawnChance > 0D && random.nextDouble() <= level().purpurConfig.vindicatorJohnnySpawnChance) {
|
||||
+ setCustomName(Component.translatable("Johnny"));
|
||||
+ }
|
||||
+ // Purpur end - Special mobs naturally spawn
|
||||
return spawnGroupData1;
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/monster/piglin/PiglinAi.java b/net/minecraft/world/entity/monster/piglin/PiglinAi.java
|
||||
index 436b17a709517766fdb9d7198f0ae457facd90a1..49294ccf5c4ac3acf7793c8d7cbc449a0d0f44e6 100644
|
||||
--- a/net/minecraft/world/entity/monster/piglin/PiglinAi.java
|
||||
+++ b/net/minecraft/world/entity/monster/piglin/PiglinAi.java
|
||||
@@ -660,7 +660,10 @@ public class PiglinAi {
|
||||
|
||||
public static boolean isWearingSafeArmor(LivingEntity entity) {
|
||||
for (EquipmentSlot equipmentSlot : EquipmentSlotGroup.ARMOR) {
|
||||
- if (entity.getItemBySlot(equipmentSlot).is(ItemTags.PIGLIN_SAFE_ARMOR)) {
|
||||
+ // Purpur start - piglins ignore gold-trimmed armor
|
||||
+ net.minecraft.world.item.ItemStack itemStack = entity.getItemBySlot(equipmentSlot);
|
||||
+ if (itemStack.is(ItemTags.PIGLIN_SAFE_ARMOR) || (entity.level().purpurConfig.piglinIgnoresArmorWithGoldTrim && isWearingGoldTrim(itemStack))) {
|
||||
+ // Purpur end - piglins ignore gold-trimmed armor
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -668,6 +671,13 @@ public class PiglinAi {
|
||||
return false;
|
||||
}
|
||||
|
||||
+ // Purpur start - piglins ignore gold-trimmed armor
|
||||
+ private static boolean isWearingGoldTrim(net.minecraft.world.item.ItemStack itemstack) {
|
||||
+ net.minecraft.world.item.equipment.trim.ArmorTrim armorTrim = itemstack.getComponents().get(net.minecraft.core.component.DataComponents.TRIM);
|
||||
+ return armorTrim != null && armorTrim.material().is(net.minecraft.world.item.equipment.trim.TrimMaterials.GOLD);
|
||||
+ }
|
||||
+ // Purpur end - piglins ignore gold-trimmed armor
|
||||
+
|
||||
private static void stopWalking(Piglin piglin) {
|
||||
piglin.getBrain().eraseMemory(MemoryModuleType.WALK_TARGET);
|
||||
piglin.getNavigation().stop();
|
||||
@@ -1,28 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java b/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java
|
||||
index 0f5bfbfc97c2826de72985c4e2e1dec1d94337f2..1ba7777164c7fd8516c97e1bd964183df37c029f 100644
|
||||
--- a/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java
|
||||
+++ b/net/minecraft/world/entity/monster/skeleton/AbstractSkeleton.java
|
||||
@@ -137,7 +137,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
|
||||
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
|
||||
- if (this.getItemBySlot(EquipmentSlot.HEAD).isEmpty() && SpecialDates.isHalloween() && random.nextFloat() < 0.25F) {
|
||||
+ if (this.getItemBySlot(EquipmentSlot.HEAD).isEmpty() && (level.getLevel().purpurConfig.forceHalloweenSeason || SpecialDates.isHalloween()) && random.nextFloat() < this.level().purpurConfig.chanceHeadHalloweenOnEntity) { // Purpur - Halloween options and optimizations
|
||||
this.setItemSlot(EquipmentSlot.HEAD, new ItemStack(random.nextFloat() < 0.1F ? Blocks.JACK_O_LANTERN : Blocks.CARVED_PUMPKIN));
|
||||
this.setDropChance(EquipmentSlot.HEAD, 0.0F);
|
||||
}
|
||||
@@ -184,7 +184,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
|
||||
double squareRoot = Math.sqrt(d * d + d2 * d2);
|
||||
if (this.level() instanceof ServerLevel serverLevel) {
|
||||
Projectile.Delayed<AbstractArrow> delayedEntity = Projectile.spawnProjectileUsingShootDelayed( // Paper - delayed
|
||||
- arrow, serverLevel, projectile, d, d1 + squareRoot * 0.2F, d2, 1.6F, 14 - serverLevel.getDifficulty().getId() * 4
|
||||
+ arrow, serverLevel, projectile, d, d1 + squareRoot * 0.2F, d2, 1.6F, serverLevel.purpurConfig.skeletonBowAccuracyMap.getOrDefault(serverLevel.getDifficulty().getId(), (float) (14 - serverLevel.getDifficulty().getId() * 4)) // Purpur - skeleton bow accuracy option
|
||||
);
|
||||
|
||||
// Paper start - call EntityShootBowEvent
|
||||
@@ -1,35 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/monster/zombie/Drowned.java b/net/minecraft/world/entity/monster/zombie/Drowned.java
|
||||
index db164101d440c503e2e88b1f31af7f0638faaec5..604d5e6a4962de61fb97988a2f3de2965908bada 100644
|
||||
--- a/net/minecraft/world/entity/monster/zombie/Drowned.java
|
||||
+++ b/net/minecraft/world/entity/monster/zombie/Drowned.java
|
||||
@@ -86,10 +86,23 @@ public class Drowned extends Zombie implements RangedAttackMob {
|
||||
this.goalSelector.addGoal(2, new Drowned.DrownedAttackGoal(this, 1.0, false));
|
||||
this.goalSelector.addGoal(5, new Drowned.DrownedGoToBeachGoal(this, 1.0));
|
||||
this.goalSelector.addGoal(6, new Drowned.DrownedSwimUpGoal(this, 1.0, this.level().getSeaLevel()));
|
||||
+ if (level().purpurConfig.drownedBreakDoors) this.goalSelector.addGoal(6, new net.minecraft.world.entity.ai.goal.MoveThroughVillageGoal(this, 1.0D, true, 4, this::canBreakDoors)); // Purpur - Option to make drowned break doors
|
||||
this.goalSelector.addGoal(7, new RandomStrollGoal(this, 1.0));
|
||||
this.targetSelector.addGoal(1, new HurtByTargetGoal(this, Drowned.class).setAlertOthers(ZombifiedPiglin.class));
|
||||
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (entity, level) -> this.okTarget(entity)));
|
||||
- if (this.level().spigotConfig.zombieAggressiveTowardsVillager) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false)); // Paper - Check drowned for villager aggression config
|
||||
+ // Purpur start - Add option to disable zombie aggressiveness towards villagers
|
||||
+ if (this.level().spigotConfig.zombieAggressiveTowardsVillager) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false) { // Paper - Check drowned for villager aggression config
|
||||
+ @Override
|
||||
+ public boolean canUse() {
|
||||
+ return (level().purpurConfig.zombieAggressiveTowardsVillagerWhenLagging || !level().getServer().server.isLagging()) && super.canUse();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean canContinueToUse() {
|
||||
+ return (level().purpurConfig.zombieAggressiveTowardsVillagerWhenLagging || !level().getServer().server.isLagging()) && super.canContinueToUse();
|
||||
+ }
|
||||
+ });
|
||||
+ // Purpur end - Add option to disable zombie aggressiveness towards villagers
|
||||
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true));
|
||||
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Axolotl.class, true, false));
|
||||
this.targetSelector.addGoal(5, new NearestAttackableTargetGoal<>(this, Turtle.class, 10, true, false, Turtle.BABY_ON_LAND_SELECTOR));
|
||||
@@ -1,23 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/monster/zombie/ZombieVillager.java b/net/minecraft/world/entity/monster/zombie/ZombieVillager.java
|
||||
index 8af935a11a0988f10a2908f6337504f7f6e13d1b..c6f271a921fde124df1a7c5d175cb83b420cd2e3 100644
|
||||
--- a/net/minecraft/world/entity/monster/zombie/ZombieVillager.java
|
||||
+++ b/net/minecraft/world/entity/monster/zombie/ZombieVillager.java
|
||||
@@ -159,10 +159,10 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder {
|
||||
public InteractionResult mobInteract(Player player, InteractionHand hand) {
|
||||
ItemStack itemInHand = player.getItemInHand(hand);
|
||||
if (itemInHand.is(Items.GOLDEN_APPLE)) {
|
||||
- if (this.hasEffect(MobEffects.WEAKNESS)) {
|
||||
+ if (this.hasEffect(MobEffects.WEAKNESS) && level().purpurConfig.zombieVillagerCureEnabled) { // Purpur - Add option to disable zombie villagers cure
|
||||
itemInHand.consume(1, player);
|
||||
if (!this.level().isClientSide()) {
|
||||
- this.startConverting(player.getUUID(), this.random.nextInt(2401) + 3600);
|
||||
+ this.startConverting(player.getUUID(), this.random.nextInt(level().purpurConfig.zombieVillagerCuringTimeMax - level().purpurConfig.zombieVillagerCuringTimeMin + 1) + level().purpurConfig.zombieVillagerCuringTimeMin); // Purpur - Customizable Zombie Villager curing times
|
||||
}
|
||||
|
||||
return InteractionResult.SUCCESS_SERVER;
|
||||
@@ -1,149 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/npc/villager/Villager.java b/net/minecraft/world/entity/npc/villager/Villager.java
|
||||
index 89844d7e804cc8a2110b694e448bc5993991bea7..e117ae1b114c7e2ca314a00335473efc41137f7f 100644
|
||||
--- a/net/minecraft/world/entity/npc/villager/Villager.java
|
||||
+++ b/net/minecraft/world/entity/npc/villager/Villager.java
|
||||
@@ -179,6 +179,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
MemoryModuleType.MEETING_POINT,
|
||||
(villager, poiType) -> poiType.is(PoiTypes.MEETING)
|
||||
);
|
||||
+ private boolean isLobotomized = false; public boolean isLobotomized() { return this.isLobotomized; } // Purpur - Lobotomize stuck villagers
|
||||
+ private int notLobotomizedCount = 0; // Purpur - Lobotomize stuck villagers
|
||||
|
||||
public Villager(EntityType<? extends Villager> type, Level level) {
|
||||
this(type, level, VillagerType.PLAINS);
|
||||
@@ -197,6 +199,57 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
this.setVillagerData(this.getVillagerData().withType(villagerType).withProfession(level.registryAccess(), VillagerProfession.NONE));
|
||||
}
|
||||
|
||||
+ // Purpur start - Allow leashing villagers
|
||||
+ @Override
|
||||
+ public boolean canBeLeashed() {
|
||||
+ return level().purpurConfig.villagerCanBeLeashed;
|
||||
+ }
|
||||
+ // Purpur end - Allow leashing villagers
|
||||
+
|
||||
+ // Purpur start - Lobotomize stuck villagers
|
||||
+ private boolean checkLobotomized() {
|
||||
+ int interval = this.level().purpurConfig.villagerLobotomizeCheckInterval;
|
||||
+ boolean shouldCheckForTradeLocked = this.level().purpurConfig.villagerLobotomizeWaitUntilTradeLocked;
|
||||
+ if (this.notLobotomizedCount > 3) {
|
||||
+ // check half as often if not lobotomized for the last 3+ consecutive checks
|
||||
+ interval *= 2;
|
||||
+ }
|
||||
+ if (this.level().getGameTime() % interval == 0) {
|
||||
+ // offset Y for short blocks like dirt_path/farmland
|
||||
+ this.isLobotomized = !(shouldCheckForTradeLocked && this.getVillagerXp() == 0) && !canTravelFrom(BlockPos.containing(this.position().x, this.getBoundingBox().minY + 0.0625D, this.position().z));
|
||||
+
|
||||
+ if (this.isLobotomized) {
|
||||
+ this.notLobotomizedCount = 0;
|
||||
+ } else {
|
||||
+ this.notLobotomizedCount++;
|
||||
+ }
|
||||
+ }
|
||||
+ return this.isLobotomized;
|
||||
+ }
|
||||
+
|
||||
+ private boolean canTravelFrom(BlockPos pos) {
|
||||
+ return canTravelTo(pos.east()) || canTravelTo(pos.west()) || canTravelTo(pos.north()) || canTravelTo(pos.south());
|
||||
+ }
|
||||
+
|
||||
+ private boolean canTravelTo(BlockPos pos) {
|
||||
+ net.minecraft.world.level.block.state.BlockState state = this.level().getBlockStateIfLoaded(pos);
|
||||
+ if (state == null) {
|
||||
+ // chunk not loaded
|
||||
+ return false;
|
||||
+ }
|
||||
+ net.minecraft.world.level.block.Block bottom = state.getBlock();
|
||||
+ if (bottom instanceof net.minecraft.world.level.block.FenceBlock ||
|
||||
+ bottom instanceof net.minecraft.world.level.block.FenceGateBlock ||
|
||||
+ bottom instanceof net.minecraft.world.level.block.WallBlock) {
|
||||
+ // bottom block is too tall to get over
|
||||
+ return false;
|
||||
+ }
|
||||
+ net.minecraft.world.level.block.Block top = level().getBlockState(pos.above()).getBlock();
|
||||
+ // only if both blocks have no collision
|
||||
+ return !bottom.hasCollision && !top.hasCollision;
|
||||
+ }
|
||||
+ // Purpur end - Lobotomize stuck villagers
|
||||
+
|
||||
@Override
|
||||
public Brain<Villager> getBrain() {
|
||||
return (Brain<Villager>)super.getBrain();
|
||||
@@ -293,11 +346,22 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
// Paper start - EAR 2
|
||||
this.customServerAiStep(level, false);
|
||||
}
|
||||
- protected void customServerAiStep(ServerLevel level, final boolean inactive) {
|
||||
+ protected void customServerAiStep(ServerLevel level, boolean inactive) { // Purpur - Lobotomize stuck villagers - not final
|
||||
// Paper end - EAR 2
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
profilerFiller.push("villagerBrain");
|
||||
- if (!inactive) this.getBrain().tick(level, this); // Paper - EAR 2
|
||||
+ // Purpur start - Lobotomize stuck villagers
|
||||
+ if (this.level().purpurConfig.villagerLobotomizeEnabled) {
|
||||
+ // treat as inactive if lobotomized
|
||||
+ inactive = inactive || checkLobotomized();
|
||||
+ } else {
|
||||
+ this.isLobotomized = false;
|
||||
+ }
|
||||
+ if (!inactive) {
|
||||
+ this.getBrain().tick(level, this); // Paper - EAR 2
|
||||
+ }
|
||||
+ else if (this.isLobotomized && shouldRestock(level)) restock();
|
||||
+ // Purpur end - Lobotomize stuck villagers
|
||||
profilerFiller.pop();
|
||||
if (this.assignProfessionWhenSpawned) {
|
||||
this.assignProfessionWhenSpawned = false;
|
||||
@@ -369,6 +433,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
return InteractionResult.CONSUME;
|
||||
}
|
||||
|
||||
+ if (this.level().purpurConfig.villagerAllowTrading) // Purpur - Add config for villager trading
|
||||
this.startTrading(player);
|
||||
}
|
||||
|
||||
@@ -500,7 +565,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
|
||||
public void updateDemand() {
|
||||
for (MerchantOffer merchantOffer : this.getOffers()) {
|
||||
- merchantOffer.updateDemand();
|
||||
+ merchantOffer.updateDemand(this.level().purpurConfig.villagerMinimumDemand); // Purpur - Configurable minimum demand for trades
|
||||
}
|
||||
}
|
||||
|
||||
@@ -692,7 +757,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
|
||||
@Override
|
||||
public boolean canBreed() {
|
||||
- return this.foodLevel + this.countFoodPointsInInventory() >= 12 && !this.isSleeping() && this.getAge() == 0;
|
||||
+ return this.level().purpurConfig.villagerCanBreed && this.foodLevel + this.countFoodPointsInInventory() >= 12 && !this.isSleeping() && this.getAge() == 0; // Purpur - Configurable villager breeding
|
||||
}
|
||||
|
||||
private boolean hungry() {
|
||||
@@ -915,6 +980,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
}
|
||||
|
||||
public void spawnGolemIfNeeded(ServerLevel level, long gameTime, int minVillagerAmount) {
|
||||
+ if (level.purpurConfig.villagerSpawnIronGolemRadius > 0 && level.getEntitiesOfClass(net.minecraft.world.entity.animal.golem.IronGolem.class, getBoundingBox().inflate(level.purpurConfig.villagerSpawnIronGolemRadius)).size() > level.purpurConfig.villagerSpawnIronGolemLimit) return; // Purpur - Implement configurable search radius for villagers to spawn iron golems
|
||||
if (this.wantsToSpawnGolem(gameTime)) {
|
||||
AABB aabb = this.getBoundingBox().inflate(10.0, 10.0, 10.0);
|
||||
List<Villager> entitiesOfClass = level.getEntitiesOfClass(Villager.class, aabb);
|
||||
@@ -982,6 +1048,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
|
||||
@Override
|
||||
public void startSleeping(BlockPos pos) {
|
||||
+ // Purpur start - Option for beds to explode on villager sleep
|
||||
+ if (level().purpurConfig.bedExplodeOnVillagerSleep && this.level().getBlockState(pos).getBlock() instanceof net.minecraft.world.level.block.BedBlock) {
|
||||
+ this.level().explode(null, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, (float) this.level().purpurConfig.bedExplosionPower, this.level().purpurConfig.bedExplosionFire, this.level().purpurConfig.bedExplosionEffect);
|
||||
+ return;
|
||||
+ }
|
||||
+ // Purpur end - Option for beds to explode on villager sleep
|
||||
super.startSleeping(pos);
|
||||
this.brain.setMemory(MemoryModuleType.LAST_SLEPT, this.level().getGameTime());
|
||||
this.brain.eraseMemory(MemoryModuleType.WALK_TARGET);
|
||||
@@ -1,29 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/npc/wanderingtrader/WanderingTraderSpawner.java b/net/minecraft/world/entity/npc/wanderingtrader/WanderingTraderSpawner.java
|
||||
index 44b43ca9fba989f975133f966cedd582a93d3350..7aef337fc0b6fd52c27ad5ca3f38d74f213d9725 100644
|
||||
--- a/net/minecraft/world/entity/npc/wanderingtrader/WanderingTraderSpawner.java
|
||||
+++ b/net/minecraft/world/entity/npc/wanderingtrader/WanderingTraderSpawner.java
|
||||
@@ -134,7 +134,17 @@ public class WanderingTraderSpawner implements CustomSpawner {
|
||||
int i1 = pos.getX() + this.random.nextInt(maxDistance * 2) - maxDistance;
|
||||
int i2 = pos.getZ() + this.random.nextInt(maxDistance * 2) - maxDistance;
|
||||
int height = level.getHeight(Heightmap.Types.WORLD_SURFACE, i1, i2);
|
||||
- BlockPos blockPos1 = new BlockPos(i1, height, i2);
|
||||
+ // Purpur start - Allow toggling special MobSpawners per world - allow traders to spawn below nether roof
|
||||
+ BlockPos.MutableBlockPos blockPos1 = new BlockPos.MutableBlockPos(i1, height, i2);
|
||||
+ if (level.dimensionType().hasCeiling()) {
|
||||
+ do {
|
||||
+ blockPos1.relative(net.minecraft.core.Direction.DOWN);
|
||||
+ } while (!level.getBlockState(blockPos1).isAir());
|
||||
+ do {
|
||||
+ blockPos1.relative(net.minecraft.core.Direction.DOWN);
|
||||
+ } while (level.getBlockState(blockPos1).isAir() && blockPos1.getY() > 0);
|
||||
+ }
|
||||
+ // Purpur end - Allow toggling special MobSpawners per world
|
||||
if (placementType.isSpawnPositionOk(level, blockPos1, EntityType.WANDERING_TRADER)) {
|
||||
blockPos = blockPos1;
|
||||
break;
|
||||
@@ -1,25 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/inventory/AbstractFurnaceMenu.java b/net/minecraft/world/inventory/AbstractFurnaceMenu.java
|
||||
index 6e13b05ebd924d98066624d9ff6ee7f61e248617..9304bc239ffafbef3b34c5a5a42039c86acd5e80 100644
|
||||
--- a/net/minecraft/world/inventory/AbstractFurnaceMenu.java
|
||||
+++ b/net/minecraft/world/inventory/AbstractFurnaceMenu.java
|
||||
@@ -121,7 +121,13 @@ public abstract class AbstractFurnaceMenu extends RecipeBookMenu {
|
||||
} else if (slotIndex != 1 && slotIndex != 0) {
|
||||
if (this.canSmelt(item)) {
|
||||
if (!this.moveItemStackTo(item, 0, 1, false)) {
|
||||
- return ItemStack.EMPTY;
|
||||
+ // Purpur start - Added the ability to add combustible items
|
||||
+ if (this.isFuel(item)) {
|
||||
+ if (!this.moveItemStackTo(item, 1, 2, false)) {
|
||||
+ return ItemStack.EMPTY;
|
||||
+ }
|
||||
+ }
|
||||
+ // Purpur end - Added the ability to add combustible items
|
||||
}
|
||||
} else if (this.isFuel(item)) {
|
||||
if (!this.moveItemStackTo(item, 1, 2, false)) {
|
||||
@@ -1,204 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/inventory/AnvilMenu.java b/net/minecraft/world/inventory/AnvilMenu.java
|
||||
index 7939f19b87364a32a40e58e001cea14e06348f86..b790b9476ec0a0569470d5de4067caa5373b2f6b 100644
|
||||
--- a/net/minecraft/world/inventory/AnvilMenu.java
|
||||
+++ b/net/minecraft/world/inventory/AnvilMenu.java
|
||||
@@ -23,6 +23,12 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
+// Purpur start - Anvil API
|
||||
+import net.minecraft.network.protocol.game.ClientboundContainerSetDataPacket;
|
||||
+import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
+// Purpur end - Anvil API
|
||||
+
|
||||
public class AnvilMenu extends ItemCombinerMenu {
|
||||
public static final int INPUT_SLOT = 0;
|
||||
public static final int ADDITIONAL_SLOT = 1;
|
||||
@@ -51,6 +57,10 @@ public class AnvilMenu extends ItemCombinerMenu {
|
||||
private org.bukkit.craftbukkit.inventory.view.CraftAnvilView bukkitEntity;
|
||||
// CraftBukkit end
|
||||
public boolean bypassEnchantmentLevelRestriction = false; // Paper - bypass anvil level restrictions
|
||||
+ // Purpur start - Anvil API
|
||||
+ public boolean bypassCost = false;
|
||||
+ public boolean canDoUnsafeEnchants = false;
|
||||
+ // Purpur end - Anvil API
|
||||
|
||||
public AnvilMenu(int containerId, Inventory playerInventory) {
|
||||
this(containerId, playerInventory, ContainerLevelAccess.NULL);
|
||||
@@ -76,12 +86,17 @@ public class AnvilMenu extends ItemCombinerMenu {
|
||||
|
||||
@Override
|
||||
protected boolean mayPickup(Player player, boolean hasStack) {
|
||||
- return (player.hasInfiniteMaterials() || player.experienceLevel >= this.cost.get()) && this.cost.get() > AnvilMenu.DEFAULT_DENIED_COST && hasStack; // CraftBukkit - allow cost 0 like a free item
|
||||
+ return (player.hasInfiniteMaterials() || player.experienceLevel >= this.cost.get()) && (this.bypassCost || this.cost.get() > AnvilMenu.DEFAULT_DENIED_COST) && hasStack; // CraftBukkit - allow cost 0 like a free item // Purpur - Anvil API
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTake(Player player, ItemStack stack) {
|
||||
+ // Purpur start - Anvil API
|
||||
+ ItemStack itemstack = this.activeQuickItem != null ? this.activeQuickItem : stack;
|
||||
+ if (org.purpurmc.purpur.event.inventory.AnvilTakeResultEvent.getHandlerList().getRegisteredListeners().length > 0) new org.purpurmc.purpur.event.inventory.AnvilTakeResultEvent(player.getBukkitEntity(), getBukkitView(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)).callEvent();
|
||||
+ // Purpur end - Anvil API
|
||||
if (!player.hasInfiniteMaterials()) {
|
||||
+ if (this.bypassCost) ((ServerPlayer) player).lastSentExp = -1; else // Purpur - Anvil API
|
||||
player.giveExperienceLevels(-this.cost.get());
|
||||
}
|
||||
|
||||
@@ -134,13 +149,19 @@ public class AnvilMenu extends ItemCombinerMenu {
|
||||
|
||||
@Override
|
||||
public void createResult() {
|
||||
+ // Purpur start - Anvil API
|
||||
+ this.bypassCost = false;
|
||||
+ this.canDoUnsafeEnchants = false;
|
||||
+ if (org.purpurmc.purpur.event.inventory.AnvilUpdateResultEvent.getHandlerList().getRegisteredListeners().length > 0) new org.purpurmc.purpur.event.inventory.AnvilUpdateResultEvent(getBukkitView()).callEvent();
|
||||
+ // Purpur end - Anvil API
|
||||
+
|
||||
ItemStack item = this.inputSlots.getItem(0);
|
||||
this.onlyRenaming = false;
|
||||
this.cost.set(1);
|
||||
int i = 0;
|
||||
long l = 0L;
|
||||
int i1 = 0;
|
||||
- if (!item.isEmpty() && EnchantmentHelper.canStoreEnchantments(item)) {
|
||||
+ if (!item.isEmpty() && this.canDoUnsafeEnchants || EnchantmentHelper.canStoreEnchantments(item)) { // Purpur - Anvil API
|
||||
ItemStack itemStack = item.copy();
|
||||
ItemStack item1 = this.inputSlots.getItem(1);
|
||||
ItemEnchantments.Mutable mutable = new ItemEnchantments.Mutable(EnchantmentHelper.getEnchantmentsForCrafting(itemStack));
|
||||
@@ -198,23 +219,34 @@ public class AnvilMenu extends ItemCombinerMenu {
|
||||
int intValue = entry.getIntValue();
|
||||
intValue = level == intValue ? intValue + 1 : Math.max(intValue, level);
|
||||
Enchantment enchantment = holder.value();
|
||||
- boolean canEnchant = enchantment.canEnchant(item);
|
||||
+ // Purpur start - Config to allow unsafe enchants
|
||||
+ boolean canEnchant = this.canDoUnsafeEnchants || org.purpurmc.purpur.PurpurConfig.allowInapplicableEnchants || enchantment.canEnchant(item); // whether the enchantment can be applied on specific item type
|
||||
+ boolean canEnchant1 = true; // whether two incompatible enchantments can be applied on a single item
|
||||
+ // Purpur end - Config to allow unsafe enchants
|
||||
if (this.player.hasInfiniteMaterials() || item.is(Items.ENCHANTED_BOOK)) {
|
||||
canEnchant = true;
|
||||
}
|
||||
|
||||
+ java.util.Set<Holder<Enchantment>> removedEnchantments = new java.util.HashSet<>(); // Purpur - Config to allow unsafe enchants
|
||||
for (Holder<Enchantment> holder1 : mutable.keySet()) {
|
||||
if (!holder1.equals(holder) && !Enchantment.areCompatible(holder, holder1)) {
|
||||
- canEnchant = false;
|
||||
+ canEnchant1 = this.canDoUnsafeEnchants || org.purpurmc.purpur.PurpurConfig.allowIncompatibleEnchants; // Purpur - Anvil API // Purpur - canEnchant -> canEnchant1 - Config to allow unsafe enchants
|
||||
+ // Purpur start - Config to allow unsafe enchants
|
||||
+ if (!canEnchant1 && org.purpurmc.purpur.PurpurConfig.replaceIncompatibleEnchants) {
|
||||
+ removedEnchantments.add(holder1);
|
||||
+ canEnchant1 = true;
|
||||
+ }
|
||||
+ // Purpur end - Config to allow unsafe enchants
|
||||
i++;
|
||||
}
|
||||
}
|
||||
+ mutable.removeIf(removedEnchantments::contains); // Purpur - Config to allow unsafe enchants
|
||||
|
||||
- if (!canEnchant) {
|
||||
+ if (!canEnchant || !canEnchant1) { // Purpur - Config to allow unsafe enchants
|
||||
flag1 = true;
|
||||
} else {
|
||||
flag = true;
|
||||
- if (intValue > enchantment.getMaxLevel() && !this.bypassEnchantmentLevelRestriction) { // Paper - bypass anvil level restrictions
|
||||
+ if (!org.purpurmc.purpur.PurpurConfig.allowHigherEnchantsLevels && intValue > enchantment.getMaxLevel() && !this.bypassEnchantmentLevelRestriction) { // Paper - bypass anvil level restrictions // Purpur - Config to allow unsafe enchants
|
||||
intValue = enchantment.getMaxLevel();
|
||||
}
|
||||
|
||||
@@ -243,6 +275,54 @@ public class AnvilMenu extends ItemCombinerMenu {
|
||||
if (!this.itemName.equals(item.getHoverName().getString())) {
|
||||
i1 = 1;
|
||||
i += i1;
|
||||
+ // Purpur start - Allow anvil colors
|
||||
+ if (this.player != null) {
|
||||
+ org.bukkit.craftbukkit.entity.CraftHumanEntity player = this.player.getBukkitEntity();
|
||||
+ String name = this.itemName;
|
||||
+ boolean removeItalics = false;
|
||||
+ if (player.hasPermission("purpur.anvil.remove_italics")) {
|
||||
+ if (name.startsWith("&r")) {
|
||||
+ name = name.substring(2);
|
||||
+ removeItalics = true;
|
||||
+ } else if (name.startsWith("<r>")) {
|
||||
+ name = name.substring(3);
|
||||
+ removeItalics = true;
|
||||
+ } else if (name.startsWith("<reset>")) {
|
||||
+ name = name.substring(7);
|
||||
+ removeItalics = true;
|
||||
+ }
|
||||
+ }
|
||||
+ if (this.player.level().purpurConfig.anvilAllowColors) {
|
||||
+ if (player.hasPermission("purpur.anvil.color")) {
|
||||
+ java.util.regex.Matcher matcher = java.util.regex.Pattern.compile("(?i)&([0-9a-fr])").matcher(name);
|
||||
+ while (matcher.find()) {
|
||||
+ String match = matcher.group(1);
|
||||
+ name = name.replace("&" + match, "\u00a7" + match.toLowerCase(java.util.Locale.ROOT));
|
||||
+ }
|
||||
+ //name = name.replaceAll("(?i)&([0-9a-fr])", "\u00a7$1");
|
||||
+ }
|
||||
+ if (player.hasPermission("purpur.anvil.format")) {
|
||||
+ java.util.regex.Matcher matcher = java.util.regex.Pattern.compile("(?i)&([k-or])").matcher(name);
|
||||
+ while (matcher.find()) {
|
||||
+ String match = matcher.group(1);
|
||||
+ name = name.replace("&" + match, "\u00a7" + match.toLowerCase(java.util.Locale.ROOT));
|
||||
+ }
|
||||
+ //name = name.replaceAll("(?i)&([l-or])", "\u00a7$1");
|
||||
+ }
|
||||
+ }
|
||||
+ net.kyori.adventure.text.Component component;
|
||||
+ if (this.player.level().purpurConfig.anvilColorsUseMiniMessage && player.hasPermission("purpur.anvil.minimessage")) {
|
||||
+ component = net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.bukkit.ChatColor.stripColor(name));
|
||||
+ } else {
|
||||
+ component = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(name);
|
||||
+ }
|
||||
+ if (removeItalics) {
|
||||
+ component = component.decoration(net.kyori.adventure.text.format.TextDecoration.ITALIC, false);
|
||||
+ }
|
||||
+ itemStack.set(DataComponents.CUSTOM_NAME, io.papermc.paper.adventure.PaperAdventure.asVanilla(component));
|
||||
+ }
|
||||
+ else
|
||||
+ // Purpur end - Allow anvil colors
|
||||
itemStack.set(DataComponents.CUSTOM_NAME, Component.literal(this.itemName));
|
||||
}
|
||||
} else if (item.has(DataComponents.CUSTOM_NAME)) {
|
||||
@@ -267,6 +347,12 @@ public class AnvilMenu extends ItemCombinerMenu {
|
||||
this.onlyRenaming = true;
|
||||
}
|
||||
|
||||
+ // Purpur start - Anvil API
|
||||
+ if (this.bypassCost && this.cost.get() >= this.maximumRepairCost) {
|
||||
+ this.cost.set(this.maximumRepairCost - 1);
|
||||
+ }
|
||||
+ // Purpur end - Anvil API
|
||||
+
|
||||
if (this.cost.get() >= this.maximumRepairCost && !this.player.hasInfiniteMaterials()) { // CraftBukkit
|
||||
itemStack = ItemStack.EMPTY;
|
||||
}
|
||||
@@ -287,6 +373,13 @@ public class AnvilMenu extends ItemCombinerMenu {
|
||||
|
||||
org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(this.getBukkitView(), itemStack); // CraftBukkit
|
||||
this.broadcastChanges();
|
||||
+
|
||||
+ // Purpur start - Anvil API
|
||||
+ if ((this.canDoUnsafeEnchants || org.purpurmc.purpur.PurpurConfig.allowInapplicableEnchants || org.purpurmc.purpur.PurpurConfig.allowIncompatibleEnchants) && itemStack != ItemStack.EMPTY) { // Purpur - Config to allow unsafe enchants
|
||||
+ ((ServerPlayer) this.player).connection.send(new ClientboundContainerSetSlotPacket(this.containerId, this.incrementStateId(), 2, itemStack));
|
||||
+ ((ServerPlayer) this.player).connection.send(new ClientboundContainerSetDataPacket(this.containerId, 0, this.cost.get()));
|
||||
+ }
|
||||
+ // Purpur end - Anvil API
|
||||
} else {
|
||||
org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(this.getBukkitView(), ItemStack.EMPTY); // CraftBukkit
|
||||
this.cost.set(AnvilMenu.DEFAULT_DENIED_COST); // CraftBukkit - use a variable for set a cost for denied item
|
||||
@@ -295,7 +388,7 @@ public class AnvilMenu extends ItemCombinerMenu {
|
||||
}
|
||||
|
||||
public static int calculateIncreasedRepairCost(int oldRepairCost) {
|
||||
- return (int)Math.min(oldRepairCost * 2L + 1L, 2147483647L);
|
||||
+ return org.purpurmc.purpur.PurpurConfig.anvilCumulativeCost ? (int)Math.min(oldRepairCost * 2L + 1L, 2147483647L) : 0; // Purpur - Make anvil cumulative cost configurable
|
||||
}
|
||||
|
||||
public boolean setItemName(String itemName) {
|
||||
@@ -1,19 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/inventory/ArmorSlot.java b/net/minecraft/world/inventory/ArmorSlot.java
|
||||
index f9fef56709a40e2581170a807a0035b593795b05..cdc95952311e6a2df757c3d8ec1224e3e5ad3069 100644
|
||||
--- a/net/minecraft/world/inventory/ArmorSlot.java
|
||||
+++ b/net/minecraft/world/inventory/ArmorSlot.java
|
||||
@@ -46,7 +46,7 @@ class ArmorSlot extends Slot {
|
||||
@Override
|
||||
public boolean mayPickup(Player player) {
|
||||
ItemStack item = this.getItem();
|
||||
- return (item.isEmpty() || player.isCreative() || !EnchantmentHelper.has(item, EnchantmentEffectComponents.PREVENT_ARMOR_CHANGE))
|
||||
+ return (item.isEmpty() || player.isCreative() || (!EnchantmentHelper.has(item, EnchantmentEffectComponents.PREVENT_ARMOR_CHANGE) || player.level().purpurConfig.playerRemoveBindingWithWeakness && player.hasEffect(net.minecraft.world.effect.MobEffects.WEAKNESS))) // Purpur - Config to remove curse of binding with weakness
|
||||
&& super.mayPickup(player);
|
||||
}
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/inventory/EnchantmentMenu.java b/net/minecraft/world/inventory/EnchantmentMenu.java
|
||||
index 385eecd0c59d3c9510e39f96aa9614a7a57fb65a..40860d2facd6720300793dcc2cf99cb3367e61f7 100644
|
||||
--- a/net/minecraft/world/inventory/EnchantmentMenu.java
|
||||
+++ b/net/minecraft/world/inventory/EnchantmentMenu.java
|
||||
@@ -63,6 +63,22 @@ public class EnchantmentMenu extends AbstractContainerMenu {
|
||||
return access.getLocation();
|
||||
}
|
||||
// CraftBukkit end
|
||||
+
|
||||
+ // Purpur start - Enchantment Table Persists Lapis
|
||||
+ @Override
|
||||
+ public void onClose(org.bukkit.craftbukkit.entity.CraftHumanEntity who) {
|
||||
+ super.onClose(who);
|
||||
+
|
||||
+ if (who.getHandle().level().purpurConfig.enchantmentTableLapisPersists) {
|
||||
+ access.execute((level, pos) -> {
|
||||
+ net.minecraft.world.level.block.entity.BlockEntity blockEntity = level.getBlockEntity(pos);
|
||||
+ if (blockEntity instanceof net.minecraft.world.level.block.entity.EnchantingTableBlockEntity enchantmentTable) {
|
||||
+ enchantmentTable.setLapis(this.getItem(1).getCount());
|
||||
+ }
|
||||
+ });
|
||||
+ }
|
||||
+ }
|
||||
+ // Purpur end - Enchantment Table Persists Lapis
|
||||
};
|
||||
// Paper end - Add missing InventoryHolders
|
||||
this.access = access;
|
||||
@@ -83,6 +99,16 @@ public class EnchantmentMenu extends AbstractContainerMenu {
|
||||
return EnchantmentMenu.EMPTY_SLOT_LAPIS_LAZULI;
|
||||
}
|
||||
});
|
||||
+ // Purpur start - Enchantment Table Persists Lapis
|
||||
+ access.execute((level, pos) -> {
|
||||
+ if (level.purpurConfig.enchantmentTableLapisPersists) {
|
||||
+ net.minecraft.world.level.block.entity.BlockEntity blockEntity = level.getBlockEntity(pos);
|
||||
+ if (blockEntity instanceof net.minecraft.world.level.block.entity.EnchantingTableBlockEntity enchantmentTable) {
|
||||
+ this.getSlot(1).set(new ItemStack(Items.LAPIS_LAZULI, enchantmentTable.getLapis()));
|
||||
+ }
|
||||
+ }
|
||||
+ });
|
||||
+ // Purpur end - Enchantment Table Persists Lapis
|
||||
this.addStandardInventorySlots(playerInventory, 8, 84);
|
||||
this.addDataSlot(DataSlot.shared(this.costs, 0));
|
||||
this.addDataSlot(DataSlot.shared(this.costs, 1));
|
||||
@@ -299,7 +325,7 @@ public class EnchantmentMenu extends AbstractContainerMenu {
|
||||
@Override
|
||||
public void removed(Player player) {
|
||||
super.removed(player);
|
||||
- this.access.execute((level, pos) -> this.clearContainer(player, this.enchantSlots));
|
||||
+ this.access.execute((level, pos) -> {if (level.purpurConfig.enchantmentTableLapisPersists) this.getSlot(1).set(ItemStack.EMPTY);this.clearContainer(player, this.enchantSlots);}); // Purpur - Enchantment Table Persists Lapis
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,146 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/inventory/GrindstoneMenu.java b/net/minecraft/world/inventory/GrindstoneMenu.java
|
||||
index ad70a0f7debee27d9f3b2ff39cb0429b39485190..e991ca16d069fddc3e4eb6d8c78c0dbffeb75a54 100644
|
||||
--- a/net/minecraft/world/inventory/GrindstoneMenu.java
|
||||
+++ b/net/minecraft/world/inventory/GrindstoneMenu.java
|
||||
@@ -92,11 +92,13 @@ public class GrindstoneMenu extends AbstractContainerMenu {
|
||||
@Override
|
||||
public void onTake(Player player, ItemStack stack) {
|
||||
access.execute((level, blockPos) -> {
|
||||
+ ItemStack itemstack = activeQuickItem == null ? stack : activeQuickItem; // Purpur - Grindstone API
|
||||
if (level instanceof ServerLevel) {
|
||||
// Paper start - Fire BlockExpEvent on grindstone use
|
||||
org.bukkit.event.block.BlockExpEvent event = new org.bukkit.event.block.BlockExpEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, blockPos), this.getExperienceAmount(level));
|
||||
event.callEvent();
|
||||
- ExperienceOrb.awardWithDirection((ServerLevel) level, Vec3.atCenterOf(blockPos), Vec3.ZERO, event.getExpToDrop(), org.bukkit.entity.ExperienceOrb.SpawnReason.GRINDSTONE, player, null);
|
||||
+ org.purpurmc.purpur.event.inventory.GrindstoneTakeResultEvent grindstoneTakeResultEvent = new org.purpurmc.purpur.event.inventory.GrindstoneTakeResultEvent(player.getBukkitEntity(), getBukkitView(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), event.getExpToDrop()); grindstoneTakeResultEvent.callEvent(); // Purpur - Grindstone API
|
||||
+ ExperienceOrb.awardWithDirection((ServerLevel) level, Vec3.atCenterOf(blockPos), Vec3.ZERO, grindstoneTakeResultEvent.getExperienceAmount(), org.bukkit.entity.ExperienceOrb.SpawnReason.GRINDSTONE, player, null); // Purpur - Grindstone API
|
||||
// Paper end - Fire BlockExpEvent on grindstone use
|
||||
}
|
||||
|
||||
@@ -125,7 +127,7 @@ public class GrindstoneMenu extends AbstractContainerMenu {
|
||||
for (Entry<Holder<Enchantment>> entry : enchantmentsForCrafting.entrySet()) {
|
||||
Holder<Enchantment> holder = entry.getKey();
|
||||
int intValue = entry.getIntValue();
|
||||
- if (!holder.is(EnchantmentTags.CURSE)) {
|
||||
+ if (!org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(holder.value())) { // Purpur - Config for grindstones
|
||||
i += holder.value().getMinCost(intValue);
|
||||
}
|
||||
}
|
||||
@@ -203,15 +205,75 @@ public class GrindstoneMenu extends AbstractContainerMenu {
|
||||
|
||||
for (Entry<Holder<Enchantment>> entry : enchantmentsForCrafting.entrySet()) {
|
||||
Holder<Enchantment> holder = entry.getKey();
|
||||
- if (!holder.is(EnchantmentTags.CURSE) || mutable.getLevel(holder) == 0) {
|
||||
+ if (!org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(holder.value()) || mutable.getLevel(holder) == 0) { // Purpur - Config for grindstones
|
||||
mutable.upgrade(holder, entry.getIntValue());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+ // Purpur start - Config for grindstones
|
||||
+ private java.util.List<net.minecraft.core.component.DataComponentType<?>> GRINDSTONE_REMOVE_ATTRIBUTES_REMOVAL_LIST = java.util.List.of(
|
||||
+ // DataComponents.MAX_STACK_SIZE,
|
||||
+ // DataComponents.DAMAGE,
|
||||
+ // DataComponents.BLOCK_STATE,
|
||||
+ DataComponents.CUSTOM_DATA,
|
||||
+ // DataComponents.MAX_DAMAGE,
|
||||
+ // DataComponents.UNBREAKABLE,
|
||||
+ // DataComponents.CUSTOM_NAME,
|
||||
+ // DataComponents.ITEM_NAME,
|
||||
+ // DataComponents.LORE,
|
||||
+ // DataComponents.RARITY,
|
||||
+ // DataComponents.ENCHANTMENTS,
|
||||
+ // DataComponents.CAN_PLACE_ON,
|
||||
+ // DataComponents.CAN_BREAK,
|
||||
+ DataComponents.ATTRIBUTE_MODIFIERS,
|
||||
+ DataComponents.CUSTOM_MODEL_DATA,
|
||||
+ // DataComponents.HIDE_ADDITIONAL_TOOLTIP,
|
||||
+ // DataComponents.HIDE_TOOLTIP,
|
||||
+ // DataComponents.REPAIR_COST,
|
||||
+ // DataComponents.CREATIVE_SLOT_LOCK,
|
||||
+ // DataComponents.ENCHANTMENT_GLINT_OVERRIDE,
|
||||
+ // DataComponents.INTANGIBLE_PROJECTILE,
|
||||
+ // DataComponents.FOOD,
|
||||
+ // DataComponents.FIRE_RESISTANT,
|
||||
+ // DataComponents.TOOL,
|
||||
+ // DataComponents.STORED_ENCHANTMENTS,
|
||||
+ DataComponents.DYED_COLOR,
|
||||
+ // DataComponents.MAP_COLOR,
|
||||
+ // DataComponents.MAP_ID,
|
||||
+ // DataComponents.MAP_DECORATIONS,
|
||||
+ // DataComponents.MAP_POST_PROCESSING,
|
||||
+ // DataComponents.CHARGED_PROJECTILES,
|
||||
+ // DataComponents.BUNDLE_CONTENTS,
|
||||
+ // DataComponents.POTION_CONTENTS,
|
||||
+ DataComponents.SUSPICIOUS_STEW_EFFECTS
|
||||
+ // DataComponents.WRITABLE_BOOK_CONTENT,
|
||||
+ // DataComponents.WRITTEN_BOOK_CONTENT,
|
||||
+ // DataComponents.TRIM,
|
||||
+ // DataComponents.DEBUG_STICK_STATE,
|
||||
+ // DataComponents.ENTITY_DATA,
|
||||
+ // DataComponents.BUCKET_ENTITY_DATA,
|
||||
+ // DataComponents.BLOCK_ENTITY_DATA,
|
||||
+ // DataComponents.INSTRUMENT,
|
||||
+ // DataComponents.OMINOUS_BOTTLE_AMPLIFIER,
|
||||
+ // DataComponents.RECIPES,
|
||||
+ // DataComponents.LODESTONE_TRACKER,
|
||||
+ // DataComponents.FIREWORK_EXPLOSION,
|
||||
+ // DataComponents.FIREWORKS,
|
||||
+ // DataComponents.PROFILE,
|
||||
+ // DataComponents.NOTE_BLOCK_SOUND,
|
||||
+ // DataComponents.BANNER_PATTERNS,
|
||||
+ // DataComponents.BASE_COLOR,
|
||||
+ // DataComponents.POT_DECORATIONS,
|
||||
+ // DataComponents.CONTAINER,
|
||||
+ // DataComponents.BEES,
|
||||
+ // DataComponents.LOCK,
|
||||
+ // DataComponents.CONTAINER_LOOT,
|
||||
+ );
|
||||
+ // Purpur end - Config for grindstones
|
||||
private ItemStack removeNonCursesFrom(ItemStack item) {
|
||||
- ItemEnchantments itemEnchantments = EnchantmentHelper.updateEnchantments(item, mutable -> mutable.removeIf(holder -> !holder.is(EnchantmentTags.CURSE)));
|
||||
+ ItemEnchantments itemEnchantments = EnchantmentHelper.updateEnchantments(item, mutable -> mutable.removeIf(holder -> !org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(holder.value()))); // Purpur - Config for grindstones
|
||||
if (item.is(Items.ENCHANTED_BOOK) && itemEnchantments.isEmpty()) {
|
||||
item = item.transmuteCopy(Items.BOOK);
|
||||
}
|
||||
@@ -223,6 +285,23 @@ public class GrindstoneMenu extends AbstractContainerMenu {
|
||||
}
|
||||
|
||||
item.set(DataComponents.REPAIR_COST, i);
|
||||
+
|
||||
+ // Purpur start - Config for grindstones
|
||||
+ net.minecraft.core.component.DataComponentPatch.Builder builder = net.minecraft.core.component.DataComponentPatch.builder();
|
||||
+ if (org.purpurmc.purpur.PurpurConfig.grindstoneRemoveAttributes) {
|
||||
+ item.getComponents().forEach(typedDataComponent -> {
|
||||
+ if (GRINDSTONE_REMOVE_ATTRIBUTES_REMOVAL_LIST.contains(typedDataComponent.type())) {
|
||||
+ builder.remove(typedDataComponent.type());
|
||||
+ }
|
||||
+ });
|
||||
+ }
|
||||
+ if (org.purpurmc.purpur.PurpurConfig.grindstoneRemoveDisplay) {
|
||||
+ builder.remove(DataComponents.CUSTOM_NAME);
|
||||
+ builder.remove(DataComponents.LORE);
|
||||
+ }
|
||||
+ item.applyComponents(builder.build());
|
||||
+ // Purpur end - Config for grindstones
|
||||
+
|
||||
return item;
|
||||
}
|
||||
|
||||
@@ -279,7 +358,9 @@ public class GrindstoneMenu extends AbstractContainerMenu {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
+ this.activeQuickItem = itemStack; // Purpur - Grindstone API
|
||||
slot.onTake(player, item);
|
||||
+ this.activeQuickItem = null; // Purpur - Grindstone API
|
||||
}
|
||||
|
||||
return itemStack;
|
||||
@@ -1,20 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/inventory/ItemCombinerMenu.java b/net/minecraft/world/inventory/ItemCombinerMenu.java
|
||||
index 1296631fc74e83e6c9d6af0cd46d12d9851a30b1..e6c3a0086963298be31befbbbf8d42e85f379c79 100644
|
||||
--- a/net/minecraft/world/inventory/ItemCombinerMenu.java
|
||||
+++ b/net/minecraft/world/inventory/ItemCombinerMenu.java
|
||||
@@ -156,7 +156,9 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
+ this.activeQuickItem = itemStack; // Purpur - Anvil API
|
||||
slot.onTake(player, item);
|
||||
+ this.activeQuickItem = null; // Purpur - Anvil API
|
||||
}
|
||||
|
||||
return itemStack;
|
||||
@@ -1,57 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/FarmBlock.java b/net/minecraft/world/level/block/FarmBlock.java
|
||||
index da822a89e134e98696308315799d872944e7712f..75b38812b538e0938bbbde62427fa9fd23d372a1 100644
|
||||
--- a/net/minecraft/world/level/block/FarmBlock.java
|
||||
+++ b/net/minecraft/world/level/block/FarmBlock.java
|
||||
@@ -112,7 +112,7 @@ public class FarmBlock extends Block {
|
||||
public void fallOn(Level level, BlockState state, BlockPos pos, Entity entity, double fallDistance) {
|
||||
super.fallOn(level, state, pos, entity, fallDistance); // CraftBukkit - moved here as game rules / events shouldn't affect fall damage.
|
||||
if (level instanceof ServerLevel serverLevel
|
||||
- && level.random.nextFloat() < fallDistance - 0.5
|
||||
+ && (serverLevel.purpurConfig.farmlandTrampleHeight >= 0D ? fallDistance >= serverLevel.purpurConfig.farmlandTrampleHeight : level.random.nextFloat() < fallDistance - 0.5) // Purpur - Configurable farmland trample height
|
||||
&& entity instanceof LivingEntity
|
||||
&& (entity instanceof Player || serverLevel.getGameRules().get(GameRules.MOB_GRIEFING))
|
||||
&& entity.getBbWidth() * entity.getBbWidth() * entity.getBbHeight() > 0.512F) {
|
||||
@@ -129,6 +129,28 @@ public class FarmBlock extends Block {
|
||||
return;
|
||||
}
|
||||
|
||||
+ if (level.purpurConfig.farmlandTramplingDisabled) return; // Purpur - Farmland trampling changes
|
||||
+ if (level.purpurConfig.farmlandTramplingOnlyPlayers && !(entity instanceof Player)) return; // Purpur - Farmland trampling changes
|
||||
+
|
||||
+ // Purpur start - Ability to re-add farmland mechanics from Alpha
|
||||
+ if (level.purpurConfig.farmlandAlpha) {
|
||||
+ Block block = level.getBlockState(pos.below()).getBlock();
|
||||
+ if (block instanceof FenceBlock || block instanceof WallBlock) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // Purpur end - Ability to re-add farmland mechanics from Alpha
|
||||
+
|
||||
+ // Purpur start - Farmland trampling changes
|
||||
+ if (level.purpurConfig.farmlandTramplingFeatherFalling) {
|
||||
+ net.minecraft.world.item.ItemStack bootsItem = ((net.minecraft.world.entity.LivingEntity) entity).getItemBySlot(net.minecraft.world.entity.EquipmentSlot.FEET);
|
||||
+
|
||||
+ if (bootsItem != net.minecraft.world.item.ItemStack.EMPTY && net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.FEATHER_FALLING, bootsItem) >= (int) entity.fallDistance) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // Purpur end - Farmland trampling changes
|
||||
+
|
||||
if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.DIRT.defaultBlockState())) {
|
||||
return;
|
||||
}
|
||||
@@ -177,7 +199,7 @@ public class FarmBlock extends Block {
|
||||
}
|
||||
}
|
||||
|
||||
- return false;
|
||||
+ return ((ServerLevel) level).purpurConfig.farmlandGetsMoistFromBelow && level.getFluidState(pos.relative(Direction.DOWN)).is(FluidTags.WATER); // Purpur - Allow soil to moisten from water directly under it
|
||||
// Paper end - Perf: remove abstract block iteration
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
index 1215ac44fd30dc872f9d319be34e5e08ba880ea2..c0bb687b94f3baa9ffda9c47c69a1d6d244acd4e 100644
|
||||
--- a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
@@ -187,6 +187,21 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
||||
}
|
||||
|
||||
ItemStack itemStack = furnace.items.get(1);
|
||||
+ // Purpur start - Furnace uses lava from underneath
|
||||
+ boolean usedLavaFromUnderneath = false;
|
||||
+ if (level.purpurConfig.furnaceUseLavaFromUnderneath && !furnace.isLit() && itemStack.isEmpty() && !furnace.items.get(0).isEmpty() && level.getGameTime() % 20 == 0) {
|
||||
+ BlockPos below = furnace.getBlockPos().below();
|
||||
+ BlockState belowState = level.getBlockStateIfLoaded(below);
|
||||
+ if (belowState != null && belowState.is(Blocks.LAVA)) {
|
||||
+ net.minecraft.world.level.material.FluidState fluidState = belowState.getFluidState();
|
||||
+ if (fluidState != null && fluidState.isSource()) {
|
||||
+ level.setBlock(below, Blocks.AIR.defaultBlockState(), 3);
|
||||
+ itemStack = Items.LAVA_BUCKET.getDefaultInstance();
|
||||
+ usedLavaFromUnderneath = true;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Purpur end - Furnace uses lava from underneath
|
||||
ItemStack itemStack1 = furnace.items.get(0);
|
||||
boolean flag1 = !itemStack1.isEmpty();
|
||||
boolean flag2 = !itemStack.isEmpty();
|
||||
@@ -270,6 +285,8 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
||||
if (flag) {
|
||||
setChanged(level, pos, state);
|
||||
}
|
||||
+
|
||||
+ if (usedLavaFromUnderneath) furnace.items.set(1, ItemStack.EMPTY); // Purpur - Furnace uses lava from underneath
|
||||
}
|
||||
|
||||
private static boolean canBurn(
|
||||
@@ -1,66 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
|
||||
index 0db33d7e1227e914326e9eb3b50338b001872938..cc301cff64e1bf604a1432f6e36be8aa17db53e7 100644
|
||||
--- a/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
|
||||
@@ -138,6 +138,16 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
|
||||
|
||||
public double getEffectRange() {
|
||||
if (this.effectRange < 0) {
|
||||
+ // Purpur start - Beacon Activation Range Configurable
|
||||
+ if (this.level != null) {
|
||||
+ switch (this.levels) {
|
||||
+ case 1: return this.level.purpurConfig.beaconLevelOne;
|
||||
+ case 2: return this.level.purpurConfig.beaconLevelTwo;
|
||||
+ case 3: return this.level.purpurConfig.beaconLevelThree;
|
||||
+ case 4: return this.level.purpurConfig.beaconLevelFour;
|
||||
+ }
|
||||
+ }
|
||||
+ // Purpur end - Beacon Activation Range Configurable
|
||||
return this.levels * 10 + 10;
|
||||
} else {
|
||||
return effectRange;
|
||||
@@ -166,6 +176,7 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
|
||||
int y = pos.getY();
|
||||
int z = pos.getZ();
|
||||
BlockPos blockPos;
|
||||
+ boolean isTintedGlass = false; // Purpur - allow beacon effects when covered by tinted glass
|
||||
if (blockEntity.lastCheckY < y) {
|
||||
blockPos = pos;
|
||||
blockEntity.checkingBeamSections = Lists.newArrayList();
|
||||
@@ -195,11 +206,15 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
|
||||
}
|
||||
}
|
||||
} else {
|
||||
- if (section == null || blockState.getLightBlock() >= 15 && !blockState.is(Blocks.BEDROCK)) {
|
||||
+ if (level.purpurConfig.beaconAllowEffectsWithTintedGlass && blockState.getBlock().equals(Blocks.TINTED_GLASS)) {isTintedGlass = true;} // Purpur - allow beacon effects when covered by tinted glass
|
||||
+ // Purpur start - fix effects being applied when tinted glass is covered
|
||||
+ if (section == null || blockState.getLightBlock() >= 15 && !blockState.is(Blocks.BEDROCK) && !(blockState.getBlock().equals(Blocks.TINTED_GLASS) && level.purpurConfig.beaconAllowEffectsWithTintedGlass)) {
|
||||
blockEntity.checkingBeamSections.clear();
|
||||
blockEntity.lastCheckY = height;
|
||||
+ isTintedGlass = false;
|
||||
break;
|
||||
}
|
||||
+ // Purpur end - fix effects being applied when tinted glass is covered
|
||||
|
||||
section.increaseHeight();
|
||||
}
|
||||
@@ -210,11 +225,11 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
|
||||
|
||||
int i = blockEntity.levels; final int originalLevels = i; // Paper - OBFHELPER
|
||||
if (level.getGameTime() % 80L == 0L) {
|
||||
- if (!blockEntity.beamSections.isEmpty()) {
|
||||
+ if (!blockEntity.beamSections.isEmpty() || (level.purpurConfig.beaconAllowEffectsWithTintedGlass && isTintedGlass)) { // Purpur - fix beacon effects persisting with broken base while tinted glass is used
|
||||
blockEntity.levels = updateBase(level, x, y, z);
|
||||
}
|
||||
|
||||
- if (blockEntity.levels > 0 && !blockEntity.beamSections.isEmpty()) {
|
||||
+ if (blockEntity.levels > 0 && (!blockEntity.beamSections.isEmpty() || (level.purpurConfig.beaconAllowEffectsWithTintedGlass && isTintedGlass))) { // Purpur - allow beacon effects when covered by tinted glass
|
||||
applyEffects(level, pos, blockEntity.levels, blockEntity.primaryPower, blockEntity.secondaryPower, blockEntity); // Paper - Custom beacon ranges
|
||||
playSound(level, pos, SoundEvents.BEACON_AMBIENT);
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java b/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
|
||||
index c989b7d52e16d93e65afb0f921d514c68b814921..9261bc38258ee80aa6ec2f4bcb27a48c01f84b8f 100644
|
||||
--- a/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
|
||||
@@ -79,7 +79,7 @@ public class BeehiveBlockEntity extends BlockEntity {
|
||||
"leash",
|
||||
"UUID"
|
||||
);
|
||||
- public static final int MAX_OCCUPANTS = 3;
|
||||
+ public static final int MAX_OCCUPANTS = org.purpurmc.purpur.PurpurConfig.beeInsideBeeHive; // Purpur - Config to change max number of bees
|
||||
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;
|
||||
@@ -153,11 +153,33 @@ public class BeehiveBlockEntity extends BlockEntity {
|
||||
return list;
|
||||
}
|
||||
|
||||
+ // Purpur start - Stored Bee API
|
||||
+ public List<Entity> releaseBee(BlockState iblockdata, BeehiveBlockEntity.BeeData data, BeehiveBlockEntity.BeeReleaseStatus tileentitybeehive_releasestatus, boolean force) {
|
||||
+ List<Entity> list = Lists.newArrayList();
|
||||
+
|
||||
+ BeehiveBlockEntity.releaseOccupant(this.level, this.worldPosition, iblockdata, data.occupant, list, tileentitybeehive_releasestatus, this.savedFlowerPos, force);
|
||||
+
|
||||
+ if (!list.isEmpty()) {
|
||||
+ stored.remove(data);
|
||||
+
|
||||
+ super.setChanged();
|
||||
+ }
|
||||
+
|
||||
+ return list;
|
||||
+ }
|
||||
+ // Purpur end - Stored Bee API
|
||||
+
|
||||
@VisibleForDebug
|
||||
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();
|
||||
@@ -398,8 +420,8 @@ public class BeehiveBlockEntity extends BlockEntity {
|
||||
registrar.register(DebugSubscriptions.BEE_HIVES, () -> DebugHiveInfo.pack(this));
|
||||
}
|
||||
|
||||
- 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,50 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/entity/BlockEntity.java b/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
index fb22ebe9758014ebf2aebcda21155f1c4c83fafe..7cbb92c23f0b3d49b8ea6cd66ed4f377dd22ee98 100644
|
||||
--- a/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
@@ -105,6 +105,10 @@ public abstract class BlockEntity implements DebugValueSource {
|
||||
input.read("PublicBukkitValues", CompoundTag.CODEC)
|
||||
.ifPresent(this.persistentDataContainer::putAll);
|
||||
// Paper end - read persistent data container
|
||||
+
|
||||
+
|
||||
+ this.persistentLore = input.read("Purpur.persistentLore", net.minecraft.world.item.component.ItemLore.CODEC).orElse(null); // Purpur - Persistent BlockEntity Lore and DisplayName
|
||||
+
|
||||
}
|
||||
|
||||
public final void loadWithComponents(ValueInput input) {
|
||||
@@ -117,6 +121,11 @@ public abstract class BlockEntity implements DebugValueSource {
|
||||
}
|
||||
|
||||
protected void saveAdditional(ValueOutput output) {
|
||||
+ // Purpur start - Persistent BlockEntity Lore and DisplayName
|
||||
+ if (this.persistentLore != null) {
|
||||
+ output.store("Purpur.persistentLore", net.minecraft.world.item.component.ItemLore.CODEC, this.persistentLore);
|
||||
+ }
|
||||
+ // Purpur end - Persistent BlockEntity Lore and DisplayName
|
||||
}
|
||||
|
||||
public final CompoundTag saveWithFullMetadata(HolderLookup.Provider registries) {
|
||||
@@ -402,4 +411,16 @@ public abstract class BlockEntity implements DebugValueSource {
|
||||
return this.blockEntity.getNameForReporting() + "@" + this.blockEntity.getBlockPos();
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Purpur start - Persistent BlockEntity Lore and DisplayName
|
||||
+ private net.minecraft.world.item.component.@Nullable ItemLore persistentLore = null;
|
||||
+
|
||||
+ public void setPersistentLore(net.minecraft.world.item.component.ItemLore lore) {
|
||||
+ this.persistentLore = lore;
|
||||
+ }
|
||||
+
|
||||
+ public @org.jetbrains.annotations.Nullable net.minecraft.world.item.component.ItemLore getPersistentLore() {
|
||||
+ return this.persistentLore;
|
||||
+ }
|
||||
+ // Purpur end - Persistent BlockEntity Lore and DisplayName
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/entity/ConduitBlockEntity.java b/net/minecraft/world/level/block/entity/ConduitBlockEntity.java
|
||||
index be4b46d56ca67cb5c0fac5e0bbc9456fb5552d78..816d9a0f7f35b95b369ffbfc02e4d1f306b814c5 100644
|
||||
--- a/net/minecraft/world/level/block/entity/ConduitBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/ConduitBlockEntity.java
|
||||
@@ -150,7 +150,7 @@ public class ConduitBlockEntity extends BlockEntity {
|
||||
BlockPos blockPos1 = pos.offset(i, i1, i2x);
|
||||
BlockState blockState = level.getBlockState(blockPos1);
|
||||
|
||||
- for (Block block : VALID_BLOCKS) {
|
||||
+ for (Block block : level.purpurConfig.conduitBlocks) { // Purpur - Conduit behavior configuration
|
||||
if (blockState.is(block)) {
|
||||
positions.add(blockPos1);
|
||||
}
|
||||
@@ -165,13 +165,13 @@ public class ConduitBlockEntity extends BlockEntity {
|
||||
|
||||
private static void applyEffects(Level level, BlockPos pos, List<BlockPos> positions) {
|
||||
// CraftBukkit start
|
||||
- ConduitBlockEntity.applyEffects(level, pos, ConduitBlockEntity.getRange(positions));
|
||||
+ ConduitBlockEntity.applyEffects(level, pos, ConduitBlockEntity.getRange(positions, level)); // Purpur - Conduit behavior configuration
|
||||
}
|
||||
|
||||
- public static int getRange(List<BlockPos> positions) {
|
||||
+ public static int getRange(List<BlockPos> positions, Level level) { // Purpur - Conduit behavior configuration
|
||||
// CraftBukkit end
|
||||
int size = positions.size();
|
||||
- int i = size / 7 * 16;
|
||||
+ int i = size / 7 * level.purpurConfig.conduitDistance; // Purpur - Conduit behavior configuration
|
||||
// CraftBukkit start
|
||||
return i;
|
||||
}
|
||||
@@ -201,7 +201,7 @@ public class ConduitBlockEntity extends BlockEntity {
|
||||
EntityReference<LivingEntity> entityReference = updateDestroyTarget(blockEntity.destroyTarget, level, pos, canDestroy);
|
||||
LivingEntity livingEntity = EntityReference.getLivingEntity(entityReference, level);
|
||||
if (damageTarget && livingEntity != null) { // CraftBukkit
|
||||
- if (livingEntity.hurtServer(level, level.damageSources().magic().eventBlockDamager(level, pos), 4.0F)) // CraftBukkit - move up
|
||||
+ if (livingEntity.hurtServer(level, level.damageSources().magic().eventBlockDamager(level, pos), level.purpurConfig.conduitDamageAmount)) // CraftBukkit - move up // Purpur - Conduit behavior configuration
|
||||
level.playSound(
|
||||
null, livingEntity.getX(), livingEntity.getY(), livingEntity.getZ(), SoundEvents.CONDUIT_ATTACK_TARGET, SoundSource.BLOCKS, 1.0F, 1.0F
|
||||
);
|
||||
@@ -222,19 +222,25 @@ public class ConduitBlockEntity extends BlockEntity {
|
||||
return selectNewTarget(level, pos);
|
||||
} else {
|
||||
LivingEntity livingEntity = EntityReference.getLivingEntity(destroyTarget, level);
|
||||
- return livingEntity != null && livingEntity.isAlive() && pos.closerThan(livingEntity.blockPosition(), 8.0) ? destroyTarget : null;
|
||||
+ return livingEntity != null && livingEntity.isAlive() && pos.closerThan(livingEntity.blockPosition(), level.purpurConfig.conduitDamageDistance) ? destroyTarget : null; // Purpur - Conduit behavior configuration
|
||||
}
|
||||
}
|
||||
|
||||
private static @Nullable EntityReference<LivingEntity> selectNewTarget(ServerLevel level, BlockPos pos) {
|
||||
List<LivingEntity> entitiesOfClass = level.getEntitiesOfClass(
|
||||
- LivingEntity.class, getDestroyRangeAABB(pos), livingEntity -> livingEntity instanceof Enemy && livingEntity.isInWaterOrRain()
|
||||
+ LivingEntity.class, getDestroyRangeAABB(pos, level), livingEntity -> livingEntity instanceof Enemy && livingEntity.isInWaterOrRain() // Purpur - Conduit behavior configuration
|
||||
);
|
||||
return entitiesOfClass.isEmpty() ? null : EntityReference.of(Util.getRandom(entitiesOfClass, level.random));
|
||||
}
|
||||
|
||||
public static AABB getDestroyRangeAABB(BlockPos pos) {
|
||||
- return new AABB(pos).inflate(8.0);
|
||||
+ // Purpur start - Conduit behavior configuration
|
||||
+ return getDestroyRangeAABB(pos, null);
|
||||
+ }
|
||||
+
|
||||
+ private static AABB getDestroyRangeAABB(BlockPos pos, Level level) {
|
||||
+ // Purpur end - Conduit behavior configuration
|
||||
+ return new AABB(pos).inflate(level == null ? 8.0 : level.purpurConfig.conduitDamageDistance); // Purpur - Conduit behavior configuration
|
||||
}
|
||||
|
||||
private static void animationTick(Level level, BlockPos pos, List<BlockPos> positions, @Nullable Entity entity, int tickCount) {
|
||||
@@ -1,73 +0,0 @@
|
||||
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
|
||||
From: File <noreply+automated@papermc.io>
|
||||
Date: Sun, 20 Apr 1997 05:37:42 -0800
|
||||
Subject: [PATCH] purpur File Patches
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/entity/SignBlockEntity.java b/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
||||
index ce6108ea608463a28f9349010e912f23a7a1cb0c..e93f399c02aa3c47b08e33b8cf2f8b474273c33b 100644
|
||||
--- a/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
||||
@@ -149,16 +149,32 @@ public class SignBlockEntity extends BlockEntity {
|
||||
return this.setText(updater.apply(text), isFrontText);
|
||||
}
|
||||
|
||||
+ // Purpur start - Signs allow color codes
|
||||
+ private Component translateColors(org.bukkit.entity.Player player, String line, Style style) {
|
||||
+ if (level.purpurConfig.signAllowColors) {
|
||||
+ if (player.hasPermission("purpur.sign.color")) line = line.replaceAll("(?i)&([0-9a-fr])", "\u00a7$1");
|
||||
+ if (player.hasPermission("purpur.sign.style")) line = line.replaceAll("(?i)&([l-or])", "\u00a7$1");
|
||||
+ if (player.hasPermission("purpur.sign.magic")) line = line.replaceAll("(?i)&([kr])", "\u00a7$1");
|
||||
+
|
||||
+ return io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(line));
|
||||
+ } else {
|
||||
+ return Component.literal(line).setStyle(style);
|
||||
+ }
|
||||
+ }
|
||||
+ // Purpur end - Signs allow color codes
|
||||
+
|
||||
private SignText setMessages(Player player, List<FilteredText> filteredText, SignText text, boolean front) { // CraftBukkit
|
||||
SignText originalText = text; // CraftBukkit
|
||||
for (int i = 0; i < filteredText.size(); i++) {
|
||||
FilteredText filteredText1 = filteredText.get(i);
|
||||
Style style = text.getMessage(i, player.isTextFilteringEnabled()).getStyle();
|
||||
+
|
||||
+ org.bukkit.entity.Player craftPlayer = (org.bukkit.craftbukkit.entity.CraftPlayer) player.getBukkitEntity(); // Purpur - Signs allow color codes
|
||||
if (player.isTextFilteringEnabled()) {
|
||||
- text = text.setMessage(i, Component.literal(net.minecraft.util.StringUtil.filterText(filteredText1.filteredOrEmpty())).setStyle(style)); // Paper - filter sign text to chat only
|
||||
+ text = text.setMessage(i, translateColors(craftPlayer, net.minecraft.util.StringUtil.filterText(filteredText1.filteredOrEmpty()), style)); // Paper - filter sign text to chat only // Purpur - Signs allow color codes
|
||||
} else {
|
||||
text = text.setMessage(
|
||||
- i, Component.literal(filteredText1.raw()).setStyle(style), Component.literal(net.minecraft.util.StringUtil.filterText(filteredText1.filteredOrEmpty())).setStyle(style) // Paper - filter sign text to chat only
|
||||
+ i, translateColors(craftPlayer, net.minecraft.util.StringUtil.filterText(filteredText1.raw()), style), translateColors(craftPlayer, net.minecraft.util.StringUtil.filterText(filteredText1.filteredOrEmpty()), style) // Paper - filter sign text to chat only // Purpur - Signs allow color codes
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -308,6 +324,27 @@ public class SignBlockEntity extends BlockEntity {
|
||||
return new CommandSourceStack(commandSource, Vec3.atCenterOf(pos), Vec2.ZERO, level, LevelBasedPermissionSet.GAMEMASTER, string, component, level.getServer(), player); // Paper - Fix commands from signs not firing command events
|
||||
}
|
||||
|
||||
+ // Purpur start - Signs allow color codes
|
||||
+ public ClientboundBlockEntityDataPacket getTranslatedUpdatePacket(boolean filtered, boolean front) {
|
||||
+ try (net.minecraft.util.ProblemReporter.ScopedCollector scopedCollector = new net.minecraft.util.ProblemReporter.ScopedCollector(this.problemPath(), LOGGER)) {
|
||||
+ net.minecraft.world.level.storage.TagValueOutput tagValueOutput = net.minecraft.world.level.storage.TagValueOutput.createWithContext(scopedCollector, this.getLevel().registryAccess());
|
||||
+ this.saveAdditional(tagValueOutput);
|
||||
+
|
||||
+ final Component[] lines = front ? frontText.getMessages(filtered) : backText.getMessages(filtered);
|
||||
+ final String side = front ? "front_text" : "back_text";
|
||||
+ net.minecraft.world.level.storage.ValueOutput sideNbt = tagValueOutput.child(side);
|
||||
+ net.minecraft.world.level.storage.ValueOutput.TypedOutputList<String> messagesNbt = sideNbt.list("messages", com.mojang.serialization.Codec.STRING);
|
||||
+ for (int i = 0; i < 4; i++) {
|
||||
+ final net.kyori.adventure.text.Component component = io.papermc.paper.adventure.PaperAdventure.asAdventure(lines[i]);
|
||||
+ final String line = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacyAmpersand().serialize(component);
|
||||
+ messagesNbt.add(line);
|
||||
+ }
|
||||
+ tagValueOutput.putString("PurpurEditor", "true");
|
||||
+ return ClientboundBlockEntityDataPacket.create(this, (blockEntity, registryAccess) -> tagValueOutput.buildResult());
|
||||
+ }
|
||||
+ }
|
||||
+ // Purpur end - Signs allow color codes
|
||||
+
|
||||
@Override
|
||||
public ClientboundBlockEntityDataPacket getUpdatePacket() {
|
||||
return ClientboundBlockEntityDataPacket.create(this);
|
||||
Reference in New Issue
Block a user