diff --git a/gradle.properties b/gradle.properties index 2e53a5344..a9b05822b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ group=net.pl3x.purpur version=1.17-R0.1-SNAPSHOT packageVersion=1_17_R1 -paperCommit=ce6610254f61047ec957814426a643138f077979 +paperCommit=ed5100faf11436cb924b1cdb2401c2c65881b739 org.gradle.parallel=true org.gradle.jvmargs=-Xmx3G diff --git a/patches/server-unmapped/0144-Spread-out-and-optimise-player-list-ticks.patch b/patches/server-unmapped/0144-Spread-out-and-optimise-player-list-ticks.patch deleted file mode 100644 index 0391a93d4..000000000 --- a/patches/server-unmapped/0144-Spread-out-and-optimise-player-list-ticks.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: James Lyne -Date: Mon, 7 Dec 2020 17:52:36 +0000 -Subject: [PATCH] Spread out and optimise player list ticks - - -diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 1d7685f5373249a6cc950ebd8a75cda53e5680d6..9a41d4ae2a64ba542dd9b6b98b01dd660a43b2dc 100644 ---- a/src/main/java/net/minecraft/server/players/PlayerList.java -+++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -151,7 +151,7 @@ public abstract class PlayerList { - private int viewDistance; - private EnumGamemode u; - private boolean v; -- private int w; -+ private int w; private int getTick() { return this.w; } private int setTick(int i) { return this.w = i; } // Purpur - OBFHELPER - - // CraftBukkit start - private CraftServer cserver; -@@ -1028,22 +1028,23 @@ public abstract class PlayerList { - } - - public void tick() { -- if (++this.w > 600) { -- // CraftBukkit start -- for (int i = 0; i < this.players.size(); ++i) { -- final EntityPlayer target = (EntityPlayer) this.players.get(i); -- -- target.playerConnection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.UPDATE_LATENCY, Iterables.filter(this.players, new Predicate() { -- @Override -- public boolean apply(EntityPlayer input) { -- return target.getBukkitEntity().canSee(input.getBukkitEntity()); -- } -- }))); -+ // Purpur start -+ int tick = getTick(); -+ if (tick < this.players.size()) { -+ final org.bukkit.craftbukkit.entity.CraftPlayer target = this.players.get(tick).getBukkitEntity(); -+ final java.util.List list = new java.util.ArrayList<>(); -+ for (EntityPlayer entityplayer : this.players) { -+ if (target.canSee(entityplayer.getUniqueID())) { -+ list.add(entityplayer); -+ } - } -- // CraftBukkit end -- this.w = 0; -+ target.getHandle().playerConnection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.UPDATE_LATENCY, list)); - } -- -+ if (++tick > 600) { -+ tick = 0; -+ } -+ setTick(tick); -+ // Purpur end - } - - public void sendAll(Packet packet) { -diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 45bf2b87518ba81cb4a18a59d11dba9430e63e40..175dfb418f910d6486109073d0a406461a48f7ec 100644 ---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1447,7 +1447,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { - - @Override - public boolean canSee(Player player) { -- return !hiddenPlayers.containsKey(player.getUniqueId()); -+ // Purpur start -+ return canSee(player.getUniqueId()); -+ } -+ -+ public boolean canSee(UUID uuid) { -+ return !hiddenPlayers.containsKey(uuid); -+ // Purpur end - } - - @Override diff --git a/patches/server-unmapped/0145-Configurable-chance-for-wolves-to-spawn-rabid.patch b/patches/server-unmapped/0145-Configurable-chance-for-wolves-to-spawn-rabid.patch deleted file mode 100644 index a4874540f..000000000 --- a/patches/server-unmapped/0145-Configurable-chance-for-wolves-to-spawn-rabid.patch +++ /dev/null @@ -1,283 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Encode42 -Date: Tue, 8 Dec 2020 17:15:15 -0500 -Subject: [PATCH] Configurable chance for wolves to spawn rabid - -Configurable chance to spawn a wolf that is rabid. -Rabid wolves attack all players, mobs, and animals. - -diff --git a/src/main/java/net/minecraft/world/entity/EntityLiving.java b/src/main/java/net/minecraft/world/entity/EntityLiving.java -index a1a8441e26ce1414b2406f9be559eeb3a34453d9..65cafb25252aa1d2013311a8fef364b96ee7273c 100644 ---- a/src/main/java/net/minecraft/world/entity/EntityLiving.java -+++ b/src/main/java/net/minecraft/world/entity/EntityLiving.java -@@ -2197,6 +2197,7 @@ public abstract class EntityLiving extends Entity { - } - } - -+ public final void setItemInHand(EnumHand enumHand, ItemStack itemStack) { this.a(enumHand, itemStack); } // Purpur - OBFHELPER - public void a(EnumHand enumhand, ItemStack itemstack) { - if (enumhand == EnumHand.MAIN_HAND) { - this.setSlot(EnumItemSlot.MAINHAND, itemstack); -diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalAvoidTarget.java b/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalAvoidTarget.java -index 5115c56487a12f904ff836355375f66a16098790..35502bd2f7d9cebf5cfe1060e300a5032dbe6a5d 100644 ---- a/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalAvoidTarget.java -+++ b/src/main/java/net/minecraft/world/entity/ai/goal/PathfinderGoalAvoidTarget.java -@@ -17,7 +17,7 @@ public class PathfinderGoalAvoidTarget extends Pathfinde - protected final EntityCreature a; - private final double i; - private final double j; -- protected T b; -+ protected T b; protected T getTarget() { return this.b; } // Purpur - OBFHELPER - protected final float c; - protected PathEntity d; - protected final NavigationAbstract e; -@@ -27,12 +27,7 @@ public class PathfinderGoalAvoidTarget extends Pathfinde - private final PathfinderTargetCondition k; - - public PathfinderGoalAvoidTarget(EntityCreature entitycreature, Class oclass, float f, double d0, double d1) { -- Predicate predicate = (entityliving) -> { -- return true; -- }; -- Predicate predicate1 = IEntitySelector.e; -- -- this(entitycreature, oclass, predicate, f, d0, d1, predicate1::test); -+ this(entitycreature, oclass, entityliving -> true, f, d0, d1, IEntitySelector.e::test); // Purpur - decompile fix - } - - public PathfinderGoalAvoidTarget(EntityCreature entitycreature, Class oclass, Predicate predicate, float f, double d0, double d1, Predicate predicate1) { -diff --git a/src/main/java/net/minecraft/world/entity/animal/EntityWolf.java b/src/main/java/net/minecraft/world/entity/animal/EntityWolf.java -index dd3c7ad7701ad18ccaf86d73fde7051090ed3d57..e8c6aca70db693250224d1c162e3c2684687ea41 100644 ---- a/src/main/java/net/minecraft/world/entity/animal/EntityWolf.java -+++ b/src/main/java/net/minecraft/world/entity/animal/EntityWolf.java -@@ -10,15 +10,19 @@ import net.minecraft.network.syncher.DataWatcher; - import net.minecraft.network.syncher.DataWatcherObject; - import net.minecraft.network.syncher.DataWatcherRegistry; - import net.minecraft.server.PathfinderGoalHasRider; -+import net.minecraft.server.level.EntityPlayer; - import net.minecraft.server.level.WorldServer; - import net.minecraft.sounds.SoundEffect; - import net.minecraft.sounds.SoundEffects; - import net.minecraft.util.IntRange; - import net.minecraft.util.MathHelper; - import net.minecraft.util.TimeRange; -+import net.minecraft.world.DifficultyDamageScaler; - import net.minecraft.world.EnumHand; - import net.minecraft.world.EnumInteractionResult; - import net.minecraft.world.damagesource.DamageSource; -+import net.minecraft.world.effect.MobEffect; -+import net.minecraft.world.effect.MobEffects; - import net.minecraft.world.entity.Entity; - import net.minecraft.world.entity.EntityAgeable; - import net.minecraft.world.entity.EntityInsentient; -@@ -27,9 +31,12 @@ import net.minecraft.world.entity.EntityPose; - import net.minecraft.world.entity.EntitySize; - import net.minecraft.world.entity.EntityTameableAnimal; - import net.minecraft.world.entity.EntityTypes; -+import net.minecraft.world.entity.EnumMobSpawn; -+import net.minecraft.world.entity.GroupDataEntity; - import net.minecraft.world.entity.IEntityAngerable; - import net.minecraft.world.entity.ai.attributes.AttributeProvider; - import net.minecraft.world.entity.ai.attributes.GenericAttributes; -+import net.minecraft.world.entity.ai.goal.PathfinderGoal; - import net.minecraft.world.entity.ai.goal.PathfinderGoalAvoidTarget; - import net.minecraft.world.entity.ai.goal.PathfinderGoalBeg; - import net.minecraft.world.entity.ai.goal.PathfinderGoalBreed; -@@ -60,6 +67,7 @@ import net.minecraft.world.item.ItemDye; - import net.minecraft.world.item.ItemStack; - import net.minecraft.world.item.Items; - import net.minecraft.world.level.World; -+import net.minecraft.world.level.WorldAccess; - import net.minecraft.world.level.block.state.IBlockData; - import net.minecraft.world.phys.Vec3D; - -@@ -73,11 +81,42 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable - private static final DataWatcherObject br = DataWatcher.a(EntityWolf.class, DataWatcherRegistry.i); - private static final DataWatcherObject bs = DataWatcher.a(EntityWolf.class, DataWatcherRegistry.b); - private static final DataWatcherObject bt = DataWatcher.a(EntityWolf.class, DataWatcherRegistry.b); -- public static final Predicate bq = (entityliving) -> { -+ public static Predicate vanillaPredicate() { return bq; } public static final Predicate bq = (entityliving) -> { // Purpur - OBFHELPER - EntityTypes entitytypes = entityliving.getEntityType(); - - return entitytypes == EntityTypes.SHEEP || entitytypes == EntityTypes.RABBIT || entitytypes == EntityTypes.FOX; - }; -+ // Purpur start - rabid wolf spawn chance -+ private boolean isRabid = false; -+ private static final Predicate RABID_PREDICATE = e -> e instanceof EntityPlayer || e instanceof EntityInsentient; -+ private final PathfinderGoal PATHFINDER_VANILLA = new PathfinderGoalRandomTargetNonTamed<>(this, EntityAnimal.class, false, vanillaPredicate()); -+ private final PathfinderGoal PATHFINDER_RABID = new PathfinderGoalRandomTargetNonTamed<>(this, EntityLiving.class, false, RABID_PREDICATE); -+ private static final class PathfinderGoalAvoidRabidWolves extends PathfinderGoalAvoidTarget { -+ private final EntityWolf wolf; -+ -+ public PathfinderGoalAvoidRabidWolves(EntityWolf wolf, float distance, double minSpeed, double maxSpeed) { -+ super(wolf, EntityWolf.class, distance, minSpeed, maxSpeed); -+ this.wolf = wolf; -+ } -+ -+ @Override -+ public boolean a() { // shouldExecute -+ return super.a() && !this.wolf.isRabid() && this.getTarget() != null && this.getTarget().isRabid(); // wolves which are not rabid run away from rabid wolves -+ } -+ -+ @Override -+ public void c() { // startExecuting -+ this.wolf.setGoalTarget(null); -+ super.c(); -+ } -+ -+ @Override -+ public void e() { // tick -+ this.wolf.setGoalTarget(null); -+ super.e(); -+ } -+ } -+ // Purpur end - private float bu; - private float bv; - private boolean bw; -@@ -112,6 +151,37 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable - public int getPurpurBreedTime() { - return this.world.purpurConfig.wolfBreedingTicks; - } -+ -+ 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) { -+ setTamed(false); -+ setOwnerUUID(null); -+ this.targetSelector.addGoal(5, PATHFINDER_RABID); -+ if (modifyEffects) this.addEffect(new MobEffect(MobEffects.CONFUSION, 1200)); -+ } else { -+ this.targetSelector.addGoal(5, PATHFINDER_VANILLA); -+ this.pacify(); -+ if (modifyEffects) this.removeEffect(MobEffects.CONFUSION); -+ } -+ } -+ -+ @Override -+ public GroupDataEntity prepare(WorldAccess worldaccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { -+ this.isRabid = world.purpurConfig.wolfNaturalRabid > 0.0D && random.nextDouble() <= world.purpurConfig.wolfNaturalRabid; -+ this.updatePathfinders(false); -+ return super.prepare(worldaccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); -+ } - // Purpur end - - @Override -@@ -120,6 +190,7 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable - this.goalSelector.a(1, new PathfinderGoalHasRider(this)); // Purpur - this.goalSelector.a(2, new PathfinderGoalSit(this)); - this.goalSelector.a(3, new EntityWolf.a<>(this, EntityLlama.class, 24.0F, 1.5D, 1.5D)); -+ this.goalSelector.addGoal(3, new PathfinderGoalAvoidRabidWolves(this, 24.0F, 1.5D, 1.5D)); // Purpur - this.goalSelector.a(4, new PathfinderGoalLeapAtTarget(this, 0.4F)); - this.goalSelector.a(5, new PathfinderGoalMeleeAttack(this, 1.0D, true)); - this.goalSelector.a(6, new PathfinderGoalFollowOwner(this, 1.0D, 10.0F, 2.0F, false)); -@@ -133,7 +204,7 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable - this.targetSelector.a(2, new PathfinderGoalOwnerHurtTarget(this)); - this.targetSelector.a(3, (new PathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0])); // CraftBukkit - decompile error - this.targetSelector.a(4, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, 10, true, false, this::a_)); -- this.targetSelector.a(5, new PathfinderGoalRandomTargetNonTamed<>(this, EntityAnimal.class, false, EntityWolf.bq)); -+ //this.targetSelector.a(5, new PathfinderGoalRandomTargetNonTamed<>(this, EntityAnimal.class, false, EntityWolf.bq)); // Purpur - moved to updatePathfinders() - this.targetSelector.a(6, new PathfinderGoalRandomTargetNonTamed<>(this, EntityTurtle.class, false, EntityTurtle.bo)); - this.targetSelector.a(7, new PathfinderGoalNearestAttackableTarget<>(this, EntitySkeletonAbstract.class, false)); - this.targetSelector.a(8, new PathfinderGoalUniversalAngerReset<>(this, true)); -@@ -178,6 +249,7 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable - public void saveData(NBTTagCompound nbttagcompound) { - super.saveData(nbttagcompound); - nbttagcompound.setByte("CollarColor", (byte) this.getCollarColor().getColorIndex()); -+ nbttagcompound.setBoolean("Purpur.IsRabid", this.isRabid); // Purpur - this.c(nbttagcompound); - } - -@@ -187,6 +259,10 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable - if (nbttagcompound.hasKeyOfType("CollarColor", 99)) { - this.setCollarColor(EnumColor.fromColorIndex(nbttagcompound.getInt("CollarColor"))); - } -+ // Purpur start -+ this.isRabid = nbttagcompound.getBoolean("Purpur.IsRabid"); -+ this.updatePathfinders(false); -+ // Purpur end - - this.a((WorldServer) this.world, nbttagcompound); - } -@@ -231,6 +307,11 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable - public void tick() { - super.tick(); - if (this.isAlive()) { -+ // Purpur start -+ if (this.ticksLived % 300 == 0 && this.isRabid()) { -+ this.addEffect(new MobEffect(MobEffects.CONFUSION, 400)); -+ } -+ // Purpur end - this.bv = this.bu; - if (this.eY()) { - this.bu += (1.0F - this.bu) * 0.4F; -@@ -402,6 +483,20 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable - - return EnumInteractionResult.SUCCESS; - } -+ // Purpur start -+ else if (this.world.purpurConfig.wolfMilkCuresRabies && itemstack.getItem() == Items.MILK_BUCKET && this.isRabid()) { -+ if (!entityhuman.isCreative()) { -+ entityhuman.setItemInHand(enumhand, new ItemStack(Items.BUCKET)); -+ } -+ this.setRabid(false); -+ for (int i = 0; i < 10; ++i) { -+ ((WorldServer) world).sendParticles(((WorldServer) world).players, null, Particles.HAPPY_VILLAGER, -+ locX() + random.nextFloat(), locY() + (random.nextFloat() * 1.5), locZ() + random.nextFloat(), 1, -+ random.nextGaussian() * 0.05D, random.nextGaussian() * 0.05D, random.nextGaussian() * 0.05D, 0, true); -+ } -+ return EnumInteractionResult.SUCCESS; -+ } -+ // Purpur end - - return super.b(entityhuman, enumhand); - } -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 7d32788c5e538be6eff9b6ff4655f279ac1e0e6b..5a05d4e511bf7c96d3e01c59e6e53b105bf7baf6 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -1219,10 +1219,14 @@ public class PurpurWorldConfig { - - public boolean wolfRidable = false; - public boolean wolfRidableInWater = false; -+ public boolean wolfMilkCuresRabies = true; -+ public double wolfNaturalRabid = 0.0D; - public int wolfBreedingTicks = 6000; - private void wolfSettings() { - wolfRidable = getBoolean("mobs.wolf.ridable", wolfRidable); - wolfRidableInWater = getBoolean("mobs.wolf.ridable-in-water", wolfRidableInWater); -+ wolfMilkCuresRabies = getBoolean("mobs.wolf.milk-cures-rabid-wolves", wolfMilkCuresRabies); -+ wolfNaturalRabid = getDouble("mobs.wolf.spawn-rabid-chance", wolfNaturalRabid); - wolfBreedingTicks = getInt("mobs.wolf.breeding-delay-ticks", wolfBreedingTicks); - } - -diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java -index dc5ba91ebdef25d633205a65148b62f1853b4da5..71e5b36b7d0bb92ef6e94759318a4a82a19e729a 100644 ---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java -+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java -@@ -45,4 +45,16 @@ public class CraftWolf extends CraftTameableAnimal implements Wolf { - public void setCollarColor(DyeColor color) { - getHandle().setCollarColor(EnumColor.fromColorIndex(color.getWoolData())); - } -+ -+ // Purpur start -+ @Override -+ public boolean isRabid() { -+ return getHandle().isRabid(); -+ } -+ -+ @Override -+ public void setRabid(boolean isRabid) { -+ getHandle().setRabid(isRabid); -+ } -+ // Purpur end - } diff --git a/patches/server-unmapped/0146-Configurable-default-wolf-collar-color.patch b/patches/server-unmapped/0146-Configurable-default-wolf-collar-color.patch deleted file mode 100644 index b2e3efadb..000000000 --- a/patches/server-unmapped/0146-Configurable-default-wolf-collar-color.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Encode42 -Date: Thu, 10 Dec 2020 13:43:28 -0500 -Subject: [PATCH] Configurable default wolf collar color - -This allows for the server to set a default collar color when a wolf is tamed. -Resets to RED when the value is invalid. - -diff --git a/src/main/java/net/minecraft/world/entity/animal/EntityWolf.java b/src/main/java/net/minecraft/world/entity/animal/EntityWolf.java -index e8c6aca70db693250224d1c162e3c2684687ea41..e33aadead6e6c5e0a7b39ef95e7aeb0f0092a94e 100644 ---- a/src/main/java/net/minecraft/world/entity/animal/EntityWolf.java -+++ b/src/main/java/net/minecraft/world/entity/animal/EntityWolf.java -@@ -182,6 +182,12 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable - this.updatePathfinders(false); - return super.prepare(worldaccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); - } -+ -+ @Override -+ public void tame(EntityHuman entityhuman) { -+ setCollarColor(world.purpurConfig.wolfDefaultCollarColor); -+ super.tame(entityhuman); -+ } - // Purpur end - - @Override -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 5a05d4e511bf7c96d3e01c59e6e53b105bf7baf6..0666c523f82b9083ed8e81570faa923bbeb00ab8 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -3,6 +3,7 @@ package net.pl3x.purpur; - import com.destroystokyo.paper.PaperConfig; - import net.minecraft.core.IRegistry; - import net.minecraft.world.EnumDifficulty; -+import net.minecraft.world.item.EnumColor; - import net.minecraft.world.level.Explosion; - import net.minecraft.world.level.block.Block; - import net.minecraft.world.level.block.Blocks; -@@ -1219,12 +1220,18 @@ public class PurpurWorldConfig { - - public boolean wolfRidable = false; - public boolean wolfRidableInWater = false; -+ public EnumColor wolfDefaultCollarColor = EnumColor.RED; - public boolean wolfMilkCuresRabies = true; - public double wolfNaturalRabid = 0.0D; - public int wolfBreedingTicks = 6000; - private void wolfSettings() { - wolfRidable = getBoolean("mobs.wolf.ridable", wolfRidable); - wolfRidableInWater = getBoolean("mobs.wolf.ridable-in-water", wolfRidableInWater); -+ try { -+ wolfDefaultCollarColor = EnumColor.valueOf(getString("mobs.wolf.default-collar-color", wolfDefaultCollarColor.name())); -+ } catch (IllegalArgumentException ignore) { -+ wolfDefaultCollarColor = EnumColor.RED; -+ } - wolfMilkCuresRabies = getBoolean("mobs.wolf.milk-cures-rabid-wolves", wolfMilkCuresRabies); - wolfNaturalRabid = getDouble("mobs.wolf.spawn-rabid-chance", wolfNaturalRabid); - wolfBreedingTicks = getInt("mobs.wolf.breeding-delay-ticks", wolfBreedingTicks); diff --git a/patches/server-unmapped/0148-Phantom-flames-on-swoop.patch b/patches/server-unmapped/0148-Phantom-flames-on-swoop.patch deleted file mode 100644 index 59eb0bbb0..000000000 --- a/patches/server-unmapped/0148-Phantom-flames-on-swoop.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 12 Dec 2020 09:10:59 -0600 -Subject: [PATCH] Phantom flames on swoop - - -diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityPhantom.java b/src/main/java/net/minecraft/world/entity/monster/EntityPhantom.java -index 437d602cf4a0da52fc61a50321d795290eea11bf..fe07d9798eaae670e218d25fe23256c87c41d686 100644 ---- a/src/main/java/net/minecraft/world/entity/monster/EntityPhantom.java -+++ b/src/main/java/net/minecraft/world/entity/monster/EntityPhantom.java -@@ -226,6 +226,7 @@ public class EntityPhantom extends EntityFlying implements IMonster { - this.world.addParticle(Particles.MYCELIUM, this.locX() - (double) f2, this.locY() + (double) f4, this.locZ() - (double) f3, 0.0D, 0.0D, 0.0D); - } - -+ if (world.purpurConfig.phantomFlamesOnSwoop && getAttackPhase() == AttackPhase.SWOOP) shoot(); // Purpur - } - - @Override -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index f0f8165c51c17855d0c719d47bea194b80ff7847..c84a331c157ea1180813cba1107bf901a35b2833 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -1206,6 +1206,7 @@ public class PurpurWorldConfig { - public boolean phantomIgnorePlayersWithTorch = false; - public boolean phantomBurnInDaylight = true; - public boolean phantomAllowGriefing = false; -+ public boolean phantomFlamesOnSwoop = false; - public double phantomMaxHealth = 20.0D; - private void phantomSettings() { - phantomRidable = getBoolean("mobs.phantom.ridable", phantomRidable); -@@ -1232,6 +1233,7 @@ public class PurpurWorldConfig { - phantomBurnInDaylight = getBoolean("mobs.phantom.burn-in-daylight", phantomBurnInDaylight); - phantomIgnorePlayersWithTorch = getBoolean("mobs.phantom.ignore-players-with-torch", phantomIgnorePlayersWithTorch); - phantomAllowGriefing = getBoolean("mobs.phantom.allow-griefing", phantomAllowGriefing); -+ phantomFlamesOnSwoop = getBoolean("mobs.phantom.flames-on-swoop", phantomFlamesOnSwoop); - if (PurpurConfig.version < 10) { - double oldValue = getDouble("mobs.phantom.attributes.max-health", phantomMaxHealth); - set("mobs.phantom.attributes.max-health", null); diff --git a/patches/server-unmapped/0149-Option-for-chests-to-open-even-with-a-solid-block-on.patch b/patches/server-unmapped/0149-Option-for-chests-to-open-even-with-a-solid-block-on.patch deleted file mode 100644 index b8582feaf..000000000 --- a/patches/server-unmapped/0149-Option-for-chests-to-open-even-with-a-solid-block-on.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> -Date: Sat, 12 Dec 2020 14:34:18 -0800 -Subject: [PATCH] Option for chests to open even with a solid block on top - - -diff --git a/src/main/java/net/minecraft/world/level/block/BlockChest.java b/src/main/java/net/minecraft/world/level/block/BlockChest.java -index a45ee959f41e7f349ff2c309f21fa44ec671cb87..cddf8e3d34385eb264cd28ba6b4392d682df0360 100644 ---- a/src/main/java/net/minecraft/world/level/block/BlockChest.java -+++ b/src/main/java/net/minecraft/world/level/block/BlockChest.java -@@ -306,6 +306,7 @@ public class BlockChest extends BlockChestAbstract implements I - } - - private static boolean a(IBlockAccess iblockaccess, BlockPosition blockposition) { -+ if (iblockaccess instanceof World && ((World) iblockaccess).purpurConfig.chestOpenWithBlockOnTop) return false; // Purpur - BlockPosition blockposition1 = blockposition.up(); - - return iblockaccess.getType(blockposition1).isOccluding(iblockaccess, blockposition1); -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index c84a331c157ea1180813cba1107bf901a35b2833..3d1cfd550b12c8dd4bd536c518ac169ff6bbfe50 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -439,6 +439,11 @@ public class PurpurWorldConfig { - } - } - -+ public boolean chestOpenWithBlockOnTop = false; -+ private void chestSettings() { -+ chestOpenWithBlockOnTop = getBoolean("blocks.chest.open-with-solid-block-on-top", chestOpenWithBlockOnTop); -+ } -+ - public boolean dispenserApplyCursedArmor = true; - public boolean dispenserPlaceAnvils = false; - private void dispenserSettings() { diff --git a/patches/server/0138-Spread-out-and-optimise-player-list-ticksSpread-out-.patch b/patches/server/0138-Spread-out-and-optimise-player-list-ticksSpread-out-.patch new file mode 100644 index 000000000..2270f758b --- /dev/null +++ b/patches/server/0138-Spread-out-and-optimise-player-list-ticksSpread-out-.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: James Lyne +Date: Mon, 7 Dec 2020 17:52:36 +0000 +Subject: [PATCH] Spread out and optimise player list ticksSpread out and + optimise player list ticks + + +diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java +index d613b5bf9d0be9b8593d4cc02b8cb77a1f49938a..7bab62ac11d31f9eb0936f8c8540ad19685b49ee 100644 +--- a/src/main/java/net/minecraft/server/players/PlayerList.java ++++ b/src/main/java/net/minecraft/server/players/PlayerList.java +@@ -998,22 +998,22 @@ public abstract class PlayerList { + } + + public void tick() { +- if (++this.sendAllPlayerInfoIn > 600) { +- // CraftBukkit start +- for (int i = 0; i < this.players.size(); ++i) { +- final ServerPlayer target = (ServerPlayer) this.players.get(i); +- +- target.connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.UPDATE_LATENCY, this.players.stream().filter(new Predicate() { +- @Override +- public boolean apply(ServerPlayer input) { +- return target.getBukkitEntity().canSee(input.getBukkitEntity()); +- } +- }).collect(Collectors.toList()))); ++ // Purpur start ++ if (this.sendAllPlayerInfoIn < this.players.size()) { ++ final org.bukkit.craftbukkit.entity.CraftPlayer target = this.players.get(this.sendAllPlayerInfoIn).getBukkitEntity(); ++ final List list = new java.util.ArrayList<>(); ++ for (ServerPlayer player : this.players) { ++ if (target.canSee(player.getUUID())) { ++ list.add(player); ++ } + } +- // CraftBukkit end +- this.sendAllPlayerInfoIn = 0; ++ target.getHandle().connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.UPDATE_LATENCY, list)); + } + ++ if (++this.sendAllPlayerInfoIn > 600) { ++ this.sendAllPlayerInfoIn = 0; ++ } ++ // Purpur end + } + + public void broadcastAll(Packet packet) { +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index 676d98f183d798f1ea894cd78539f9034edb3659..9388a960317b3d0bcebbbce3855db64d2dc9e97a 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -1503,7 +1503,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + + @Override + public boolean canSee(Player player) { +- return !this.hiddenPlayers.containsKey(player.getUniqueId()); ++ // Purpur start ++ return canSee(player.getUniqueId()); ++ } ++ ++ public boolean canSee(UUID uuid) { ++ return !hiddenPlayers.containsKey(uuid); ++ // Purpur end + } + + @Override diff --git a/patches/server/0139-Configurable-chance-for-wolves-to-spawn-rabid.patch b/patches/server/0139-Configurable-chance-for-wolves-to-spawn-rabid.patch new file mode 100644 index 000000000..ae1b9caf0 --- /dev/null +++ b/patches/server/0139-Configurable-chance-for-wolves-to-spawn-rabid.patch @@ -0,0 +1,245 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Encode42 +Date: Tue, 8 Dec 2020 17:15:15 -0500 +Subject: [PATCH] Configurable chance for wolves to spawn rabid + +Configurable chance to spawn a wolf that is rabid. +Rabid wolves attack all players, mobs, and animals. + +diff --git a/src/main/java/net/minecraft/world/entity/animal/Wolf.java b/src/main/java/net/minecraft/world/entity/animal/Wolf.java +index ef4abaf68de01b0879f7d0b330d2d57cc6bd10f9..3e7409ebf1f94b9cf55f2d0b0fe17ca8ec44659f 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/Wolf.java ++++ b/src/main/java/net/minecraft/world/entity/animal/Wolf.java +@@ -10,22 +10,28 @@ import net.minecraft.network.syncher.EntityDataAccessor; + import net.minecraft.network.syncher.EntityDataSerializers; + import net.minecraft.network.syncher.SynchedEntityData; + import net.minecraft.server.level.ServerLevel; ++import net.minecraft.server.level.ServerPlayer; + import net.minecraft.sounds.SoundEvent; + import net.minecraft.sounds.SoundEvents; + import net.minecraft.util.Mth; + import net.minecraft.util.TimeUtil; + import net.minecraft.util.valueproviders.UniformInt; ++import net.minecraft.world.DifficultyInstance; + import net.minecraft.world.InteractionHand; + import net.minecraft.world.InteractionResult; + import net.minecraft.world.damagesource.DamageSource; ++import net.minecraft.world.effect.MobEffectInstance; ++import net.minecraft.world.effect.MobEffects; + import net.minecraft.world.entity.AgeableMob; + import net.minecraft.world.entity.Entity; + import net.minecraft.world.entity.EntityDimensions; + import net.minecraft.world.entity.EntityType; + import net.minecraft.world.entity.LivingEntity; + import net.minecraft.world.entity.Mob; ++import net.minecraft.world.entity.MobSpawnType; + import net.minecraft.world.entity.NeutralMob; + import net.minecraft.world.entity.Pose; ++import net.minecraft.world.entity.SpawnGroupData; + import net.minecraft.world.entity.TamableAnimal; + import net.minecraft.world.entity.ai.attributes.AttributeSupplier; + import net.minecraft.world.entity.ai.attributes.Attributes; +@@ -34,6 +40,7 @@ import net.minecraft.world.entity.ai.goal.BegGoal; + import net.minecraft.world.entity.ai.goal.BreedGoal; + import net.minecraft.world.entity.ai.goal.FloatGoal; + import net.minecraft.world.entity.ai.goal.FollowOwnerGoal; ++import net.minecraft.world.entity.ai.goal.Goal; + import net.minecraft.world.entity.ai.goal.LeapAtTargetGoal; + import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal; + import net.minecraft.world.entity.ai.goal.MeleeAttackGoal; +@@ -59,6 +66,7 @@ import net.minecraft.world.item.Item; + import net.minecraft.world.item.ItemStack; + import net.minecraft.world.item.Items; + import net.minecraft.world.level.Level; ++import net.minecraft.world.level.ServerLevelAccessor; + import net.minecraft.world.level.block.state.BlockState; + import net.minecraft.world.level.gameevent.GameEvent; + import net.minecraft.world.phys.Vec3; +@@ -77,6 +85,37 @@ public class Wolf extends TamableAnimal implements NeutralMob { + + return entitytypes == EntityType.SHEEP || entitytypes == EntityType.RABBIT || entitytypes == EntityType.FOX; + }; ++ // Purpur start - rabid wolf spawn chance ++ private boolean isRabid = false; ++ private static final Predicate RABID_PREDICATE = entity -> entity instanceof ServerPlayer || entity instanceof Mob; ++ private final Goal PATHFINDER_VANILLA = new NonTameRandomTargetGoal<>(this, Animal.class, false, PREY_SELECTOR); ++ private final Goal PATHFINDER_RABID = new NonTameRandomTargetGoal<>(this, LivingEntity.class, false, RABID_PREDICATE); ++ private static final class AvoidRabidWolfGoal extends AvoidEntityGoal { ++ 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 + private static final float START_HEALTH = 8.0F; + private static final float TAME_HEALTH = 20.0F; + private float interestedAngle; +@@ -118,6 +157,37 @@ public class Wolf extends TamableAnimal implements NeutralMob { + public int getPurpurBreedTime() { + return this.level.purpurConfig.wolfBreedingTicks; + } ++ ++ 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) { ++ setTame(false); ++ setOwnerUUID(null); ++ this.targetSelector.addGoal(5, PATHFINDER_RABID); ++ if (modifyEffects) this.addEffect(new MobEffectInstance(MobEffects.CONFUSION, 1200)); ++ } else { ++ this.targetSelector.addGoal(5, PATHFINDER_VANILLA); ++ this.stopBeingAngry(); ++ if (modifyEffects) this.removeEffect(MobEffects.CONFUSION); ++ } ++ } ++ ++ @Override ++ public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType type, @Nullable SpawnGroupData data, @Nullable CompoundTag nbt) { ++ this.isRabid = level.purpurConfig.wolfNaturalRabid > 0.0D && random.nextDouble() <= level.purpurConfig.wolfNaturalRabid; ++ this.updatePathfinders(false); ++ return super.finalizeSpawn(world, difficulty, type, data, nbt); ++ } + // Purpur end + + @Override +@@ -126,6 +196,7 @@ public class Wolf extends TamableAnimal implements NeutralMob { + this.goalSelector.addGoal(1, new net.pl3x.purpur.entity.ai.HasRider(this)); // Purpur + this.goalSelector.addGoal(2, new SitWhenOrderedToGoal(this)); + this.goalSelector.addGoal(3, new Wolf.WolfAvoidEntityGoal<>(this, Llama.class, 24.0F, 1.5D, 1.5D)); ++ this.goalSelector.addGoal(3, new AvoidRabidWolfGoal(this, 24.0F, 1.5D, 1.5D)); // Purpur + this.goalSelector.addGoal(4, new LeapAtTargetGoal(this, 0.4F)); + this.goalSelector.addGoal(5, new MeleeAttackGoal(this, 1.0D, true)); + this.goalSelector.addGoal(6, new FollowOwnerGoal(this, 1.0D, 10.0F, 2.0F, false)); +@@ -139,7 +210,7 @@ public class Wolf extends TamableAnimal implements NeutralMob { + this.targetSelector.addGoal(2, new OwnerHurtTargetGoal(this)); + this.targetSelector.addGoal(3, (new HurtByTargetGoal(this, new Class[0])).setAlertOthers(new Class[0])); // CraftBukkit - decompile error + this.targetSelector.addGoal(4, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, this::isAngryAt)); +- this.targetSelector.addGoal(5, new NonTameRandomTargetGoal<>(this, Animal.class, false, Wolf.PREY_SELECTOR)); ++ // this.targetSelector.addGoal(5, new NonTameRandomTargetGoal<>(this, Animal.class, false, Wolf.PREY_SELECTOR)); // Purpur - 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)); +@@ -184,6 +255,7 @@ public class Wolf extends TamableAnimal implements NeutralMob { + public void addAdditionalSaveData(CompoundTag nbt) { + super.addAdditionalSaveData(nbt); + nbt.putByte("CollarColor", (byte) this.getCollarColor().getId()); ++ nbt.putBoolean("Purpur.IsRabid", this.isRabid); // Purpur + this.addPersistentAngerSaveData(nbt); + } + +@@ -193,6 +265,10 @@ public class Wolf extends TamableAnimal implements NeutralMob { + if (nbt.contains("CollarColor", 99)) { + this.setCollarColor(DyeColor.byId(nbt.getInt("CollarColor"))); + } ++ // Purpur start ++ this.isRabid = nbt.getBoolean("Purpur.IsRabid"); ++ this.updatePathfinders(false); ++ // Purpur end + + this.readPersistentAngerSaveData(this.level, nbt); + } +@@ -237,6 +313,11 @@ public class Wolf extends TamableAnimal implements NeutralMob { + public void tick() { + super.tick(); + if (this.isAlive()) { ++ // Purpur start ++ if (this.age % 300 == 0 && this.isRabid()) { ++ this.addEffect(new MobEffectInstance(MobEffects.CONFUSION, 400)); ++ } ++ // Purpur end + this.interestedAngleO = this.interestedAngle; + if (this.isInterested()) { + this.interestedAngle += (1.0F - this.interestedAngle) * 0.4F; +@@ -434,6 +515,20 @@ public class Wolf extends TamableAnimal implements NeutralMob { + + return InteractionResult.SUCCESS; + } ++ // Purpur start ++ else if (this.level.purpurConfig.wolfMilkCuresRabies && itemstack.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).sendParticles(((ServerLevel) level).players, null, ParticleTypes.HAPPY_VILLAGER, ++ 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, true); ++ } ++ return InteractionResult.SUCCESS; ++ } ++ // Purpur end + + return super.mobInteract(player, hand); + } +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index 9a48046093f3de6f68c5e33adbbe5ea3090315ec..69abb2cee655040032d3300591689b5f99bb879b 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -1739,6 +1739,8 @@ public class PurpurWorldConfig { + public boolean wolfRidable = false; + public boolean wolfRidableInWater = false; + public double wolfMaxHealth = 8.0D; ++ public boolean wolfMilkCuresRabies = true; ++ public double wolfNaturalRabid = 0.0D; + public int wolfBreedingTicks = 6000; + private void wolfSettings() { + wolfRidable = getBoolean("mobs.wolf.ridable", wolfRidable); +@@ -1749,6 +1751,8 @@ public class PurpurWorldConfig { + set("mobs.wolf.attributes.max_health", oldValue); + } + wolfMaxHealth = getDouble("mobs.wolf.attributes.max_health", wolfMaxHealth); ++ wolfMilkCuresRabies = getBoolean("mobs.wolf.milk-cures-rabid-wolves", wolfMilkCuresRabies); ++ wolfNaturalRabid = getDouble("mobs.wolf.spawn-rabid-chance", wolfNaturalRabid); + wolfBreedingTicks = getInt("mobs.wolf.breeding-delay-ticks", wolfBreedingTicks); + } + +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java +index f856b42201c17f8da21251e54fcf052336916e70..ac0803d42be2f36a2f40487ee31413d059d2f0e2 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java +@@ -43,4 +43,16 @@ public class CraftWolf extends CraftTameableAnimal implements Wolf { + public void setCollarColor(DyeColor color) { + this.getHandle().setCollarColor(net.minecraft.world.item.DyeColor.byId(color.getWoolData())); + } ++ ++ // Purpur start ++ @Override ++ public boolean isRabid() { ++ return getHandle().isRabid(); ++ } ++ ++ @Override ++ public void setRabid(boolean isRabid) { ++ getHandle().setRabid(isRabid); ++ } ++ // Purpur end + } diff --git a/patches/server/0140-Configurable-default-wolf-collar-color.patch b/patches/server/0140-Configurable-default-wolf-collar-color.patch new file mode 100644 index 000000000..aeea449d9 --- /dev/null +++ b/patches/server/0140-Configurable-default-wolf-collar-color.patch @@ -0,0 +1,57 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Encode42 +Date: Thu, 10 Dec 2020 13:43:28 -0500 +Subject: [PATCH] Configurable default wolf collar color + +This allows for the server to set a default collar color when a wolf is tamed. +Resets to RED when the value is invalid. + +diff --git a/src/main/java/net/minecraft/world/entity/animal/Wolf.java b/src/main/java/net/minecraft/world/entity/animal/Wolf.java +index 3e7409ebf1f94b9cf55f2d0b0fe17ca8ec44659f..518dd0e6b4889c049e438b393baa795a5eac3e7d 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/Wolf.java ++++ b/src/main/java/net/minecraft/world/entity/animal/Wolf.java +@@ -188,6 +188,12 @@ public class Wolf extends TamableAnimal implements NeutralMob { + this.updatePathfinders(false); + return super.finalizeSpawn(world, difficulty, type, data, nbt); + } ++ ++ @Override ++ public void tame(Player player) { ++ setCollarColor(level.purpurConfig.wolfDefaultCollarColor); ++ super.tame(player); ++ } + // Purpur end + + @Override +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index 69abb2cee655040032d3300591689b5f99bb879b..70a6f1bc6f0d8a057a65b95651ab547f48167f1c 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -3,6 +3,7 @@ package net.pl3x.purpur; + import net.minecraft.core.Registry; + import net.minecraft.resources.ResourceLocation; + import net.minecraft.world.Difficulty; ++import net.minecraft.world.item.DyeColor; + import net.minecraft.world.item.Item; + import net.minecraft.world.item.Items; + import net.minecraft.world.level.Explosion; +@@ -1739,6 +1740,7 @@ public class PurpurWorldConfig { + public boolean wolfRidable = false; + public boolean wolfRidableInWater = false; + public double wolfMaxHealth = 8.0D; ++ public DyeColor wolfDefaultCollarColor = DyeColor.RED; + public boolean wolfMilkCuresRabies = true; + public double wolfNaturalRabid = 0.0D; + public int wolfBreedingTicks = 6000; +@@ -1751,6 +1753,11 @@ public class PurpurWorldConfig { + set("mobs.wolf.attributes.max_health", oldValue); + } + wolfMaxHealth = getDouble("mobs.wolf.attributes.max_health", wolfMaxHealth); ++ try { ++ wolfDefaultCollarColor = DyeColor.valueOf(getString("mobs.wolf.default-collar-color", wolfDefaultCollarColor.name())); ++ } catch (IllegalArgumentException ignore) { ++ wolfDefaultCollarColor = DyeColor.RED; ++ } + wolfMilkCuresRabies = getBoolean("mobs.wolf.milk-cures-rabid-wolves", wolfMilkCuresRabies); + wolfNaturalRabid = getDouble("mobs.wolf.spawn-rabid-chance", wolfNaturalRabid); + wolfBreedingTicks = getInt("mobs.wolf.breeding-delay-ticks", wolfBreedingTicks); diff --git a/patches/server/0141-Phantom-flames-on-swoop.patch b/patches/server/0141-Phantom-flames-on-swoop.patch new file mode 100644 index 000000000..c475d3fdf --- /dev/null +++ b/patches/server/0141-Phantom-flames-on-swoop.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Sat, 12 Dec 2020 09:10:59 -0600 +Subject: [PATCH] Phantom flames on swoop + + +diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java +index 782d4499f925950d66072b63f34a828bcc51d2e7..3ea6f2d96245caa85f365c488b8cc019a8318009 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java ++++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java +@@ -227,6 +227,7 @@ public class Phantom extends FlyingMob implements Enemy { + this.level.addParticle(ParticleTypes.MYCELIUM, this.getX() - (double) f2, this.getY() + (double) f4, this.getZ() - (double) f3, 0.0D, 0.0D, 0.0D); + } + ++ if (level.purpurConfig.phantomFlamesOnSwoop && attackPhase == AttackPhase.SWOOP) shoot(); // Purpur + } + + @Override +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index 70a6f1bc6f0d8a057a65b95651ab547f48167f1c..98f02e3b3f257040f03deb5df8938edbd623ab0d 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -1146,6 +1146,7 @@ public class PurpurWorldConfig { + public float phantomFlameDamage = 1.0F; + public int phantomFlameFireTime = 8; + public boolean phantomAllowGriefing = false; ++ public boolean phantomFlamesOnSwoop = false; + public double phantomMaxHealth = 20.0D; + public double phantomAttackedByCrystalRadius = 0.0D; + public float phantomAttackedByCrystalDamage = 1.0F; +@@ -1172,6 +1173,7 @@ public class PurpurWorldConfig { + phantomFlameDamage = (float) getDouble("mobs.phantom.flames.damage", phantomFlameDamage); + phantomFlameFireTime = getInt("mobs.phantom.flames.fire-time", phantomFlameFireTime); + phantomAllowGriefing = getBoolean("mobs.phantom.allow-griefing", phantomAllowGriefing); ++ phantomFlamesOnSwoop = getBoolean("mobs.phantom.flames-on-swoop", phantomFlamesOnSwoop); + if (PurpurConfig.version < 10) { + double oldValue = getDouble("mobs.phantom.attributes.max-health", phantomMaxHealth); + set("mobs.phantom.attributes.max-health", null); diff --git a/patches/server/0142-Option-for-chests-to-open-even-with-a-solid-block-on.patch b/patches/server/0142-Option-for-chests-to-open-even-with-a-solid-block-on.patch new file mode 100644 index 000000000..7a94f9c11 --- /dev/null +++ b/patches/server/0142-Option-for-chests-to-open-even-with-a-solid-block-on.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> +Date: Sat, 12 Dec 2020 14:34:18 -0800 +Subject: [PATCH] Option for chests to open even with a solid block on top + + +diff --git a/src/main/java/net/minecraft/world/level/block/ChestBlock.java b/src/main/java/net/minecraft/world/level/block/ChestBlock.java +index d980a556785b52fe827310b83638139df0816b11..3c8c02fc92374def12254f7ffad604b2779117f6 100644 +--- a/src/main/java/net/minecraft/world/level/block/ChestBlock.java ++++ b/src/main/java/net/minecraft/world/level/block/ChestBlock.java +@@ -349,6 +349,7 @@ public class ChestBlock extends AbstractChestBlock implements + } + + private static boolean isBlockedChestByBlock(BlockGetter world, BlockPos pos) { ++ if (world instanceof Level && ((Level) world).purpurConfig.chestOpenWithBlockOnTop) return false; // Purpur + BlockPos blockposition1 = pos.above(); + + return world.getBlockState(blockposition1).isRedstoneConductor(world, blockposition1); +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index 98f02e3b3f257040f03deb5df8938edbd623ab0d..56010a52b16075e5307e33e02a9fb25b45ff0032 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -405,6 +405,11 @@ public class PurpurWorldConfig { + } + } + ++ public boolean chestOpenWithBlockOnTop = false; ++ private void chestSettings() { ++ chestOpenWithBlockOnTop = getBoolean("blocks.chest.open-with-solid-block-on-top", chestOpenWithBlockOnTop); ++ } ++ + public boolean dispenserApplyCursedArmor = true; + public boolean dispenserPlaceAnvils = false; + private void dispenserSettings() { diff --git a/patches/server-unmapped/0150-Implement-TPSBar.patch b/patches/server/0143-Implement-TPSBar.patch similarity index 68% rename from patches/server-unmapped/0150-Implement-TPSBar.patch rename to patches/server/0143-Implement-TPSBar.patch index f419817ec..70b06f623 100644 --- a/patches/server-unmapped/0150-Implement-TPSBar.patch +++ b/patches/server/0143-Implement-TPSBar.patch @@ -4,36 +4,36 @@ Date: Sat, 12 Dec 2020 21:19:05 -0600 Subject: [PATCH] Implement TPSBar -diff --git a/src/main/java/net/minecraft/commands/CommandDispatcher.java b/src/main/java/net/minecraft/commands/CommandDispatcher.java -index 0ea56c863a9a1019b36f7f9f9164301aef12637b..4338b459011bf7a083790b7bb76cf1b24471fd19 100644 ---- a/src/main/java/net/minecraft/commands/CommandDispatcher.java -+++ b/src/main/java/net/minecraft/commands/CommandDispatcher.java -@@ -193,6 +193,7 @@ public class CommandDispatcher { - CommandWhitelist.a(this.b); - net.pl3x.purpur.command.DemoCommand.register(getDispatcher()); // Purpur - net.pl3x.purpur.command.PingCommand.register(getDispatcher()); // Purpur -+ net.pl3x.purpur.command.TPSBarCommand.register(getDispatcher()); // Purpur +diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java +index 9cbaaf4cd138e6c1d2d51afcef24a81a3f2973c5..13e90bf9506862a4830b50dcce06cc95a6ada5e3 100644 +--- a/src/main/java/net/minecraft/commands/Commands.java ++++ b/src/main/java/net/minecraft/commands/Commands.java +@@ -200,6 +200,7 @@ public class Commands { + WhitelistCommand.register(this.dispatcher); + net.pl3x.purpur.command.DemoCommand.register(this.dispatcher); // Purpur + net.pl3x.purpur.command.PingCommand.register(this.dispatcher); // Purpur ++ net.pl3x.purpur.command.TPSBarCommand.register(this.dispatcher); // Purpur } - if (commanddispatcher_servertype.d) { + if (environment.includeIntegrated) { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 5c5da6e2be6d3a0ca2fee4e0a5510ccb15fa8020..ab49314a0b2fb70bab879be2adcf938bb43c5dcb 100644 +index 91e6d0b6560ffa8e870eca9707d5cd117fcb2347..d525bd371bedf75c24afd4a8a1240b31f91aa9da 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -991,6 +991,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant dispatcher) { -+ dispatcher.register(CommandDispatcher.literal("tpsbar") -+ .requires((listener) -> { -+ return listener.hasPermission(2); -+ }) -+ .executes((context) -> { -+ return execute(context.getSource(), context.getSource().getPlayerOrException()); -+ }) ++ public static void register(CommandDispatcher dispatcher) { ++ dispatcher.register(Commands.literal("tpsbar") ++ .requires(listener -> listener.hasPermission(2)) ++ .executes(context -> execute(context.getSource(), context.getSource().getPlayerOrException())) + ).setPermission("bukkit.command.tpsbar"); + } + -+ private static int execute(CommandListenerWrapper sender, EntityPlayer player) { ++ private static int execute(CommandSourceStack source, ServerPlayer player) { + if (player != null) { + TPSBarTask.togglePlayer(player.getBukkitEntity()); + return 1; @@ -89,7 +86,7 @@ index 0000000000000000000000000000000000000000..807f5709af7fd9497633ecfc9e932f0d +} diff --git a/src/main/java/net/pl3x/purpur/task/TPSBarTask.java b/src/main/java/net/pl3x/purpur/task/TPSBarTask.java new file mode 100644 -index 0000000000000000000000000000000000000000..a9d71d2b769b8e4e0f5039e997fc5ebc1cc9bfbb +index 0000000000000000000000000000000000000000..11791bbd4dbe4037f7a5b630be2ff1fa4d599513 --- /dev/null +++ b/src/main/java/net/pl3x/purpur/task/TPSBarTask.java @@ -0,0 +1,116 @@ @@ -140,7 +137,7 @@ index 0000000000000000000000000000000000000000..a9d71d2b769b8e4e0f5039e997fc5ebc + return; + } + -+ double tps = Bukkit.getTPS()[0]; ++ double tps = Bukkit.getTPS()[0]; + if (tps > 20.0D) { + tps = 20.0D; + } else if (tps < 0.0D) {