Merge branch 'ver/1.21.4' into feat/quiver-bundle

This commit is contained in:
granny
2025-01-30 12:20:21 -08:00
772 changed files with 33474 additions and 45822 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,219 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 23 May 2019 21:50:37 -0500
Subject: [PATCH] Barrels and enderchests 6 rows
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index 2d09f2a2c97f29ac0d941b7a3fb941102a5d545e..94abb9d8f6381aee000dbd0720477db8b7ca279c 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -1027,6 +1027,27 @@ public abstract class PlayerList {
player.getBukkitEntity().recalculatePermissions(); // CraftBukkit
this.server.getCommands().sendCommands(player);
} // Paper - Add sendOpLevel API
+
+ // Purpur start - Barrels and enderchests 6 rows
+ if (org.purpurmc.purpur.PurpurConfig.enderChestSixRows && org.purpurmc.purpur.PurpurConfig.enderChestPermissionRows) {
+ org.bukkit.craftbukkit.entity.CraftHumanEntity bukkit = player.getBukkitEntity();
+ if (bukkit.hasPermission("purpur.enderchest.rows.six")) {
+ player.sixRowEnderchestSlotCount = 54;
+ } else if (bukkit.hasPermission("purpur.enderchest.rows.five")) {
+ player.sixRowEnderchestSlotCount = 45;
+ } else if (bukkit.hasPermission("purpur.enderchest.rows.four")) {
+ player.sixRowEnderchestSlotCount = 36;
+ } else if (bukkit.hasPermission("purpur.enderchest.rows.three")) {
+ player.sixRowEnderchestSlotCount = 27;
+ } else if (bukkit.hasPermission("purpur.enderchest.rows.two")) {
+ player.sixRowEnderchestSlotCount = 18;
+ } else if (bukkit.hasPermission("purpur.enderchest.rows.one")) {
+ player.sixRowEnderchestSlotCount = 9;
+ }
+ } else {
+ player.sixRowEnderchestSlotCount = -1;
+ }
+ // Purpur end - Barrels and enderchests 6 rows
}
public boolean isWhiteListed(GameProfile profile) {
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
index ca998a8a480af63d4a5f58a1f4490528a7b33c69..43657822f0660613078e9afa512000b5255a1537 100644
--- a/net/minecraft/world/entity/player/Player.java
+++ b/net/minecraft/world/entity/player/Player.java
@@ -202,6 +202,7 @@ public abstract class Player extends LivingEntity {
public net.kyori.adventure.util.TriState flyingFallDamage = net.kyori.adventure.util.TriState.NOT_SET; // Paper - flying fall damage
public int burpDelay = 0; // Purpur - Burp delay
public boolean canPortalInstant = false; // Purpur - Add portal permission bypass
+ public int sixRowEnderchestSlotCount = -1; // Purpur - Barrels and enderchests 6 rows
// CraftBukkit start
public boolean fauxSleeping;
diff --git a/net/minecraft/world/inventory/ChestMenu.java b/net/minecraft/world/inventory/ChestMenu.java
index 280169afbd637eeb67ddf7eaeb4eecd464a128d5..ba7730a24831efa33de4c5ffce57bfa7177f89d6 100644
--- a/net/minecraft/world/inventory/ChestMenu.java
+++ b/net/minecraft/world/inventory/ChestMenu.java
@@ -66,10 +66,30 @@ public class ChestMenu extends AbstractContainerMenu {
return new ChestMenu(MenuType.GENERIC_9x6, containerId, playerInventory, 6);
}
+ // Purpur start - Barrels and enderchests 6 rows
+ public static ChestMenu oneRow(int syncId, Inventory playerInventory, Container inventory) {
+ return new ChestMenu(MenuType.GENERIC_9x1, syncId, playerInventory, inventory, 1);
+ }
+
+ public static ChestMenu twoRows(int syncId, Inventory playerInventory, Container inventory) {
+ return new ChestMenu(MenuType.GENERIC_9x2, syncId, playerInventory, inventory, 2);
+ }
+ // Purpur end - Barrels and enderchests 6 rows
+
public static ChestMenu threeRows(int containerId, Inventory playerInventory, Container container) {
return new ChestMenu(MenuType.GENERIC_9x3, containerId, playerInventory, container, 3);
}
+ // Purpur start - Barrels and enderchests 6 rows
+ public static ChestMenu fourRows(int syncId, Inventory playerInventory, Container inventory) {
+ return new ChestMenu(MenuType.GENERIC_9x4, syncId, playerInventory, inventory, 4);
+ }
+
+ public static ChestMenu fiveRows(int syncId, Inventory playerInventory, Container inventory) {
+ return new ChestMenu(MenuType.GENERIC_9x5, syncId, playerInventory, inventory, 5);
+ }
+ // Purpur end - Barrels and enderchests 6 rows
+
public static ChestMenu sixRows(int containerId, Inventory playerInventory, Container container) {
return new ChestMenu(MenuType.GENERIC_9x6, containerId, playerInventory, container, 6);
}
diff --git a/net/minecraft/world/inventory/PlayerEnderChestContainer.java b/net/minecraft/world/inventory/PlayerEnderChestContainer.java
index a6a359bab2a727f4631b633a8bb370dd40decc75..d2d75e5c34c97300ce5da8c7ea70958aba31fa4a 100644
--- a/net/minecraft/world/inventory/PlayerEnderChestContainer.java
+++ b/net/minecraft/world/inventory/PlayerEnderChestContainer.java
@@ -25,11 +25,18 @@ public class PlayerEnderChestContainer extends SimpleContainer {
}
public PlayerEnderChestContainer(Player owner) {
- super(27);
+ super(org.purpurmc.purpur.PurpurConfig.enderChestSixRows ? 54 : 27); // Purpur - Barrels and enderchests 6 rows
this.owner = owner;
// CraftBukkit end
}
+ // Purpur start - Barrels and enderchests 6 rows
+ @Override
+ public int getContainerSize() {
+ return owner.sixRowEnderchestSlotCount < 0 ? super.getContainerSize() : owner.sixRowEnderchestSlotCount;
+ }
+ // Purpur end - Barrels and enderchests 6 rows
+
public void setActiveChest(EnderChestBlockEntity enderChestBlockEntity) {
this.activeChest = enderChestBlockEntity;
}
diff --git a/net/minecraft/world/level/block/EnderChestBlock.java b/net/minecraft/world/level/block/EnderChestBlock.java
index f5533960708bdbaf2eacefbc7c7c3123b7d26502..17aa27885b4431bf7b98799e02d080b5a0ecbbf1 100644
--- a/net/minecraft/world/level/block/EnderChestBlock.java
+++ b/net/minecraft/world/level/block/EnderChestBlock.java
@@ -85,8 +85,8 @@ public class EnderChestBlock extends AbstractChestBlock<EnderChestBlockEntity> i
enderChestInventory.setActiveChest(enderChestBlockEntity); // Needs to happen before ChestMenu.threeRows as it is required for opening animations
if (level instanceof ServerLevel serverLevel && player.openMenu(
new SimpleMenuProvider(
- (containerId, playerInventory, player1) -> ChestMenu.threeRows(containerId, playerInventory, enderChestInventory), CONTAINER_TITLE
- )
+ (containerId, playerInventory, player1) -> org.purpurmc.purpur.PurpurConfig.enderChestSixRows ? getEnderChestSixRows(containerId, playerInventory, player, enderChestInventory) : ChestMenu.threeRows(containerId, playerInventory, enderChestInventory), CONTAINER_TITLE
+ ) // Purpur - Barrels and enderchests 6 rows
).isPresent()) {
// Paper end - Fix InventoryOpenEvent cancellation - moved up;
player.awardStat(Stats.OPEN_ENDERCHEST);
@@ -100,6 +100,35 @@ public class EnderChestBlock extends AbstractChestBlock<EnderChestBlockEntity> i
}
}
+ // Purpur start - Barrels and enderchests 6 rows
+ private ChestMenu getEnderChestSixRows(int syncId, net.minecraft.world.entity.player.Inventory inventory, Player player, PlayerEnderChestContainer playerEnderChestContainer) {
+ if (org.purpurmc.purpur.PurpurConfig.enderChestPermissionRows) {
+ org.bukkit.craftbukkit.entity.CraftHumanEntity bukkitPlayer = player.getBukkitEntity();
+ if (bukkitPlayer.hasPermission("purpur.enderchest.rows.six")) {
+ player.sixRowEnderchestSlotCount = 54;
+ return ChestMenu.sixRows(syncId, inventory, playerEnderChestContainer);
+ } else if (bukkitPlayer.hasPermission("purpur.enderchest.rows.five")) {
+ player.sixRowEnderchestSlotCount = 45;
+ return ChestMenu.fiveRows(syncId, inventory, playerEnderChestContainer);
+ } else if (bukkitPlayer.hasPermission("purpur.enderchest.rows.four")) {
+ player.sixRowEnderchestSlotCount = 36;
+ return ChestMenu.fourRows(syncId, inventory, playerEnderChestContainer);
+ } else if (bukkitPlayer.hasPermission("purpur.enderchest.rows.three")) {
+ player.sixRowEnderchestSlotCount = 27;
+ return ChestMenu.threeRows(syncId, inventory, playerEnderChestContainer);
+ } else if (bukkitPlayer.hasPermission("purpur.enderchest.rows.two")) {
+ player.sixRowEnderchestSlotCount = 18;
+ return ChestMenu.twoRows(syncId, inventory, playerEnderChestContainer);
+ } else if (bukkitPlayer.hasPermission("purpur.enderchest.rows.one")) {
+ player.sixRowEnderchestSlotCount = 9;
+ return ChestMenu.oneRow(syncId, inventory, playerEnderChestContainer);
+ }
+ }
+ player.sixRowEnderchestSlotCount = -1;
+ return ChestMenu.sixRows(syncId, inventory, playerEnderChestContainer);
+ }
+ // Purpur end - Barrels and enderchests 6 rows
+
@Override
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
return new EnderChestBlockEntity(pos, state);
diff --git a/net/minecraft/world/level/block/entity/BarrelBlockEntity.java b/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
index 0f808855f58281578c2758513787f0f7330c9291..9f6063089f0aa3a68d26ae7cfe39379123ab2f47 100644
--- a/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
@@ -55,7 +55,17 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity {
this.maxStack = i;
}
// CraftBukkit end
- private NonNullList<ItemStack> items = NonNullList.withSize(27, ItemStack.EMPTY);
+ // Purpur start - Barrels and enderchests 6 rows
+ private NonNullList<ItemStack> items = NonNullList.withSize(switch (org.purpurmc.purpur.PurpurConfig.barrelRows) {
+ case 6 -> 54;
+ case 5 -> 45;
+ case 4 -> 36;
+ case 2 -> 18;
+ case 1 -> 9;
+ default -> 27;
+ }, ItemStack.EMPTY);
+ // Purpur end - Barrels and enderchests 6 rows
+
public final ContainerOpenersCounter openersCounter = new ContainerOpenersCounter() {
@Override
protected void onOpen(Level level, BlockPos pos, BlockState state) {
@@ -107,7 +117,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity {
@Override
public int getContainerSize() {
- return 27;
+ // Purpur start - Barrels and enderchests 6 rows
+ return switch (org.purpurmc.purpur.PurpurConfig.barrelRows) {
+ case 6 -> 54;
+ case 5 -> 45;
+ case 4 -> 36;
+ case 2 -> 18;
+ case 1 -> 9;
+ default -> 27;
+ };
+ // Purpur end - Barrels and enderchests 6 rows
}
@Override
@@ -127,7 +146,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity {
@Override
protected AbstractContainerMenu createMenu(int id, Inventory player) {
- return ChestMenu.threeRows(id, player, this);
+ // Purpur start - Barrels and enderchests 6 rows
+ return switch (org.purpurmc.purpur.PurpurConfig.barrelRows) {
+ case 6 -> ChestMenu.sixRows(id, player, this);
+ case 5 -> ChestMenu.fiveRows(id, player, this);
+ case 4 -> ChestMenu.fourRows(id, player, this);
+ case 2 -> ChestMenu.twoRows(id, player, this);
+ case 1 -> ChestMenu.oneRow(id, player, this);
+ default -> ChestMenu.threeRows(id, player, this);
+ };
+ // Purpur end - Barrels and enderchests 6 rows
}
@Override

View File

@@ -0,0 +1,76 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sun, 12 May 2019 00:43:12 -0500
Subject: [PATCH] Giants AI settings
diff --git a/net/minecraft/world/entity/monster/Giant.java b/net/minecraft/world/entity/monster/Giant.java
index 13021800af7cc9263ef4f393f9cfbda5061a32ae..73da18c4b54e250c434fd75971ef0a8f7c8cf6a3 100644
--- a/net/minecraft/world/entity/monster/Giant.java
+++ b/net/minecraft/world/entity/monster/Giant.java
@@ -30,8 +30,25 @@ public class Giant extends Monster {
@Override
protected void registerGoals() {
- this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this));
- this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this));
+ // Purpur start - Giants AI settings
+ if (level().purpurConfig.giantHaveAI) {
+ this.goalSelector.addGoal(0, new net.minecraft.world.entity.ai.goal.FloatGoal(this));
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this));
+ this.goalSelector.addGoal(7, new net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal(this, 1.0D));
+ this.goalSelector.addGoal(8, new net.minecraft.world.entity.ai.goal.LookAtPlayerGoal(this, net.minecraft.world.entity.player.Player.class, 16.0F));
+ this.goalSelector.addGoal(8, new net.minecraft.world.entity.ai.goal.RandomLookAroundGoal(this));
+ this.goalSelector.addGoal(5, new net.minecraft.world.entity.ai.goal.MoveTowardsRestrictionGoal(this, 1.0D));
+ if (level().purpurConfig.giantHaveHostileAI) {
+ this.goalSelector.addGoal(2, new net.minecraft.world.entity.ai.goal.MeleeAttackGoal(this, 1.0D, false));
+ this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this));
+ this.targetSelector.addGoal(1, new net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal(this).setAlertOthers(ZombifiedPiglin.class));
+ this.targetSelector.addGoal(2, new net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal<>(this, net.minecraft.world.entity.player.Player.class, true));
+ this.targetSelector.addGoal(3, new net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal<>(this, net.minecraft.world.entity.npc.Villager.class, false));
+ this.targetSelector.addGoal(4, new net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal<>(this, net.minecraft.world.entity.animal.IronGolem.class, true));
+ this.targetSelector.addGoal(5, new net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal<>(this, net.minecraft.world.entity.animal.Turtle.class, true));
+ }
+ }
+ // Purpur end - Giants AI settings
}
// Purpur end - Ridables
@@ -49,8 +66,36 @@ public class Giant extends Monster {
return Monster.createMonsterAttributes().add(Attributes.MAX_HEALTH, 100.0).add(Attributes.MOVEMENT_SPEED, 0.5).add(Attributes.ATTACK_DAMAGE, 50.0);
}
+ // Purpur - Giants AI settings
+ @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, @org.jetbrains.annotations.Nullable net.minecraft.world.entity.SpawnGroupData entityData) {
+ net.minecraft.world.entity.SpawnGroupData groupData = super.finalizeSpawn(world, difficulty, spawnReason, entityData);
+ if (groupData == null) {
+ populateDefaultEquipmentSlots(this.random, difficulty);
+ populateDefaultEquipmentEnchantments(world, this.random, difficulty);
+ }
+ return groupData;
+ }
+
+ @Override
+ protected void populateDefaultEquipmentSlots(net.minecraft.util.RandomSource random, net.minecraft.world.DifficultyInstance difficulty) {
+ super.populateDefaultEquipmentSlots(this.random, difficulty);
+ // TODO make configurable
+ if (random.nextFloat() < (level().getDifficulty() == net.minecraft.world.Difficulty.HARD ? 0.1F : 0.05F)) {
+ this.setItemSlot(net.minecraft.world.entity.EquipmentSlot.MAINHAND, new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.IRON_SWORD));
+ }
+ }
+
+ @Override
+ public float getJumpPower() {
+ // make giants jump as high as everything else relative to their size
+ // 1.0 makes bottom of feet about as high as their waist when they jump
+ return level().purpurConfig.giantJumpHeight;
+ }
+ // Purpur end - Giants AI settings
+
@Override
public float getWalkTargetValue(BlockPos pos, LevelReader level) {
- return level.getPathfindingCostFromLightLevels(pos);
+ return super.getWalkTargetValue(pos, level); // Purpur - Giants AI settings - fix light requirements for natural spawns
}
}

View File

@@ -0,0 +1,54 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sun, 12 Apr 2020 13:19:34 -0500
Subject: [PATCH] Chickens can retaliate
diff --git a/net/minecraft/world/entity/animal/Chicken.java b/net/minecraft/world/entity/animal/Chicken.java
index 509163f409a5b8988a484aedb2f3ddf042d5eb13..d718f0ed362c49803260dceed64bd93e2b6744fc 100644
--- a/net/minecraft/world/entity/animal/Chicken.java
+++ b/net/minecraft/world/entity/animal/Chicken.java
@@ -73,6 +73,11 @@ public class Chicken extends Animal {
public void initAttributes() {
this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.chickenMaxHealth);
this.getAttribute(Attributes.SCALE).setBaseValue(this.level().purpurConfig.chickenScale);
+ // Purpur start - Chickens can retaliate
+ if (level().purpurConfig.chickenRetaliate) {
+ this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(2.0D);
+ }
+ // Purpur end - Chickens can retaliate
}
// Purpur end - Configurable entity base attributes
@@ -80,13 +85,21 @@ public class Chicken extends Animal {
protected void registerGoals() {
this.goalSelector.addGoal(0, new FloatGoal(this));
this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
- this.goalSelector.addGoal(1, new PanicGoal(this, 1.4));
+ //this.goalSelector.addGoal(1, new PanicGoal(this, 1.4)); // Purpur - Chickens can retaliate - moved down
this.goalSelector.addGoal(2, new BreedGoal(this, 1.0));
this.goalSelector.addGoal(3, new TemptGoal(this, 1.0, itemStack -> itemStack.is(ItemTags.CHICKEN_FOOD), false));
this.goalSelector.addGoal(4, new FollowParentGoal(this, 1.1));
this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 1.0));
this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 6.0F));
this.goalSelector.addGoal(7, new RandomLookAroundGoal(this));
+ // Purpur start - Chickens can retaliate
+ if (level().purpurConfig.chickenRetaliate) {
+ this.goalSelector.addGoal(1, new net.minecraft.world.entity.ai.goal.MeleeAttackGoal(this, 1.0D, false));
+ this.targetSelector.addGoal(1, new net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal(this));
+ } else {
+ this.goalSelector.addGoal(1, new PanicGoal(this, 1.4D));
+ }
+ // Purpur end - Chickens can retaliate
}
@Override
@@ -95,7 +108,7 @@ public class Chicken extends Animal {
}
public static AttributeSupplier.Builder createAttributes() {
- return Animal.createAnimalAttributes().add(Attributes.MAX_HEALTH, 4.0).add(Attributes.MOVEMENT_SPEED, 0.25);
+ return Animal.createAnimalAttributes().add(Attributes.MAX_HEALTH, 4.0).add(Attributes.MOVEMENT_SPEED, 0.25).add(Attributes.ATTACK_DAMAGE, 0.0D); // Purpur - Chickens can retaliate
}
@Override

View File

@@ -0,0 +1,152 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sat, 29 Jun 2019 02:32:40 -0500
Subject: [PATCH] Minecart settings and WASD controls
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index d77381237f8a7d1b2f280a5032f5e1c8f0ab8f94..9a88ca440fad04b5941cda125c6a39d24adf6d37 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -1240,6 +1240,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
} else {
// Purpur start - Add boat fall damage config
if (damageSource.is(net.minecraft.tags.DamageTypeTags.IS_FALL)) {
+ // Purpur start - Minecart settings and WASD controls
+ if (getRootVehicle() instanceof net.minecraft.world.entity.vehicle.AbstractMinecart && level().purpurConfig.minecartControllable && !level().purpurConfig.minecartControllableFallDamage) {
+ return false;
+ }
+ // Purpur end - Minecart settings and WASD controls
if (getRootVehicle() instanceof net.minecraft.world.entity.vehicle.Boat && !level().purpurConfig.boatsDoFallDamage) {
return false;
}
diff --git a/net/minecraft/world/entity/vehicle/AbstractMinecart.java b/net/minecraft/world/entity/vehicle/AbstractMinecart.java
index 9e15e7159cf98b3928110df9eae6de93793bf44e..6df4d736d94b9e49a3eb3d59a329e37127aa64cd 100644
--- a/net/minecraft/world/entity/vehicle/AbstractMinecart.java
+++ b/net/minecraft/world/entity/vehicle/AbstractMinecart.java
@@ -83,6 +83,10 @@ public abstract class AbstractMinecart extends VehicleEntity {
private double flyingY = 0.95;
private double flyingZ = 0.95;
public Double maxSpeed;
+ // Purpur start - Minecart settings and WASD controls
+ public double storedMaxSpeed;
+ public boolean isNewBehavior;
+ // Purpur end - Minecart settings and WASD controls
public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API
// CraftBukkit end
@@ -91,8 +95,13 @@ public abstract class AbstractMinecart extends VehicleEntity {
this.blocksBuilding = true;
if (useExperimentalMovement(level)) {
this.behavior = new NewMinecartBehavior(this);
+ this.isNewBehavior = true; // Purpur - Minecart settings and WASD controls
} else {
this.behavior = new OldMinecartBehavior(this);
+ // Purpur start - Minecart settings and WASD controls
+ this.isNewBehavior = false;
+ maxSpeed = storedMaxSpeed = level.purpurConfig.minecartMaxSpeed;
+ // Purpur end - Minecart settings and WASD controls
}
}
@@ -258,6 +267,14 @@ public abstract class AbstractMinecart extends VehicleEntity {
@Override
public void tick() {
+ // Purpur start - Minecart settings and WASD controls
+ if (!this.isNewBehavior) {
+ if (storedMaxSpeed != level().purpurConfig.minecartMaxSpeed) {
+ maxSpeed = storedMaxSpeed = level().purpurConfig.minecartMaxSpeed;
+ }
+ }
+ // Purpur end - Minecart settings and WASD controls
+
// CraftBukkit start
double prevX = this.getX();
double prevY = this.getY();
@@ -394,15 +411,61 @@ public abstract class AbstractMinecart extends VehicleEntity {
this.behavior.moveAlongTrack(level);
}
+ // Purpur start - Minecart settings and WASD controls
+ private Double lastSpeed;
+
+ public double getControllableSpeed() {
+ BlockState blockState = level().getBlockState(this.blockPosition());
+ if (!blockState.isSolid()) {
+ blockState = level().getBlockState(this.blockPosition().relative(Direction.DOWN));
+ }
+ Double speed = level().purpurConfig.minecartControllableBlockSpeeds.get(blockState.getBlock());
+ if (!blockState.isSolid()) {
+ speed = lastSpeed;
+ }
+ if (speed == null) {
+ speed = level().purpurConfig.minecartControllableBaseSpeed;
+ }
+ return lastSpeed = speed;
+ }
+ // Purpur end - Minecart settings and WASD controls
+
protected void comeOffTrack(ServerLevel level) {
double maxSpeed = this.getMaxSpeed(level);
Vec3 deltaMovement = this.getDeltaMovement();
this.setDeltaMovement(Mth.clamp(deltaMovement.x, -maxSpeed, maxSpeed), deltaMovement.y, Mth.clamp(deltaMovement.z, -maxSpeed, maxSpeed));
+
+ // Purpur start - Minecart settings and WASD controls
+ if (level().purpurConfig.minecartControllable && !isInWater() && !isInLava() && !passengers.isEmpty()) {
+ Entity passenger = passengers.get(0);
+ if (passenger instanceof net.minecraft.server.level.ServerPlayer player) {
+ net.minecraft.world.entity.player.Input lastClientInput = player.getLastClientInput();
+ float forward = (lastClientInput.forward() == lastClientInput.backward() ? 0.0F : lastClientInput.forward() ? 1.0F : -1.0F);
+ if (lastClientInput.jump() && this.onGround) {
+ setDeltaMovement(new Vec3(getDeltaMovement().x, level().purpurConfig.minecartControllableHopBoost, getDeltaMovement().z));
+ }
+ if (forward != 0.0F) {
+ org.bukkit.util.Vector velocity = player.getBukkitEntity().getEyeLocation().getDirection().normalize().multiply(getControllableSpeed());
+ if (forward < 0.0) {
+ velocity.multiply(-0.5);
+ }
+ setDeltaMovement(new Vec3(velocity.getX(), getDeltaMovement().y, velocity.getZ()));
+ }
+ this.setYRot(passenger.getYRot() - 90);
+ maxUpStep = level().purpurConfig.minecartControllableStepHeight;
+ } else {
+ maxUpStep = 0.0F;
+ }
+ } else {
+ maxUpStep = 0.0F;
+ }
+ // Purpur end - Minecart settings and WASD controls
if (this.onGround()) {
// CraftBukkit start - replace magic numbers with our variables
this.setDeltaMovement(new Vec3(this.getDeltaMovement().x * this.derailedX, this.getDeltaMovement().y * this.derailedY, this.getDeltaMovement().z * this.derailedZ));
// CraftBukkit end
}
+ else if (level().purpurConfig.minecartControllable) setDeltaMovement(new Vec3(getDeltaMovement().x * derailedX, getDeltaMovement().y, getDeltaMovement().z * derailedZ)); // Purpur - Minecart settings and WASD controls
this.move(MoverType.SELF, this.getDeltaMovement());
if (!this.onGround()) {
diff --git a/net/minecraft/world/item/MinecartItem.java b/net/minecraft/world/item/MinecartItem.java
index 620069daba04d48b57fc933328eda77f6ca9333e..0403b9b01994269d394820e8c8710ba1b9808bf0 100644
--- a/net/minecraft/world/item/MinecartItem.java
+++ b/net/minecraft/world/item/MinecartItem.java
@@ -30,8 +30,9 @@ public class MinecartItem extends Item {
BlockPos clickedPos = context.getClickedPos();
BlockState blockState = level.getBlockState(clickedPos);
if (!blockState.is(BlockTags.RAILS)) {
- return InteractionResult.FAIL;
- } else {
+ if (!level.purpurConfig.minecartPlaceAnywhere) return InteractionResult.FAIL; // Purpur - Minecart settings and WASD controls
+ if (blockState.isSolid()) clickedPos = clickedPos.relative(context.getClickedFace());
+ } // else { // Purpur - Minecart settings and WASD controls
ItemStack itemInHand = context.getItemInHand();
RailShape railShape = blockState.getBlock() instanceof BaseRailBlock
? blockState.getValue(((BaseRailBlock)blockState.getBlock()).getShapeProperty())
@@ -72,6 +73,6 @@ public class MinecartItem extends Item {
itemInHand.shrink(1);
return InteractionResult.SUCCESS;
}
- }
+ // } // Purpur - Minecart settings and WASD controls
}
}

View File

@@ -0,0 +1,103 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Fri, 29 Nov 2019 22:10:12 -0600
Subject: [PATCH] Villagers follow emerald blocks
diff --git a/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java b/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java
index 61ed4d687120fcbb7b91863e400f3657ebcde687..e773c426567964fc8269237d71c3434a5473985c 100644
--- a/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java
+++ b/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java
@@ -162,7 +162,7 @@ public class DefaultAttributes {
.put(EntityType.VILLAGER, Villager.createAttributes().build())
.put(EntityType.VINDICATOR, Vindicator.createAttributes().build())
.put(EntityType.WARDEN, Warden.createAttributes().build())
- .put(EntityType.WANDERING_TRADER, Mob.createMobAttributes().build())
+ .put(EntityType.WANDERING_TRADER, net.minecraft.world.entity.npc.WanderingTrader.createAttributes().build()) // Purpur - Villagers follow emerald blocks
.put(EntityType.WITCH, Witch.createAttributes().build())
.put(EntityType.WITHER, WitherBoss.createAttributes().build())
.put(EntityType.WITHER_SKELETON, AbstractSkeleton.createAttributes().build())
diff --git a/net/minecraft/world/entity/ai/goal/TemptGoal.java b/net/minecraft/world/entity/ai/goal/TemptGoal.java
index 438d6347778a94b4fe430320b268a2d67afa209a..f88f618d34fb343b31de3af1a875d6633703df71 100644
--- a/net/minecraft/world/entity/ai/goal/TemptGoal.java
+++ b/net/minecraft/world/entity/ai/goal/TemptGoal.java
@@ -58,7 +58,7 @@ public class TemptGoal extends Goal {
}
private boolean shouldFollow(LivingEntity entity) {
- return this.items.test(entity.getMainHandItem()) || this.items.test(entity.getOffhandItem());
+ return (this.items.test(entity.getMainHandItem()) || this.items.test(entity.getOffhandItem())) && (!(this.mob instanceof net.minecraft.world.entity.npc.Villager villager) || !villager.isSleeping()); // Purpur - Villagers follow emerald blocks
}
@Override
diff --git a/net/minecraft/world/entity/npc/AbstractVillager.java b/net/minecraft/world/entity/npc/AbstractVillager.java
index a71d16d968bb90fd7aca6f01a3dd56df4f9a7ce6..b4e79cac5611942240ce85120f7bbee329ae2fb8 100644
--- a/net/minecraft/world/entity/npc/AbstractVillager.java
+++ b/net/minecraft/world/entity/npc/AbstractVillager.java
@@ -45,6 +45,8 @@ import org.bukkit.event.entity.VillagerAcquireTradeEvent;
// CraftBukkit end
public abstract class AbstractVillager extends AgeableMob implements InventoryCarrier, Npc, Merchant {
+ static final net.minecraft.world.item.crafting.Ingredient TEMPT_ITEMS = net.minecraft.world.item.crafting.Ingredient.of(net.minecraft.world.level.block.Blocks.EMERALD_BLOCK.asItem()); // Purpur - Villagers follow emerald blocks
+
// CraftBukkit start
@Override
public CraftMerchant getCraftMerchant() {
diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java
index c4ce3a2f03bb7665beb131892288d8e4f722a4b5..ff07cfe07200be23f17310522d737fca3251a580 100644
--- a/net/minecraft/world/entity/npc/Villager.java
+++ b/net/minecraft/world/entity/npc/Villager.java
@@ -265,6 +265,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
@Override
protected void registerGoals() {
this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this));
+ if (level().purpurConfig.villagerFollowEmeraldBlock) this.goalSelector.addGoal(3, new net.minecraft.world.entity.ai.goal.TemptGoal(this, 1.0D, TEMPT_ITEMS, false)); // Purpur - Villagers follow emerald blocks
}
// Purpur end - Ridables
@@ -273,6 +274,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
public void initAttributes() {
this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.villagerMaxHealth);
this.getAttribute(Attributes.SCALE).setBaseValue(this.level().purpurConfig.villagerScale);
+ this.getAttribute(Attributes.TEMPT_RANGE).setBaseValue(this.level().purpurConfig.villagerTemptRange); // Purpur - Villagers follow emerald blocks
}
// Purpur end - Configurable entity base attributes
@@ -341,7 +343,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
}
public static AttributeSupplier.Builder createAttributes() {
- return Mob.createMobAttributes().add(Attributes.MOVEMENT_SPEED, 0.5);
+ return Mob.createMobAttributes().add(Attributes.MOVEMENT_SPEED, 0.5).add(Attributes.TEMPT_RANGE, 10.0D); // Purpur - Villagers follow emerald blocks
}
public boolean assignProfessionWhenSpawned() {
diff --git a/net/minecraft/world/entity/npc/WanderingTrader.java b/net/minecraft/world/entity/npc/WanderingTrader.java
index 5d5fa6b4ad18b4213f5098e4d708f3301a6f59c6..4ba2921dd99f674344fe3371332c9b23365d3aa2 100644
--- a/net/minecraft/world/entity/npc/WanderingTrader.java
+++ b/net/minecraft/world/entity/npc/WanderingTrader.java
@@ -97,9 +97,16 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill
@Override
public void initAttributes() {
this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.wanderingTraderMaxHealth);
+ this.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.TEMPT_RANGE).setBaseValue(this.level().purpurConfig.wanderingTraderTemptRange); // Purpur - Villagers follow emerald blocks
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Villagers follow emerald blocks
+ public static net.minecraft.world.entity.ai.attributes.AttributeSupplier.Builder createAttributes() {
+ return Mob.createMobAttributes().add(net.minecraft.world.entity.ai.attributes.Attributes.TEMPT_RANGE, 10.0D);
+ }
+ // Purpur end - Villagers follow emerald blocks
+
@Override
protected void registerGoals() {
this.goalSelector.addGoal(0, new FloatGoal(this));
@@ -134,6 +141,7 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill
this.goalSelector.addGoal(1, new PanicGoal(this, 0.5));
this.goalSelector.addGoal(1, new LookAtTradingPlayerGoal(this));
this.goalSelector.addGoal(2, new WanderingTrader.WanderToPositionGoal(this, 2.0, 0.35));
+ if (level().purpurConfig.wanderingTraderFollowEmeraldBlock) this.goalSelector.addGoal(3, new net.minecraft.world.entity.ai.goal.TemptGoal(this, 1.0D, TEMPT_ITEMS, false)); // Purpur - Villagers follow emerald blocks
this.goalSelector.addGoal(4, new MoveTowardsRestrictionGoal(this, 0.35));
this.goalSelector.addGoal(8, new WaterAvoidingRandomStrollGoal(this, 0.35));
this.goalSelector.addGoal(9, new InteractGoal(this, Player.class, 3.0F, 1.0F));

View File

@@ -0,0 +1,49 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 27 Feb 2020 21:42:19 -0600
Subject: [PATCH] Configurable void damage height and damage
temporarily migrate to paper's config
drop patch on the next minecraft release
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 9afbfe9bf493e09ca1963e8956ab7573964479b4..d04c06fafd133f773f311e7c2708fa8b049da67c 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -1222,6 +1222,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
// Purpur end - config for startup commands
+ // Purpur start - Configurable void damage height and damage
+ if (org.purpurmc.purpur.configuration.transformation.VoidDamageHeightMigration.HAS_BEEN_REGISTERED) {
+ try {
+ org.purpurmc.purpur.PurpurConfig.config.save((java.io.File) this.options.valueOf("purpur-settings"));
+ } catch (IOException ex) {
+ org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.SEVERE, "Could not save " + this.options.valueOf("purpur-settings"), ex);
+ }
+ }
+ // Purpur end - Configurable void damage height and damage
+
while (this.running) {
long l;
if (!this.isPaused() && this.tickRateManager.isSprinting() && this.tickRateManager.checkShouldSprintThisTick()) {
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index 315b5be292b5cd81c526e9190ea43cd25afb89d4..4f90ebcd86fba38dec313143e36614e992c7dbc7 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -209,6 +209,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
org.spigotmc.SpigotConfig.registerCommands();
// Spigot end
io.papermc.paper.util.ObfHelper.INSTANCE.getClass(); // Paper - load mappings for stacktrace deobf and etc.
+ // Purpur start - Configurable void damage height and damage
+ try {
+ org.purpurmc.purpur.PurpurConfig.init((java.io.File) options.valueOf("purpur-settings"));
+ } catch (Exception e) {
+ DedicatedServer.LOGGER.error("Unable to load server configuration", e);
+ return false;
+ }
+ org.purpurmc.purpur.PurpurConfig.registerCommands();
+ // Purpur end - Configurable void damage height and damage
// Paper start - initialize global and world-defaults configuration
this.paperConfigurations.initializeGlobalConfiguration(this.registryAccess());
this.paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess());

View File

@@ -0,0 +1,96 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 25 Jul 2019 18:07:37 -0500
Subject: [PATCH] Implement elytra settings
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
index d1f7da0f4adc4609247c349d7ccdb0e6bba9b8f8..6de5f527c018201d874e06a45c9509fa12125766 100644
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -3595,7 +3595,18 @@ public abstract class LivingEntity extends Entity implements Attackable {
if (i1 % 2 == 0) {
List<EquipmentSlot> list = EquipmentSlot.VALUES.stream().filter(slot -> canGlideUsing(this.getItemBySlot(slot), slot)).toList();
EquipmentSlot equipmentSlot = Util.getRandom(list, this.random);
- this.getItemBySlot(equipmentSlot).hurtAndBreak(1, this, equipmentSlot);
+
+ // Purpur start - Implement elytra settings
+ int damage = level().purpurConfig.elytraDamagePerSecond;
+ if (level().purpurConfig.elytraDamageMultiplyBySpeed > 0) {
+ double speed = getDeltaMovement().lengthSqr();
+ if (speed > level().purpurConfig.elytraDamageMultiplyBySpeed) {
+ damage *= (int) speed;
+ }
+ }
+
+ this.getItemBySlot(equipmentSlot).hurtAndBreak(damage, this, equipmentSlot);
+ // Purpur end - Implement elytra settings
}
this.gameEvent(GameEvent.ELYTRA_GLIDE);
diff --git a/net/minecraft/world/item/FireworkRocketItem.java b/net/minecraft/world/item/FireworkRocketItem.java
index 75a9bd205f32b77c5d242cb9fac0f571ce36045a..b03f182c62c699cc222e67c1ae6eadf99c45d48d 100644
--- a/net/minecraft/world/item/FireworkRocketItem.java
+++ b/net/minecraft/world/item/FireworkRocketItem.java
@@ -66,6 +66,19 @@ public class FireworkRocketItem extends Item implements ProjectileItem {
com.destroystokyo.paper.event.player.PlayerElytraBoostEvent event = new com.destroystokyo.paper.event.player.PlayerElytraBoostEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemInHand), (org.bukkit.entity.Firework) delayed.projectile().getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand));
if (event.callEvent() && delayed.attemptSpawn()) {
player.awardStat(Stats.ITEM_USED.get(this)); // Moved up from below
+
+ // Purpur start - Implement elytra settings
+ if (level.purpurConfig.elytraDamagePerFireworkBoost > 0) {
+ List<net.minecraft.world.entity.EquipmentSlot> list = net.minecraft.world.entity.EquipmentSlot.VALUES.stream().filter((enumitemslot) -> net.minecraft.world.entity.LivingEntity.canGlideUsing(player.getItemBySlot(enumitemslot), enumitemslot)).toList();
+ net.minecraft.world.entity.EquipmentSlot enumitemslot = net.minecraft.Util.getRandom(list, player.random);
+
+ ItemStack glideItem = player.getItemBySlot(enumitemslot);
+ if (player.canGlide()) {
+ glideItem.hurtAndBreak(level.purpurConfig.elytraDamagePerFireworkBoost, player, enumitemslot);
+ }
+ }
+ // Purpur end - Implement elytra settings
+
if (event.shouldConsume() && !player.hasInfiniteMaterials()) {
itemInHand.shrink(1); // Moved up from below
} else {
diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java
index c5426585f53a3139dc9d188a73e3a7ff4cb2e492..264b713e8b7c3d5f7d8e1facc90a60349f2cf414 100644
--- a/net/minecraft/world/item/ItemStack.java
+++ b/net/minecraft/world/item/ItemStack.java
@@ -733,6 +733,14 @@ public final class ItemStack implements DataComponentHolder {
org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent(serverPlayer, this); // Paper - Add EntityDamageItemEvent
}
// CraftBukkit end
+
+ // Purpur start - Implement elytra settings
+ if (this.has(DataComponents.GLIDER)) {
+ setDamageValue(this.getMaxDamage() - 1);
+ return;
+ }
+ // Purpur end - Implement elytra settings
+
this.shrink(1);
onBreak.accept(item);
}
diff --git a/net/minecraft/world/item/TridentItem.java b/net/minecraft/world/item/TridentItem.java
index 07f8c7644a112bb1ba283d1eadd8661010e888a4..7ea7db834e7b627a1d7d37ca87cd43eb61408565 100644
--- a/net/minecraft/world/item/TridentItem.java
+++ b/net/minecraft/world/item/TridentItem.java
@@ -133,6 +133,18 @@ public class TridentItem extends Item implements ProjectileItem {
f1 *= tridentSpinAttackStrength / squareRoot;
f2 *= tridentSpinAttackStrength / squareRoot;
org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerRiptideEvent(player, stack, f, f1, f2); // CraftBukkit
+
+ // Purpur start - Implement elytra settings
+ List<EquipmentSlot> list = EquipmentSlot.VALUES.stream().filter((enumitemslot) -> LivingEntity.canGlideUsing(entity.getItemBySlot(enumitemslot), enumitemslot)).toList();
+ if (!list.isEmpty()) {
+ EquipmentSlot enumitemslot = net.minecraft.Util.getRandom(list, entity.random);
+ ItemStack glideItem = entity.getItemBySlot(enumitemslot);
+ if (glideItem.has(net.minecraft.core.component.DataComponents.GLIDER) && level.purpurConfig.elytraDamagePerTridentBoost > 0) {
+ glideItem.hurtAndBreak(level.purpurConfig.elytraDamagePerTridentBoost, entity, enumitemslot);
+ }
+ }
+ // Purpur end - Implement elytra settings
+
player.push(f, f1, f2);
player.startAutoSpinAttack(20, 8.0F, stack);
if (player.onGround()) {

View File

@@ -0,0 +1,177 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 26 Mar 2020 21:39:32 -0500
Subject: [PATCH] Configurable jockey options
diff --git a/net/minecraft/world/entity/monster/Drowned.java b/net/minecraft/world/entity/monster/Drowned.java
index 9c328f67260606d9252547848d5916cab4290e74..83fc978a94be4655e8c47ee634b8cd280d2a6fde 100644
--- a/net/minecraft/world/entity/monster/Drowned.java
+++ b/net/minecraft/world/entity/monster/Drowned.java
@@ -105,6 +105,23 @@ public class Drowned extends Zombie implements RangedAttackMob {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Configurable jockey options
+ @Override
+ public boolean jockeyOnlyBaby() {
+ return level().purpurConfig.drownedJockeyOnlyBaby;
+ }
+
+ @Override
+ public double jockeyChance() {
+ return level().purpurConfig.drownedJockeyChance;
+ }
+
+ @Override
+ public boolean jockeyTryExistingChickens() {
+ return level().purpurConfig.drownedJockeyTryExistingChickens;
+ }
+ // Purpur end - Configurable jockey options
+
@Override
protected void addBehaviourGoals() {
this.goalSelector.addGoal(1, new Drowned.DrownedGoToWaterGoal(this, 1.0));
diff --git a/net/minecraft/world/entity/monster/Husk.java b/net/minecraft/world/entity/monster/Husk.java
index c2365ae1cf6f98e262f302a117c4647c383dfbb5..7a8951f93e65c6df145e30d44b9d928dd0c39189 100644
--- a/net/minecraft/world/entity/monster/Husk.java
+++ b/net/minecraft/world/entity/monster/Husk.java
@@ -50,6 +50,23 @@ public class Husk extends Zombie {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Configurable jockey options
+ @Override
+ public boolean jockeyOnlyBaby() {
+ return level().purpurConfig.huskJockeyOnlyBaby;
+ }
+
+ @Override
+ public double jockeyChance() {
+ return level().purpurConfig.huskJockeyChance;
+ }
+
+ @Override
+ public boolean jockeyTryExistingChickens() {
+ return level().purpurConfig.huskJockeyTryExistingChickens;
+ }
+ // Purpur end - Configurable jockey options
+
public static boolean checkHuskSpawnRules(
EntityType<Husk> entityType, ServerLevelAccessor level, EntitySpawnReason spawnReason, BlockPos pos, RandomSource random
) {
diff --git a/net/minecraft/world/entity/monster/Zombie.java b/net/minecraft/world/entity/monster/Zombie.java
index 8886aa0da372223ecd4d1a17c60971e167ced886..63446c874e7153dcfb99133145c8b5311d7d86cd 100644
--- a/net/minecraft/world/entity/monster/Zombie.java
+++ b/net/minecraft/world/entity/monster/Zombie.java
@@ -125,6 +125,20 @@ public class Zombie extends Monster {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Configurable jockey options
+ public boolean jockeyOnlyBaby() {
+ return level().purpurConfig.zombieJockeyOnlyBaby;
+ }
+
+ public double jockeyChance() {
+ return level().purpurConfig.zombieJockeyChance;
+ }
+
+ public boolean jockeyTryExistingChickens() {
+ return level().purpurConfig.zombieJockeyTryExistingChickens;
+ }
+ // Purpur end - Configurable jockey options
+
@Override
protected void registerGoals() {
this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
@@ -556,19 +570,18 @@ public class Zombie extends Monster {
}
if (spawnGroupData instanceof Zombie.ZombieGroupData zombieGroupData) {
- if (zombieGroupData.isBaby) {
- this.setBaby(true);
+ if (!jockeyOnlyBaby() || zombieGroupData.isBaby) { // Purpur - Configurable jockey options
+ this.setBaby(zombieGroupData.isBaby); // Purpur - Configurable jockey options
if (zombieGroupData.canSpawnJockey) {
- if (random.nextFloat() < 0.05) {
- List<Chicken> entitiesOfClass = level.getEntitiesOfClass(
+ if (random.nextFloat() < jockeyChance()) { // Purpur - Configurable jockey options
+ List<Chicken> entitiesOfClass = jockeyTryExistingChickens() ? level.getEntitiesOfClass( // Purpur - Configurable jockey options
Chicken.class, this.getBoundingBox().inflate(5.0, 3.0, 5.0), EntitySelector.ENTITY_NOT_BEING_RIDDEN
- );
+ ) : java.util.Collections.emptyList(); // Purpur - Configurable jockey options
if (!entitiesOfClass.isEmpty()) {
Chicken chicken = entitiesOfClass.get(0);
chicken.setChickenJockey(true);
this.startRiding(chicken);
- }
- } else if (random.nextFloat() < 0.05) {
+ } else { // Purpur - Configurable jockey options
Chicken chicken1 = EntityType.CHICKEN.create(this.level(), EntitySpawnReason.JOCKEY);
if (chicken1 != null) {
chicken1.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), 0.0F);
@@ -577,6 +590,7 @@ public class Zombie extends Monster {
this.startRiding(chicken1);
level.addFreshEntity(chicken1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.MOUNT); // CraftBukkit
}
+ } // Purpur - Configurable jockey options
}
}
}
diff --git a/net/minecraft/world/entity/monster/ZombieVillager.java b/net/minecraft/world/entity/monster/ZombieVillager.java
index 578cfc33a493b5ebc2ed42733577129a8953a461..f1e9bf75c50f353bd377051be82a391f97d952fd 100644
--- a/net/minecraft/world/entity/monster/ZombieVillager.java
+++ b/net/minecraft/world/entity/monster/ZombieVillager.java
@@ -107,6 +107,23 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Configurable jockey options
+ @Override
+ public boolean jockeyOnlyBaby() {
+ return level().purpurConfig.zombieVillagerJockeyOnlyBaby;
+ }
+
+ @Override
+ public double jockeyChance() {
+ return level().purpurConfig.zombieVillagerJockeyChance;
+ }
+
+ @Override
+ public boolean jockeyTryExistingChickens() {
+ return level().purpurConfig.zombieVillagerJockeyTryExistingChickens;
+ }
+ // Purpur end - Configurable jockey options
+
@Override
protected void defineSynchedData(SynchedEntityData.Builder builder) {
super.defineSynchedData(builder);
diff --git a/net/minecraft/world/entity/monster/ZombifiedPiglin.java b/net/minecraft/world/entity/monster/ZombifiedPiglin.java
index 1424954f5b4cf0fbe821425cd741b4b5c1bfed50..9603589e0501feee900cd21b04eb84b02bb45de2 100644
--- a/net/minecraft/world/entity/monster/ZombifiedPiglin.java
+++ b/net/minecraft/world/entity/monster/ZombifiedPiglin.java
@@ -88,6 +88,23 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Configurable jockey options
+ @Override
+ public boolean jockeyOnlyBaby() {
+ return level().purpurConfig.zombifiedPiglinJockeyOnlyBaby;
+ }
+
+ @Override
+ public double jockeyChance() {
+ return level().purpurConfig.zombifiedPiglinJockeyChance;
+ }
+
+ @Override
+ public boolean jockeyTryExistingChickens() {
+ return level().purpurConfig.zombifiedPiglinJockeyTryExistingChickens;
+ }
+ // Purpur end - Configurable jockey options
+
@Override
public void setPersistentAngerTarget(@Nullable UUID target) {
this.persistentAngerTarget = target;

View File

@@ -0,0 +1,255 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 9 May 2019 18:26:06 -0500
Subject: [PATCH] Phantoms attracted to crystals and crystals shoot phantoms
diff --git a/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java b/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
index 67711964552a8e32d3590a64aff78e1db768b026..d58829c88b86358a0c06a982b302fc9a31c15853 100644
--- a/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
+++ b/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
@@ -26,6 +26,12 @@ public class EndCrystal extends Entity {
private static final EntityDataAccessor<Boolean> DATA_SHOW_BOTTOM = SynchedEntityData.defineId(EndCrystal.class, EntityDataSerializers.BOOLEAN);
public int time;
public boolean generatedByDragonFight = false; // Paper - Fix invulnerable end crystals
+ // Purpur start - Phantoms attracted to crystals and crystals shoot phantoms
+ private net.minecraft.world.entity.monster.Phantom targetPhantom;
+ private int phantomBeamTicks = 0;
+ private int phantomDamageCooldown = 0;
+ private int idleCooldown = 0;
+ // Purpur end - Phantoms attracted to crystals and crystals shoot phantoms
public EndCrystal(EntityType<? extends EndCrystal> entityType, Level level) {
super(entityType, level);
@@ -94,6 +100,49 @@ 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
+ // Purpur start - Phantoms attracted to crystals and crystals shoot phantoms
+ if (level().purpurConfig.phantomAttackedByCrystalRadius <= 0 || --idleCooldown > 0) {
+ return; // on cooldown
+ }
+
+ if (targetPhantom == null) {
+ for (net.minecraft.world.entity.monster.Phantom phantom : level().getEntitiesOfClass(net.minecraft.world.entity.monster.Phantom.class, getBoundingBox().inflate(level().purpurConfig.phantomAttackedByCrystalRadius))) {
+ if (phantom.hasLineOfSight(this)) {
+ attackPhantom(phantom);
+ break;
+ }
+ }
+ } else {
+ setBeamTarget(new BlockPos(targetPhantom).offset(0, -2, 0));
+ if (--phantomBeamTicks > 0 && targetPhantom.isAlive()) {
+ phantomDamageCooldown--;
+ if (targetPhantom.hasLineOfSight(this)) {
+ if (phantomDamageCooldown <= 0) {
+ phantomDamageCooldown = 20;
+ targetPhantom.hurt(targetPhantom.damageSources().indirectMagic(this, this), level().purpurConfig.phantomAttackedByCrystalDamage);
+ }
+ } else {
+ forgetPhantom(); // no longer in sight
+ }
+ } else {
+ forgetPhantom(); // attacked long enough
+ }
+ }
+ }
+
+ private void attackPhantom(net.minecraft.world.entity.monster.Phantom phantom) {
+ phantomDamageCooldown = 0;
+ phantomBeamTicks = 60;
+ targetPhantom = phantom;
+ }
+
+ private void forgetPhantom() {
+ targetPhantom = null;
+ setBeamTarget(null);
+ phantomBeamTicks = 0;
+ phantomDamageCooldown = 0;
+ idleCooldown = 60;
+ // Purpur end - Phantoms attracted to crystals and crystals shoot phantoms
}
@Override
diff --git a/net/minecraft/world/entity/monster/Phantom.java b/net/minecraft/world/entity/monster/Phantom.java
index 08fc2dc0fecfa370c99e877d502149a8ea147e5f..aea7b608d88d243113f67665844841ac879c3f88 100644
--- a/net/minecraft/world/entity/monster/Phantom.java
+++ b/net/minecraft/world/entity/monster/Phantom.java
@@ -47,6 +47,7 @@ public class Phantom extends FlyingMob implements Enemy {
Vec3 moveTargetPoint = Vec3.ZERO;
public BlockPos anchorPoint = BlockPos.ZERO;
Phantom.AttackPhase attackPhase = Phantom.AttackPhase.CIRCLE;
+ Vec3 crystalPosition; // Purpur - Phantoms attracted to crystals and crystals shoot phantoms
// Paper start
@Nullable
public java.util.UUID spawningEntity;
@@ -118,6 +119,25 @@ public class Phantom extends FlyingMob implements Enemy {
}
// Purpur end - Ridables
+ // Purpur start - Phantoms attracted to crystals and crystals shoot phantoms
+ @Override
+ protected void dropFromLootTable(ServerLevel world, DamageSource damageSource, boolean causedByPlayer) {
+ boolean dropped = false;
+ if (lastHurtByPlayer == null && damageSource.getEntity() instanceof net.minecraft.world.entity.boss.enderdragon.EndCrystal) {
+ if (random.nextInt(5) < 1) {
+ dropped = spawnAtLocation(world, new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.PHANTOM_MEMBRANE)) != null;
+ }
+ }
+ if (!dropped) {
+ super.dropFromLootTable(world, damageSource, causedByPlayer);
+ }
+ }
+
+ public boolean isCirclingCrystal() {
+ return crystalPosition != null;
+ }
+ // Purpur end - Phantoms attracted to crystals and crystals shoot phantoms
+
@Override
public boolean isFlapping() {
return (this.getUniqueFlapTickOffset() + this.tickCount) % TICKS_PER_FLAP == 0;
@@ -131,9 +151,15 @@ public class Phantom extends FlyingMob implements Enemy {
@Override
protected void registerGoals() {
this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
- this.goalSelector.addGoal(1, new Phantom.PhantomAttackStrategyGoal());
- this.goalSelector.addGoal(2, new Phantom.PhantomSweepAttackGoal());
- this.goalSelector.addGoal(3, new Phantom.PhantomCircleAroundAnchorGoal());
+ // Purpur start - Phantoms attracted to crystals and crystals shoot phantoms
+ if (level().purpurConfig.phantomOrbitCrystalRadius > 0) {
+ this.goalSelector.addGoal(1, new PhantomFindCrystalGoal(this));
+ this.goalSelector.addGoal(2, new PhantomOrbitCrystalGoal(this));
+ }
+ this.goalSelector.addGoal(3, new Phantom.PhantomAttackStrategyGoal());
+ this.goalSelector.addGoal(4, new Phantom.PhantomSweepAttackGoal());
+ this.goalSelector.addGoal(5, new Phantom.PhantomCircleAroundAnchorGoal());
+ // Purpur end - Phantoms attracted to crystals and crystals shoot phantoms
this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
this.targetSelector.addGoal(1, new Phantom.PhantomAttackPlayerTargetGoal());
}
@@ -509,6 +535,124 @@ public class Phantom extends FlyingMob implements Enemy {
}
}
+ // Purpur start - Phantoms attracted to crystals and crystals shoot phantoms
+ class PhantomFindCrystalGoal extends Goal {
+ private final Phantom phantom;
+ private net.minecraft.world.entity.boss.enderdragon.EndCrystal crystal;
+ private Comparator<net.minecraft.world.entity.boss.enderdragon.EndCrystal> comparator;
+
+ PhantomFindCrystalGoal(Phantom phantom) {
+ this.phantom = phantom;
+ this.comparator = Comparator.comparingDouble(phantom::distanceToSqr);
+ this.setFlags(EnumSet.of(Flag.LOOK));
+ }
+
+ @Override
+ public boolean canUse() {
+ double range = maxTargetRange();
+ List<net.minecraft.world.entity.boss.enderdragon.EndCrystal> crystals = level().getEntitiesOfClass(net.minecraft.world.entity.boss.enderdragon.EndCrystal.class, phantom.getBoundingBox().inflate(range));
+ if (crystals.isEmpty()) {
+ return false;
+ }
+ crystals.sort(comparator);
+ crystal = crystals.get(0);
+ if (phantom.distanceToSqr(crystal) > range * range) {
+ crystal = null;
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean canContinueToUse() {
+ if (crystal == null || !crystal.isAlive()) {
+ return false;
+ }
+ double range = maxTargetRange();
+ return phantom.distanceToSqr(crystal) <= (range * range) * 2;
+ }
+
+ @Override
+ public void start() {
+ phantom.crystalPosition = new Vec3(crystal.getX(), crystal.getY() + (phantom.random.nextInt(10) + 10), crystal.getZ());
+ }
+
+ @Override
+ public void stop() {
+ crystal = null;
+ phantom.crystalPosition = null;
+ super.stop();
+ }
+
+ private double maxTargetRange() {
+ return phantom.level().purpurConfig.phantomOrbitCrystalRadius;
+ }
+ }
+
+ class PhantomOrbitCrystalGoal extends Goal {
+ private final Phantom phantom;
+ private float offset;
+ private float radius;
+ private float verticalChange;
+ private float direction;
+
+ PhantomOrbitCrystalGoal(Phantom phantom) {
+ this.phantom = phantom;
+ this.setFlags(EnumSet.of(Flag.MOVE));
+ }
+
+ @Override
+ public boolean canUse() {
+ return phantom.isCirclingCrystal();
+ }
+
+ @Override
+ public void start() {
+ this.radius = 5.0F + phantom.random.nextFloat() * 10.0F;
+ this.verticalChange = -4.0F + phantom.random.nextFloat() * 9.0F;
+ this.direction = phantom.random.nextBoolean() ? 1.0F : -1.0F;
+ updateOffset();
+ }
+
+ @Override
+ public void tick() {
+ if (phantom.random.nextInt(350) == 0) {
+ this.verticalChange = -4.0F + phantom.random.nextFloat() * 9.0F;
+ }
+ if (phantom.random.nextInt(250) == 0) {
+ ++this.radius;
+ if (this.radius > 15.0F) {
+ this.radius = 5.0F;
+ this.direction = -this.direction;
+ }
+ }
+ if (phantom.random.nextInt(450) == 0) {
+ this.offset = phantom.random.nextFloat() * 2.0F * 3.1415927F;
+ updateOffset();
+ }
+ if (phantom.moveTargetPoint.distanceToSqr(phantom.getX(), phantom.getY(), phantom.getZ()) < 4.0D) {
+ updateOffset();
+ }
+ if (phantom.moveTargetPoint.y < phantom.getY() && !phantom.level().isEmptyBlock(new BlockPos(phantom).below(1))) {
+ this.verticalChange = Math.max(1.0F, this.verticalChange);
+ updateOffset();
+ }
+ if (phantom.moveTargetPoint.y > phantom.getY() && !phantom.level().isEmptyBlock(new BlockPos(phantom).above(1))) {
+ this.verticalChange = Math.min(-1.0F, this.verticalChange);
+ updateOffset();
+ }
+ }
+
+ private void updateOffset() {
+ this.offset += this.direction * 15.0F * 0.017453292F;
+ phantom.moveTargetPoint = phantom.crystalPosition.add(
+ this.radius * Mth.cos(this.offset),
+ -4.0F + this.verticalChange,
+ this.radius * Mth.sin(this.offset));
+ }
+ }
+ // Purpur end - Phantoms attracted to crystals and crystals shoot phantoms
+
class PhantomMoveControl extends org.purpurmc.purpur.controller.FlyingMoveControllerWASD { // Purpur - Ridables
private float speed = 0.1F;

View File

@@ -0,0 +1,52 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: draycia <lonelyyordle@gmail.com>
Date: Sun, 12 Apr 2020 20:41:59 -0700
Subject: [PATCH] Phantoms burn in light
diff --git a/net/minecraft/world/entity/monster/Phantom.java b/net/minecraft/world/entity/monster/Phantom.java
index aea7b608d88d243113f67665844841ac879c3f88..4cc1c8d8967b1e9ee5b0b1c50d887f3de3e8a882 100644
--- a/net/minecraft/world/entity/monster/Phantom.java
+++ b/net/minecraft/world/entity/monster/Phantom.java
@@ -53,6 +53,7 @@ public class Phantom extends FlyingMob implements Enemy {
public java.util.UUID spawningEntity;
public boolean shouldBurnInDay = true;
// Paper end
+ private static final net.minecraft.world.item.crafting.Ingredient TORCH = net.minecraft.world.item.crafting.Ingredient.of(net.minecraft.world.item.Items.TORCH, net.minecraft.world.item.Items.SOUL_TORCH); // Purpur - Phantoms burn in light
public Phantom(EntityType<? extends Phantom> entityType, Level level) {
super(entityType, level);
@@ -253,7 +254,11 @@ public class Phantom extends FlyingMob implements Enemy {
@Override
public void aiStep() {
- if (this.isAlive() && this.shouldBurnInDay && this.isSunBurnTick()) { // Paper - shouldBurnInDay API
+ // Purpur start - Phantoms burn in light
+ boolean burnFromDaylight = this.shouldBurnInDay && this.isSunBurnTick() && this.level().purpurConfig.phantomBurnInDaylight;
+ boolean burnFromLightSource = this.level().purpurConfig.phantomBurnInLight > 0 && this.level().getMaxLocalRawBrightness(blockPosition()) >= this.level().purpurConfig.phantomBurnInLight;
+ if (this.isAlive() && (burnFromDaylight || burnFromLightSource)) { // Paper - shouldBurnInDay API
+ // Purpur end - Phantoms burn in light
if (getRider() == null || !this.isControllable()) // Purpur - Ridables
this.igniteForSeconds(8.0F);
}
@@ -374,6 +379,7 @@ public class Phantom extends FlyingMob implements Enemy {
List<Player> nearbyPlayers = serverLevel.getNearbyPlayers(
this.attackTargeting, Phantom.this, Phantom.this.getBoundingBox().inflate(16.0, 64.0, 16.0)
);
+ if (level().purpurConfig.phantomIgnorePlayersWithTorch) nearbyPlayers.removeIf(human -> TORCH.test(human.getItemInHand(net.minecraft.world.InteractionHand.MAIN_HAND)) || TORCH.test(human.getItemInHand(net.minecraft.world.InteractionHand.OFF_HAND))); // Purpur - Phantoms burn in light
if (!nearbyPlayers.isEmpty()) {
nearbyPlayers.sort(Comparator.<Player, Double>comparing(Entity::getY).reversed());
@@ -739,6 +745,12 @@ public class Phantom extends FlyingMob implements Enemy {
return false;
} else if (!target.isAlive()) {
return false;
+ // Purpur start - Phantoms burn in light
+ } else if (level().purpurConfig.phantomBurnInLight > 0 && level().getLightEmission(new BlockPos(Phantom.this)) >= level().purpurConfig.phantomBurnInLight) {
+ return false;
+ } else if (level().purpurConfig.phantomIgnorePlayersWithTorch && (TORCH.test(target.getItemInHand(net.minecraft.world.InteractionHand.MAIN_HAND)) || TORCH.test(target.getItemInHand(net.minecraft.world.InteractionHand.OFF_HAND)))) {
+ return false;
+ // Purpur end - Phantoms burn in light
} else if (target instanceof Player player && (target.isSpectator() || player.isCreative())) {
return false;
} else if (!this.canUse()) {

View File

@@ -0,0 +1,600 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Sun, 15 Nov 2020 02:18:15 -0800
Subject: [PATCH] Make entity breeding times configurable
diff --git a/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java b/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java
index 4fb63e58eac5d67fcd31c3233dca1dae72b98bc4..dd8d315eba203db121e24e3402f2117fc0f3043f 100644
--- a/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java
+++ b/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java
@@ -118,8 +118,10 @@ public class VillagerMakeLove extends Behavior<Villager> {
return Optional.empty();
}
// Move age setting down
- parent.setAge(6000);
- partner.setAge(6000);
+ // Purpur start - Make entity breeding times configurable
+ parent.setAge(level.purpurConfig.villagerBreedingTicks);
+ partner.setAge(level.purpurConfig.villagerBreedingTicks);
+ // Purpur end - Make entity breeding times configurable
level.addFreshEntityWithPassengers(breedOffspring, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING);
// CraftBukkit end
level.broadcastEntityEvent(breedOffspring, (byte)12);
diff --git a/net/minecraft/world/entity/animal/Animal.java b/net/minecraft/world/entity/animal/Animal.java
index 33c3752be451508343cad83766da7c3be1822d02..fa34e7f1c20dfd569b52a9c8e0a8d4d5e659ce20 100644
--- a/net/minecraft/world/entity/animal/Animal.java
+++ b/net/minecraft/world/entity/animal/Animal.java
@@ -40,6 +40,7 @@ public abstract class Animal extends AgeableMob {
@Nullable
public UUID loveCause;
public ItemStack breedItem; // CraftBukkit - Add breedItem variable
+ public abstract int getPurpurBreedTime(); // Purpur - Make entity breeding times configurable
protected Animal(EntityType<? extends Animal> entityType, Level level) {
super(entityType, level);
@@ -279,8 +280,10 @@ public abstract class Animal extends AgeableMob {
player.awardStat(Stats.ANIMALS_BRED);
CriteriaTriggers.BRED_ANIMALS.trigger(player, this, animal, baby);
} // Paper
- this.setAge(6000);
- animal.setAge(6000);
+ // Purpur start - Make entity breeding times configurable
+ this.setAge(this.getPurpurBreedTime());
+ animal.setAge(animal.getPurpurBreedTime());
+ // Purpur end - Make entity breeding times configurable
this.resetLove();
animal.resetLove();
level.broadcastEntityEvent(this, (byte)18);
diff --git a/net/minecraft/world/entity/animal/Bee.java b/net/minecraft/world/entity/animal/Bee.java
index 3cdfded14a2fb74e3f345e893e60364b6b810075..199bd7e9b053a2eac76987ceb5caebc088d1071d 100644
--- a/net/minecraft/world/entity/animal/Bee.java
+++ b/net/minecraft/world/entity/animal/Bee.java
@@ -480,6 +480,13 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.beeBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Override
public int getRemainingPersistentAngerTime() {
return this.entityData.get(DATA_REMAINING_ANGER_TIME);
diff --git a/net/minecraft/world/entity/animal/Cat.java b/net/minecraft/world/entity/animal/Cat.java
index 98ce277c5b27591e22daa3c85241be1b8689bfae..584568cef949cee24aa7850d2ff99d47cd089a6e 100644
--- a/net/minecraft/world/entity/animal/Cat.java
+++ b/net/minecraft/world/entity/animal/Cat.java
@@ -126,6 +126,13 @@ public class Cat extends TamableAnimal implements VariantHolder<Holder<CatVarian
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.catBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Override
protected void registerGoals() {
this.temptGoal = new Cat.CatTemptGoal(this, 0.6, itemStack -> itemStack.is(ItemTags.CAT_FOOD), true);
diff --git a/net/minecraft/world/entity/animal/Chicken.java b/net/minecraft/world/entity/animal/Chicken.java
index d718f0ed362c49803260dceed64bd93e2b6744fc..39ad1729ef03fc35a6365ee215be214eccfd959a 100644
--- a/net/minecraft/world/entity/animal/Chicken.java
+++ b/net/minecraft/world/entity/animal/Chicken.java
@@ -81,6 +81,13 @@ public class Chicken extends Animal {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.chickenBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Override
protected void registerGoals() {
this.goalSelector.addGoal(0, new FloatGoal(this));
diff --git a/net/minecraft/world/entity/animal/Cow.java b/net/minecraft/world/entity/animal/Cow.java
index d2a4bfa5334f7361067e4adac36ba5a4a4fa6ad8..e4965300eb41512d03a0b111422c98627cf29a54 100644
--- a/net/minecraft/world/entity/animal/Cow.java
+++ b/net/minecraft/world/entity/animal/Cow.java
@@ -63,6 +63,13 @@ public class Cow extends Animal {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.cowBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Override
protected void registerGoals() {
this.goalSelector.addGoal(0, new FloatGoal(this));
diff --git a/net/minecraft/world/entity/animal/Fox.java b/net/minecraft/world/entity/animal/Fox.java
index 8bf893837586ae2a9b4ef7564d242e16e4863b5d..1acf9b8c9e6a5915b3f095e83d3f209708947093 100644
--- a/net/minecraft/world/entity/animal/Fox.java
+++ b/net/minecraft/world/entity/animal/Fox.java
@@ -175,6 +175,13 @@ public class Fox extends Animal implements VariantHolder<Fox.Variant> {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.foxBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Override
protected void defineSynchedData(SynchedEntityData.Builder builder) {
super.defineSynchedData(builder);
@@ -969,8 +976,10 @@ public class Fox extends Animal implements VariantHolder<Fox.Variant> {
CriteriaTriggers.BRED_ANIMALS.trigger(serverPlayer, this.animal, this.partner, fox);
}
- this.animal.setAge(6000);
- this.partner.setAge(6000);
+ // Purpur start - Make entity breeding times configurable
+ this.animal.setAge(this.animal.getPurpurBreedTime());
+ this.partner.setAge(this.partner.getPurpurBreedTime());
+ // Purpur end - Make entity breeding times configurable
this.animal.resetLove();
this.partner.resetLove();
serverLevel.addFreshEntityWithPassengers(fox, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - added SpawnReason
diff --git a/net/minecraft/world/entity/animal/MushroomCow.java b/net/minecraft/world/entity/animal/MushroomCow.java
index 990723c31aa1040a4e45b9857a18d86287ef91b4..a64b609bf5ce38a252bfa1bcff869f88e14389b5 100644
--- a/net/minecraft/world/entity/animal/MushroomCow.java
+++ b/net/minecraft/world/entity/animal/MushroomCow.java
@@ -79,6 +79,13 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder<Mushroo
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.mooshroomBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Override
public float getWalkTargetValue(BlockPos pos, LevelReader level) {
return level.getBlockState(pos.below()).is(Blocks.MYCELIUM) ? 10.0F : level.getPathfindingCostFromLightLevels(pos);
diff --git a/net/minecraft/world/entity/animal/Ocelot.java b/net/minecraft/world/entity/animal/Ocelot.java
index 41c42ecbf6aa233bd82000a4bbba3b186cca6a9d..b06697fd64a8962133f0324b2c03b9e9b4f32086 100644
--- a/net/minecraft/world/entity/animal/Ocelot.java
+++ b/net/minecraft/world/entity/animal/Ocelot.java
@@ -87,6 +87,13 @@ public class Ocelot extends Animal {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.ocelotBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
public boolean isTrusting() {
return this.entityData.get(DATA_TRUSTING);
}
diff --git a/net/minecraft/world/entity/animal/Panda.java b/net/minecraft/world/entity/animal/Panda.java
index 5b07dff937c8873300eabecf1c510cf562fae4f3..450c7be36846bf4e95f84615fca893501415cdbc 100644
--- a/net/minecraft/world/entity/animal/Panda.java
+++ b/net/minecraft/world/entity/animal/Panda.java
@@ -140,6 +140,13 @@ public class Panda extends Animal {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.pandaBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Override
protected boolean canDispenserEquipIntoSlot(EquipmentSlot slot) {
return slot == EquipmentSlot.MAINHAND && this.canPickUpLoot();
diff --git a/net/minecraft/world/entity/animal/Parrot.java b/net/minecraft/world/entity/animal/Parrot.java
index 87de937fd17c2e7e8916f8503b0334e7015bdb8f..9d7e142cc4b9ea32aad7ab17f3fc09a7a3a1d862 100644
--- a/net/minecraft/world/entity/animal/Parrot.java
+++ b/net/minecraft/world/entity/animal/Parrot.java
@@ -194,6 +194,13 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder<Parrot
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return 6000;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Nullable
@Override
public SpawnGroupData finalizeSpawn(
diff --git a/net/minecraft/world/entity/animal/Pig.java b/net/minecraft/world/entity/animal/Pig.java
index 7df848bd9c4cf98fbd431a8cae16a2df86ec5e2b..801365d71b5b733e2dce54211e08d26d7f45f4d9 100644
--- a/net/minecraft/world/entity/animal/Pig.java
+++ b/net/minecraft/world/entity/animal/Pig.java
@@ -81,6 +81,13 @@ public class Pig extends Animal implements ItemSteerable, Saddleable {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.pigBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Override
protected void registerGoals() {
this.goalSelector.addGoal(0, new FloatGoal(this));
diff --git a/net/minecraft/world/entity/animal/PolarBear.java b/net/minecraft/world/entity/animal/PolarBear.java
index 913439a769a36521ba59d59cba4d6878d3186254..365ad366bd0077619b0f6b5d26ed41038da0397e 100644
--- a/net/minecraft/world/entity/animal/PolarBear.java
+++ b/net/minecraft/world/entity/animal/PolarBear.java
@@ -124,6 +124,13 @@ public class PolarBear extends Animal implements NeutralMob {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.polarBearBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Nullable
@Override
public AgeableMob getBreedOffspring(ServerLevel level, AgeableMob otherParent) {
diff --git a/net/minecraft/world/entity/animal/Rabbit.java b/net/minecraft/world/entity/animal/Rabbit.java
index e71161ecc9d4ee3fe29fa3a27d11d63e1a28d1a0..bbdd06002b07699fffebdf6ed8148abdb69c24cc 100644
--- a/net/minecraft/world/entity/animal/Rabbit.java
+++ b/net/minecraft/world/entity/animal/Rabbit.java
@@ -145,6 +145,13 @@ public class Rabbit extends Animal implements VariantHolder<Rabbit.Variant> {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.rabbitBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Override
public void registerGoals() {
this.goalSelector.addGoal(1, new FloatGoal(this));
diff --git a/net/minecraft/world/entity/animal/Sheep.java b/net/minecraft/world/entity/animal/Sheep.java
index b66440f5cfbd714c6d2f5b7f66b4e755602b4521..882c799cb66a2acada33ff24f3adb7eb611f89c1 100644
--- a/net/minecraft/world/entity/animal/Sheep.java
+++ b/net/minecraft/world/entity/animal/Sheep.java
@@ -106,6 +106,13 @@ public class Sheep extends Animal implements Shearable {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.sheepBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Override
protected void registerGoals() {
this.eatBlockGoal = new EatBlockGoal(this);
diff --git a/net/minecraft/world/entity/animal/Turtle.java b/net/minecraft/world/entity/animal/Turtle.java
index 4f0fbbb2caeda6d1477d3297fd68f802e4f3a9ca..edbccb7ca27aa8a1917eb8b35b3ba8600c91111a 100644
--- a/net/minecraft/world/entity/animal/Turtle.java
+++ b/net/minecraft/world/entity/animal/Turtle.java
@@ -109,6 +109,13 @@ public class Turtle extends Animal {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.turtleBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
public void setHomePos(BlockPos homePos) {
this.entityData.set(HOME_POS, homePos);
}
diff --git a/net/minecraft/world/entity/animal/Wolf.java b/net/minecraft/world/entity/animal/Wolf.java
index afc12968313a408e8a71a20c2c0defde52605c4e..9d79946497cfc92ff11160b86d5064d86916af36 100644
--- a/net/minecraft/world/entity/animal/Wolf.java
+++ b/net/minecraft/world/entity/animal/Wolf.java
@@ -210,6 +210,13 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder<Hol
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.wolfBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Override
protected void registerGoals() {
this.goalSelector.addGoal(1, new FloatGoal(this));
diff --git a/net/minecraft/world/entity/animal/armadillo/Armadillo.java b/net/minecraft/world/entity/animal/armadillo/Armadillo.java
index c10ebb66dec26b6ccc223e98effa0b9a68363626..90bcd8c79cccbcbe7ff3fd2534e0c3450b970bd4 100644
--- a/net/minecraft/world/entity/animal/armadillo/Armadillo.java
+++ b/net/minecraft/world/entity/animal/armadillo/Armadillo.java
@@ -105,6 +105,13 @@ public class Armadillo extends Animal {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.armadilloBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Override
protected void defineSynchedData(SynchedEntityData.Builder builder) {
super.defineSynchedData(builder);
diff --git a/net/minecraft/world/entity/animal/axolotl/Axolotl.java b/net/minecraft/world/entity/animal/axolotl/Axolotl.java
index f2f09a529e9db88784ff4299fdf3966046c736ab..07eee1f82331a2172aede02219a7eae8e82c7b59 100644
--- a/net/minecraft/world/entity/animal/axolotl/Axolotl.java
+++ b/net/minecraft/world/entity/animal/axolotl/Axolotl.java
@@ -140,6 +140,13 @@ public class Axolotl extends Animal implements VariantHolder<Axolotl.Variant>, B
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.axolotlBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Override
public float getWalkTargetValue(BlockPos pos, LevelReader level) {
return 0.0F;
diff --git a/net/minecraft/world/entity/animal/camel/Camel.java b/net/minecraft/world/entity/animal/camel/Camel.java
index 1d7e2358bac193af48dc4b7f5b0295e3bffa152b..1d7ae2a08968860636918e7c66b60139a9d761b4 100644
--- a/net/minecraft/world/entity/animal/camel/Camel.java
+++ b/net/minecraft/world/entity/animal/camel/Camel.java
@@ -90,6 +90,13 @@ public class Camel extends AbstractHorse {
}
// Purpur end - Ridables
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.camelBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Override
public void addAdditionalSaveData(CompoundTag compound) {
super.addAdditionalSaveData(compound);
diff --git a/net/minecraft/world/entity/animal/frog/Frog.java b/net/minecraft/world/entity/animal/frog/Frog.java
index 9a400c8bf2b54aa5fbcbe65b61670cac5fbebf05..c4ea9485294b7dec2582c638802f003ad70659b6 100644
--- a/net/minecraft/world/entity/animal/frog/Frog.java
+++ b/net/minecraft/world/entity/animal/frog/Frog.java
@@ -165,6 +165,12 @@ public class Frog extends Animal implements VariantHolder<Holder<FrogVariant>> {
}
// Purpur end - Ridables
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.frogBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
@Override
protected Brain.Provider<Frog> brainProvider() {
return Brain.provider(MEMORY_TYPES, SENSOR_TYPES);
diff --git a/net/minecraft/world/entity/animal/goat/Goat.java b/net/minecraft/world/entity/animal/goat/Goat.java
index 302208b566038a3a352ca867dd70a61887bac104..0a018dbfe3750cf91892d8cfb5c0eac18e83d587 100644
--- a/net/minecraft/world/entity/animal/goat/Goat.java
+++ b/net/minecraft/world/entity/animal/goat/Goat.java
@@ -128,6 +128,13 @@ public class Goat extends Animal {
}
// Purpur end - Ridables
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.goatBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Override
protected Brain.Provider<Goat> brainProvider() {
return Brain.provider(MEMORY_TYPES, SENSOR_TYPES);
diff --git a/net/minecraft/world/entity/animal/horse/Donkey.java b/net/minecraft/world/entity/animal/horse/Donkey.java
index 223f1d109680e3643ab2c8343be22713e89755fd..b977597785df5665176ab2f330633ec61b7c9feb 100644
--- a/net/minecraft/world/entity/animal/horse/Donkey.java
+++ b/net/minecraft/world/entity/animal/horse/Donkey.java
@@ -40,6 +40,13 @@ public class Donkey extends AbstractChestedHorse {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.donkeyBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Override
protected SoundEvent getAmbientSound() {
return SoundEvents.DONKEY_AMBIENT;
diff --git a/net/minecraft/world/entity/animal/horse/Horse.java b/net/minecraft/world/entity/animal/horse/Horse.java
index 8bd118e82da9e4d4153de0a3efaf6d69e3c4c540..0339ab08b3029a9ffc102c5b865e411aca2a863c 100644
--- a/net/minecraft/world/entity/animal/horse/Horse.java
+++ b/net/minecraft/world/entity/animal/horse/Horse.java
@@ -67,6 +67,13 @@ public class Horse extends AbstractHorse implements VariantHolder<Variant> {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.horseBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Override
protected void randomizeAttributes(RandomSource random) {
this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(generateMaxHealth(random::nextInt));
diff --git a/net/minecraft/world/entity/animal/horse/Llama.java b/net/minecraft/world/entity/animal/horse/Llama.java
index 58e726dd33f572a31b4910b9ff666c4252fb03a9..6efe52edb6909ed2b38210ce6a0334eddc55f261 100644
--- a/net/minecraft/world/entity/animal/horse/Llama.java
+++ b/net/minecraft/world/entity/animal/horse/Llama.java
@@ -141,6 +141,13 @@ public class Llama extends AbstractChestedHorse implements VariantHolder<Llama.V
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.llamaBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
public boolean isTraderLlama() {
return false;
}
diff --git a/net/minecraft/world/entity/animal/horse/Mule.java b/net/minecraft/world/entity/animal/horse/Mule.java
index d0d6b511dbd4f992d11f06e7539b0c1034250660..20458799fdcfa16bdd1c22df74b414000b110f82 100644
--- a/net/minecraft/world/entity/animal/horse/Mule.java
+++ b/net/minecraft/world/entity/animal/horse/Mule.java
@@ -39,6 +39,13 @@ public class Mule extends AbstractChestedHorse {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.muleBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Override
protected SoundEvent getAmbientSound() {
return SoundEvents.MULE_AMBIENT;
diff --git a/net/minecraft/world/entity/animal/horse/SkeletonHorse.java b/net/minecraft/world/entity/animal/horse/SkeletonHorse.java
index 6cc64c7e2f50a311460cd5d7ffa9545e5d7e0b02..0ce71ab6a28a5fbff9d71793b855c116b31729fc 100644
--- a/net/minecraft/world/entity/animal/horse/SkeletonHorse.java
+++ b/net/minecraft/world/entity/animal/horse/SkeletonHorse.java
@@ -63,6 +63,13 @@ public class SkeletonHorse extends AbstractHorse {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return 6000;
+ }
+ // Purpur end - Make entity breeding times configurable
+
public static AttributeSupplier.Builder createAttributes() {
return createBaseHorseAttributes().add(Attributes.MAX_HEALTH, 15.0).add(Attributes.MOVEMENT_SPEED, 0.2F);
}
diff --git a/net/minecraft/world/entity/animal/horse/TraderLlama.java b/net/minecraft/world/entity/animal/horse/TraderLlama.java
index 715cb8046e1fb9ac929d81709777bf4ae9323d46..870775ce8a1bd09d35bf85551e1af3a6edfefc0e 100644
--- a/net/minecraft/world/entity/animal/horse/TraderLlama.java
+++ b/net/minecraft/world/entity/animal/horse/TraderLlama.java
@@ -68,6 +68,13 @@ public class TraderLlama extends Llama {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.traderLlamaBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Override
public boolean isTraderLlama() {
return true;
diff --git a/net/minecraft/world/entity/animal/horse/ZombieHorse.java b/net/minecraft/world/entity/animal/horse/ZombieHorse.java
index 8da61e14f2470dfb191d9dfaf19c713584b8e9b8..cdff0fab8a256c1e06e280500a31d4a99659d1ee 100644
--- a/net/minecraft/world/entity/animal/horse/ZombieHorse.java
+++ b/net/minecraft/world/entity/animal/horse/ZombieHorse.java
@@ -62,6 +62,13 @@ public class ZombieHorse extends AbstractHorse {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return 6000;
+ }
+ // Purpur end - Make entity breeding times configurable
+
public static AttributeSupplier.Builder createAttributes() {
return createBaseHorseAttributes().add(Attributes.MAX_HEALTH, 15.0).add(Attributes.MOVEMENT_SPEED, 0.2F);
}
diff --git a/net/minecraft/world/entity/animal/sniffer/Sniffer.java b/net/minecraft/world/entity/animal/sniffer/Sniffer.java
index a5ff61a3697e2299c96288b6f8d7c6f2511d86d5..11a5da22149a61ca48bbb0a8ed10b71e91a5cc98 100644
--- a/net/minecraft/world/entity/animal/sniffer/Sniffer.java
+++ b/net/minecraft/world/entity/animal/sniffer/Sniffer.java
@@ -113,6 +113,13 @@ public class Sniffer extends Animal {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.snifferBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Override
protected void defineSynchedData(SynchedEntityData.Builder builder) {
super.defineSynchedData(builder);
diff --git a/net/minecraft/world/entity/monster/Strider.java b/net/minecraft/world/entity/monster/Strider.java
index be0dc92bf5ae3da1368a649e9c4e7ff5dbb1c67c..f36e94437b4e21961532ac9ab91767617f9c3c32 100644
--- a/net/minecraft/world/entity/monster/Strider.java
+++ b/net/minecraft/world/entity/monster/Strider.java
@@ -119,6 +119,13 @@ public class Strider extends Animal implements ItemSteerable, Saddleable {
}
// Purpur end - Configurable entity base attributes
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.striderBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
public static boolean checkStriderSpawnRules(
EntityType<Strider> entityType, LevelAccessor level, EntitySpawnReason spawnReason, BlockPos pos, RandomSource random
) {
diff --git a/net/minecraft/world/entity/monster/hoglin/Hoglin.java b/net/minecraft/world/entity/monster/hoglin/Hoglin.java
index 54924cd7c84cbcd22ffc0bd37fc24f24e73c18bc..266d1838e6602ef6322c15732f2693a865911f2e 100644
--- a/net/minecraft/world/entity/monster/hoglin/Hoglin.java
+++ b/net/minecraft/world/entity/monster/hoglin/Hoglin.java
@@ -122,6 +122,13 @@ public class Hoglin extends Animal implements Enemy, HoglinBase {
this.timeInOverworld = timeInOverworld;
}
+ // Purpur start - Make entity breeding times configurable
+ @Override
+ public int getPurpurBreedTime() {
+ return this.level().purpurConfig.hoglinBreedingTicks;
+ }
+ // Purpur end - Make entity breeding times configurable
+
@Override
public boolean canBeLeashed() {
return true;

View File

@@ -0,0 +1,111 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Tue, 17 Nov 2020 03:23:48 -0800
Subject: [PATCH] Apply display names from item forms of entities to entities
and vice versa
diff --git a/net/minecraft/world/entity/decoration/ArmorStand.java b/net/minecraft/world/entity/decoration/ArmorStand.java
index d368b1971b270c44efc849464a100832bc29a679..8c0ab32487c56e2caf42404184f86c9bcf5f8b41 100644
--- a/net/minecraft/world/entity/decoration/ArmorStand.java
+++ b/net/minecraft/world/entity/decoration/ArmorStand.java
@@ -564,6 +564,7 @@ public class ArmorStand extends LivingEntity {
private org.bukkit.event.entity.EntityDeathEvent brokenByPlayer(ServerLevel level, DamageSource damageSource) { // Paper
ItemStack itemStack = new ItemStack(Items.ARMOR_STAND);
+ if (level.purpurConfig.persistentDroppableEntityDisplayNames) // Purpur - Apply display names from item forms of entities to entities and vice versa
itemStack.set(DataComponents.CUSTOM_NAME, this.getCustomName());
this.drops.add(new DefaultDrop(itemStack, stack -> Block.popResource(this.level(), this.blockPosition(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior
return this.brokenByAnything(level, damageSource); // Paper
diff --git a/net/minecraft/world/entity/decoration/ItemFrame.java b/net/minecraft/world/entity/decoration/ItemFrame.java
index 65e1d7c5ac94b1cfb921fa009be59d3e5872f0b5..3ee1d8798db666ee8d83556047e40ff217cda732 100644
--- a/net/minecraft/world/entity/decoration/ItemFrame.java
+++ b/net/minecraft/world/entity/decoration/ItemFrame.java
@@ -223,7 +223,11 @@ public class ItemFrame extends HangingEntity {
this.removeFramedMap(item);
} else {
if (dropItem) {
- this.spawnAtLocation(level, this.getFrameItemStack());
+ // Purpur start - Apply display names from item forms of entities to entities and vice versa
+ final ItemStack itemFrame = this.getFrameItemStack();
+ if (!level.purpurConfig.persistentDroppableEntityDisplayNames) itemFrame.set(DataComponents.CUSTOM_NAME, null);
+ this.spawnAtLocation(level, itemFrame);
+ // Purpur end - Apply display names from item forms of entities to entities and vice versa
}
if (!item.isEmpty()) {
diff --git a/net/minecraft/world/entity/decoration/Painting.java b/net/minecraft/world/entity/decoration/Painting.java
index 5b905a4d49c44b04d5795c2bf297f3c69d183d7c..b6429a2bbb6fc1e08610ab20e50f8f0414f0ad26 100644
--- a/net/minecraft/world/entity/decoration/Painting.java
+++ b/net/minecraft/world/entity/decoration/Painting.java
@@ -162,7 +162,11 @@ public class Painting extends HangingEntity implements VariantHolder<Holder<Pain
if (level.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) {
this.playSound(SoundEvents.PAINTING_BREAK, 1.0F, 1.0F);
if (!(entity instanceof Player player && player.hasInfiniteMaterials())) {
- this.spawnAtLocation(level, Items.PAINTING);
+ // Purpur start - Apply display names from item forms of entities to entities and vice versa
+ final ItemStack painting = new ItemStack(Items.PAINTING);
+ if (!this.level().purpurConfig.persistentDroppableEntityDisplayNames) painting.set(net.minecraft.core.component.DataComponents.CUSTOM_NAME, null);
+ this.spawnAtLocation(level, painting);
+ // Purpur end - Apply display names from item forms of entities to entities and vice versa
}
}
}
diff --git a/net/minecraft/world/entity/vehicle/AbstractBoat.java b/net/minecraft/world/entity/vehicle/AbstractBoat.java
index 4e724a12f13032075aeff7cf71b9ceabd5a7bd88..b1b312e45ed4514eaa6fb3941af64b641220c5bd 100644
--- a/net/minecraft/world/entity/vehicle/AbstractBoat.java
+++ b/net/minecraft/world/entity/vehicle/AbstractBoat.java
@@ -879,7 +879,13 @@ public abstract class AbstractBoat extends VehicleEntity implements Leashable {
@Override
public final ItemStack getPickResult() {
- return new ItemStack(this.dropItem.get());
+ // Purpur start - Apply display names from item forms of entities to entities and vice versa
+ final ItemStack boat = new ItemStack(this.dropItem.get());
+ if (!this.level().purpurConfig.persistentDroppableEntityDisplayNames) {
+ boat.set(net.minecraft.core.component.DataComponents.CUSTOM_NAME, null);
+ }
+ return boat;
+ // Purpur end - Apply display names from item forms of entities to entities and vice versa
}
public static enum Status {
diff --git a/net/minecraft/world/item/ArmorStandItem.java b/net/minecraft/world/item/ArmorStandItem.java
index d82e6651999a2650ec8884c4c3d8de4133cb42a4..a26b9fe964c79da57aaa0f755a81934f51a79913 100644
--- a/net/minecraft/world/item/ArmorStandItem.java
+++ b/net/minecraft/world/item/ArmorStandItem.java
@@ -51,6 +51,10 @@ public class ArmorStandItem extends Item {
return InteractionResult.FAIL;
}
// CraftBukkit end
+ // Purpur start - Apply display names from item forms of entities to entities and vice versa
+ if (!serverLevel.purpurConfig.persistentDroppableEntityDisplayNames) armorStand.setCustomName(null);
+ if (serverLevel.purpurConfig.armorstandSetNameVisible && armorStand.getCustomName() != null) armorStand.setCustomNameVisible(true);
+ // Purpur end - Apply display names from item forms of entities to entities and vice versa
serverLevel.addFreshEntityWithPassengers(armorStand);
level.playSound(
null, armorStand.getX(), armorStand.getY(), armorStand.getZ(), SoundEvents.ARMOR_STAND_PLACE, SoundSource.BLOCKS, 0.75F, 0.8F
diff --git a/net/minecraft/world/item/BoatItem.java b/net/minecraft/world/item/BoatItem.java
index 13ce174e4f7e406f57a68ea0d3ef0ee3367f3f3b..ca86122e38688b29340cd8413ccf1746315e292a 100644
--- a/net/minecraft/world/item/BoatItem.java
+++ b/net/minecraft/world/item/BoatItem.java
@@ -63,6 +63,7 @@ public class BoatItem extends Item {
return InteractionResult.FAIL;
} else {
boat.setYRot(player.getYRot());
+ if (!level.purpurConfig.persistentDroppableEntityDisplayNames) boat.setCustomName(null); // Purpur - Apply display names from item forms of entities to entities and vice versa
if (!level.noCollision(boat, boat.getBoundingBox())) {
return InteractionResult.FAIL;
} else {
diff --git a/net/minecraft/world/item/HangingEntityItem.java b/net/minecraft/world/item/HangingEntityItem.java
index 85980c7e5ad63398e0f0948fb0250f580251fe63..cd9e0398876567afc337db8f6ff0ebb0ee162383 100644
--- a/net/minecraft/world/item/HangingEntityItem.java
+++ b/net/minecraft/world/item/HangingEntityItem.java
@@ -62,6 +62,7 @@ public class HangingEntityItem extends Item {
CustomData customData = itemInHand.getOrDefault(DataComponents.ENTITY_DATA, CustomData.EMPTY);
if (!customData.isEmpty()) {
EntityType.updateCustomEntityTag(level, player, hangingEntity, customData);
+ if (!level.purpurConfig.persistentDroppableEntityDisplayNames) hangingEntity.setCustomName(null); // Purpur - Apply display names from item forms of entities to entities and vice versa
}
if (hangingEntity.survives()) {

View File

@@ -0,0 +1,171 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Sat, 5 Dec 2020 01:20:16 -0800
Subject: [PATCH] Option for Villager Clerics to farm Nether Wart
Adds an option so that Villagers with the Cleric profession are able to
farm Nether Wart. Reimplemented based on a feature of the carpet-extra
mod.
diff --git a/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java b/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java
index 4106549bd4dec1cc47d8765be8f5d119fe33bf56..e98fac58b29f78cb63bd868811cca41e1644e9ac 100644
--- a/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java
+++ b/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java
@@ -32,6 +32,7 @@ public class HarvestFarmland extends Behavior<Villager> {
private long nextOkStartTime;
private int timeWorkedSoFar;
private final List<BlockPos> validFarmlandAroundVillager = Lists.newArrayList();
+ private boolean clericWartFarmer = false; // Purpur - Option for Villager Clerics to farm Nether Wart
public HarvestFarmland() {
super(
@@ -50,9 +51,10 @@ public class HarvestFarmland extends Behavior<Villager> {
protected boolean checkExtraStartConditions(ServerLevel level, Villager owner) {
if (!level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
return false;
- } else if (owner.getVillagerData().getProfession() != VillagerProfession.FARMER) {
+ } else if (owner.getVillagerData().getProfession() != VillagerProfession.FARMER && !(level.purpurConfig.villagerClericsFarmWarts && owner.getVillagerData().getProfession() == VillagerProfession.CLERIC)) { // Purpur - Option for Villager Clerics to farm Nether Wart
return false;
} else {
+ if (!this.clericWartFarmer && owner.getVillagerData().getProfession() == VillagerProfession.CLERIC) this.clericWartFarmer = true; // Purpur - Option for Villager Clerics to farm Nether Wart
BlockPos.MutableBlockPos mutableBlockPos = owner.blockPosition().mutable();
this.validFarmlandAroundVillager.clear();
@@ -83,6 +85,7 @@ public class HarvestFarmland extends Behavior<Villager> {
BlockState blockState = serverLevel.getBlockState(pos);
Block block = blockState.getBlock();
Block block1 = serverLevel.getBlockState(pos.below()).getBlock();
+ if (this.clericWartFarmer) return block == net.minecraft.world.level.block.Blocks.NETHER_WART && blockState.getValue(net.minecraft.world.level.block.NetherWartBlock.AGE) == 3 || blockState.isAir() && block1 == net.minecraft.world.level.block.Blocks.SOUL_SAND; // Purpur - Option for Villager Clerics to farm Nether Wart
return block instanceof CropBlock && ((CropBlock)block).isMaxAge(blockState) || blockState.isAir() && block1 instanceof FarmBlock;
}
@@ -109,19 +112,19 @@ public class HarvestFarmland extends Behavior<Villager> {
BlockState blockState = level.getBlockState(this.aboveFarmlandPos);
Block block = blockState.getBlock();
Block block1 = level.getBlockState(this.aboveFarmlandPos.below()).getBlock();
- if (block instanceof CropBlock && ((CropBlock)block).isMaxAge(blockState)) {
+ if (block instanceof CropBlock && ((CropBlock)block).isMaxAge(blockState) && !this.clericWartFarmer || this.clericWartFarmer && block == net.minecraft.world.level.block.Blocks.NETHER_WART && blockState.getValue(net.minecraft.world.level.block.NetherWartBlock.AGE) == 3) { // Purpur - Option for Villager Clerics to farm Nether Wart
if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(owner, this.aboveFarmlandPos, blockState.getFluidState().createLegacyBlock())) { // CraftBukkit // Paper - fix wrong block state
level.destroyBlock(this.aboveFarmlandPos, true, owner);
} // CraftBukkit
}
- if (blockState.isAir() && block1 instanceof FarmBlock && owner.hasFarmSeeds()) {
+ if (blockState.isAir() && block1 instanceof FarmBlock && !this.clericWartFarmer || this.clericWartFarmer && block1 == net.minecraft.world.level.block.Blocks.SOUL_SAND && owner.hasFarmSeeds()) { // Purpur - Option for Villager Clerics to farm Nether Wart
SimpleContainer inventory = owner.getInventory();
for (int i = 0; i < inventory.getContainerSize(); i++) {
ItemStack item = inventory.getItem(i);
boolean flag = false;
- if (!item.isEmpty() && item.is(ItemTags.VILLAGER_PLANTABLE_SEEDS) && item.getItem() instanceof BlockItem blockItem) {
+ if (!item.isEmpty() && (item.is(ItemTags.VILLAGER_PLANTABLE_SEEDS) || this.clericWartFarmer && item.getItem() == net.minecraft.world.item.Items.NETHER_WART) && item.getItem() instanceof BlockItem blockItem) { // Purpur - Option for Villager Clerics to farm Nether Wart
BlockState blockState1 = blockItem.getBlock().defaultBlockState();
if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(owner, this.aboveFarmlandPos, blockState1)) { // CraftBukkit
level.setBlockAndUpdate(this.aboveFarmlandPos, blockState1);
@@ -136,7 +139,7 @@ public class HarvestFarmland extends Behavior<Villager> {
this.aboveFarmlandPos.getX(),
this.aboveFarmlandPos.getY(),
this.aboveFarmlandPos.getZ(),
- SoundEvents.CROP_PLANTED,
+ this.clericWartFarmer ? SoundEvents.NETHER_WART_PLANTED : SoundEvents.CROP_PLANTED, // Purpur - Option for Villager Clerics to farm Nether Wart
SoundSource.BLOCKS,
1.0F,
1.0F
diff --git a/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java b/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java
index 243ac036f95794e7766aefb4630b635681ae5a5f..4d8523a43d60cd6b4fd5546ffb3a61417b2c475b 100644
--- a/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java
+++ b/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java
@@ -59,6 +59,12 @@ public class TradeWithVillager extends Behavior<Villager> {
throwHalfStack(owner, ImmutableSet.of(Items.WHEAT), villager);
}
+ // Purpur start - Option for Villager Clerics to farm Nether Wart
+ if (level.purpurConfig.villagerClericsFarmWarts && level.purpurConfig.villagerClericFarmersThrowWarts && owner.getVillagerData().getProfession() == VillagerProfession.CLERIC && owner.getInventory().countItem(Items.NETHER_WART) > Items.NETHER_WART.getDefaultMaxStackSize() / 2) {
+ throwHalfStack(owner, ImmutableSet.of(Items.NETHER_WART), villager);
+ }
+ // Purpur end - Option for Villager Clerics to farm Nether Wart
+
if (!this.trades.isEmpty() && owner.getInventory().hasAnyOf(this.trades)) {
throwHalfStack(owner, this.trades, villager);
}
diff --git a/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java b/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java
index 84afd8646b05409c582f29d73f9fea4b09feb603..32779b121322688a4b14e460b1f902ef67770b32 100644
--- a/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java
+++ b/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java
@@ -74,8 +74,13 @@ public class VillagerGoalPackages {
}
public static ImmutableList<Pair<Integer, ? extends BehaviorControl<? super Villager>>> getWorkPackage(VillagerProfession profession, float speedModifier) {
+ // Purpur start - Option for Villager Clerics to farm Nether Wart
+ return getWorkPackage(profession, speedModifier, false);
+ }
+ public static ImmutableList<Pair<Integer, ? extends BehaviorControl<? super Villager>>> getWorkPackage(VillagerProfession profession, float speedModifier, boolean clericsFarmWarts) {
+ // Purpur end - Option for Villager Clerics to farm Nether Wart
WorkAtPoi workAtPoi;
- if (profession == VillagerProfession.FARMER) {
+ if (profession == VillagerProfession.FARMER || (clericsFarmWarts && profession == VillagerProfession.CLERIC)) { // Purpur - Option for Villager Clerics to farm Nether Wart
workAtPoi = new WorkAtComposter();
} else {
workAtPoi = new WorkAtPoi();
diff --git a/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java b/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java
index 6b99afb4f237b5d6def98f3e03492975b795bc95..234e9d4aca14bc2a2e138918be1430516d710060 100644
--- a/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java
+++ b/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java
@@ -22,6 +22,13 @@ public class SecondaryPoiSensor extends Sensor<Villager> {
@Override
protected void doTick(ServerLevel level, Villager entity) {
+ // Purpur start - Option for Villager Clerics to farm Nether Wart - make sure clerics don't wander to soul sand when the option is off
+ Brain<?> brain = entity.getBrain();
+ if (!level.purpurConfig.villagerClericsFarmWarts && entity.getVillagerData().getProfession() == net.minecraft.world.entity.npc.VillagerProfession.CLERIC) {
+ brain.eraseMemory(MemoryModuleType.SECONDARY_JOB_SITE);
+ return;
+ }
+ // Purpur end - Option for Villager Clerics to farm Nether Wart
ResourceKey<Level> resourceKey = level.dimension();
BlockPos blockPos = entity.blockPosition();
List<GlobalPos> list = Lists.newArrayList();
@@ -38,7 +45,7 @@ public class SecondaryPoiSensor extends Sensor<Villager> {
}
}
- Brain<?> brain = entity.getBrain();
+ //Brain<?> brain = entity.getBrain(); // Purpur - Option for Villager Clerics to farm Nether Wart - moved up
if (!list.isEmpty()) {
brain.setMemory(MemoryModuleType.SECONDARY_JOB_SITE, list);
} else {
diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java
index ff07cfe07200be23f17310522d737fca3251a580..017b54e0b8dec8996c90a3c6651867277dd516df 100644
--- a/net/minecraft/world/entity/npc/Villager.java
+++ b/net/minecraft/world/entity/npc/Villager.java
@@ -311,7 +311,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
villagerBrain.setSchedule(Schedule.VILLAGER_DEFAULT);
villagerBrain.addActivityWithConditions(
Activity.WORK,
- VillagerGoalPackages.getWorkPackage(profession, 0.5F),
+ VillagerGoalPackages.getWorkPackage(profession, 0.5F, this.level().purpurConfig.villagerClericsFarmWarts), // Purpur - Option for Villager Clerics to farm Nether Wart
ImmutableSet.of(Pair.of(MemoryModuleType.JOB_SITE, MemoryStatus.VALUE_PRESENT))
);
}
@@ -977,7 +977,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
}
public boolean hasFarmSeeds() {
- return this.getInventory().hasAnyMatching(itemStack -> itemStack.is(ItemTags.VILLAGER_PLANTABLE_SEEDS));
+ return this.getInventory().hasAnyMatching(itemStack -> this.level().purpurConfig.villagerClericsFarmWarts && this.getVillagerData().getProfession() == VillagerProfession.CLERIC ? itemStack.is(Items.NETHER_WART) : itemStack.is(ItemTags.VILLAGER_PLANTABLE_SEEDS)); // Purpur - Option for Villager Clerics to farm Nether Wart
}
@Override
diff --git a/net/minecraft/world/entity/npc/VillagerProfession.java b/net/minecraft/world/entity/npc/VillagerProfession.java
index 1ec8ad124c76483d11057eb97fcfb9aebee0c301..f783d058a080408d572938d36ba031f33a08e9af 100644
--- a/net/minecraft/world/entity/npc/VillagerProfession.java
+++ b/net/minecraft/world/entity/npc/VillagerProfession.java
@@ -31,7 +31,7 @@ public record VillagerProfession(
public static final VillagerProfession ARMORER = register("armorer", PoiTypes.ARMORER, SoundEvents.VILLAGER_WORK_ARMORER);
public static final VillagerProfession BUTCHER = register("butcher", PoiTypes.BUTCHER, SoundEvents.VILLAGER_WORK_BUTCHER);
public static final VillagerProfession CARTOGRAPHER = register("cartographer", PoiTypes.CARTOGRAPHER, SoundEvents.VILLAGER_WORK_CARTOGRAPHER);
- public static final VillagerProfession CLERIC = register("cleric", PoiTypes.CLERIC, SoundEvents.VILLAGER_WORK_CLERIC);
+ public static final VillagerProfession CLERIC = register("cleric", PoiTypes.CLERIC, ImmutableSet.of(Items.NETHER_WART), ImmutableSet.of(Blocks.SOUL_SAND), SoundEvents.VILLAGER_WORK_CLERIC); // Purpur - Option for Villager Clerics to farm Nether Wart
public static final VillagerProfession FARMER = register(
"farmer",
PoiTypes.FARMER,

View File

@@ -0,0 +1,360 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Tue, 5 Jan 2021 22:21:56 -0500
Subject: [PATCH] Add mobGriefing bypass to everything affected
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
index 6de5f527c018201d874e06a45c9509fa12125766..2dc588e2d503c16ccd2589ce18abd2ecebbc8e74 100644
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -1818,7 +1818,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
if (this.level() instanceof ServerLevel serverLevel) {
boolean var6 = false;
if (this.dead && entitySource instanceof WitherBoss) { // Paper
- if (serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (serverLevel.purpurConfig.witherBypassMobGriefing ^ serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur - Add mobGriefing bypass to everything affected
BlockPos blockPos = this.blockPosition();
BlockState blockState = Blocks.WITHER_ROSE.defaultBlockState();
if (this.level().getBlockState(blockPos).isAir() && blockState.canSurvive(this.level(), blockPos)) {
diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java
index c431f28c3f4f6cec946048f5752c364429af5ba1..d93584c6793818463e8883ffe399bf16b03263a9 100644
--- a/net/minecraft/world/entity/Mob.java
+++ b/net/minecraft/world/entity/Mob.java
@@ -648,7 +648,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
&& this.canPickUpLoot()
&& this.isAlive()
&& !this.dead
- && serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ && serverLevel.purpurConfig.entitiesPickUpLootBypassMobGriefing ^ serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur - Add mobGriefing bypass to everything affected
Vec3i pickupReach = this.getPickupReach();
for (ItemEntity itemEntity : this.level()
diff --git a/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java b/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java
index e98fac58b29f78cb63bd868811cca41e1644e9ac..56d49bc71cb0cb0a08ff771991fd77ab774b4b59 100644
--- a/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java
+++ b/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java
@@ -49,7 +49,7 @@ public class HarvestFarmland extends Behavior<Villager> {
@Override
protected boolean checkExtraStartConditions(ServerLevel level, Villager owner) {
- if (!level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (!level.purpurConfig.villagerBypassMobGriefing == !level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur - Add mobGriefing bypass to everything affected
return false;
} else if (owner.getVillagerData().getProfession() != VillagerProfession.FARMER && !(level.purpurConfig.villagerClericsFarmWarts && owner.getVillagerData().getProfession() == VillagerProfession.CLERIC)) { // Purpur - Option for Villager Clerics to farm Nether Wart
return false;
diff --git a/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java b/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java
index e026e07ca86700c864a3dceda6817fb7b6cb11e9..f1dfe0bf047e7d331b2379a672ff7b8eae4c9c90 100644
--- a/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java
+++ b/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java
@@ -30,7 +30,7 @@ public class BreakDoorGoal extends DoorInteractGoal {
@Override
public boolean canUse() {
return super.canUse()
- && getServerLevel(this.mob).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)
+ && this.mob.level().purpurConfig.zombieBypassMobGriefing == !getServerLevel(this.mob).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) // Purpur - Add mobGriefing bypass to everything affected
&& this.isValidDifficulty(this.mob.level().getDifficulty())
&& !this.isOpen();
}
diff --git a/net/minecraft/world/entity/ai/goal/EatBlockGoal.java b/net/minecraft/world/entity/ai/goal/EatBlockGoal.java
index e84893780b533b1ecb3675606b5c2daf7339b861..65eb4d8001b07cb3f7cda17565eea10a88a9c47c 100644
--- a/net/minecraft/world/entity/ai/goal/EatBlockGoal.java
+++ b/net/minecraft/world/entity/ai/goal/EatBlockGoal.java
@@ -67,7 +67,7 @@ public class EatBlockGoal extends Goal {
BlockPos blockPos = this.mob.blockPosition();
final BlockState blockState = this.level.getBlockState(blockPos); // Paper - fix wrong block state
if (IS_TALL_GRASS.test(blockState)) { // Paper - fix wrong block state
- if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockPos, blockState.getFluidState().createLegacyBlock(), !getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Paper - fix wrong block state
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockPos, blockState.getFluidState().createLegacyBlock(), !getServerLevel(this.level).purpurConfig.sheepBypassMobGriefing == !getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Paper - fix wrong block state // Purpur - Add mobGriefing bypass to everything affected
this.level.destroyBlock(blockPos, false);
}
@@ -75,7 +75,7 @@ public class EatBlockGoal extends Goal {
} else {
BlockPos blockPos1 = blockPos.below();
if (this.level.getBlockState(blockPos1).is(Blocks.GRASS_BLOCK)) {
- if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockPos1, Blocks.DIRT.defaultBlockState(), !getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Paper - Fix wrong block state
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockPos1, Blocks.DIRT.defaultBlockState(), !getServerLevel(this.level).purpurConfig.sheepBypassMobGriefing == !getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Paper - Fix wrong block state // Purpur - Add mobGriefing bypass to everything affected
this.level.levelEvent(2001, blockPos1, Block.getId(Blocks.GRASS_BLOCK.defaultBlockState()));
this.level.setBlock(blockPos1, Blocks.DIRT.defaultBlockState(), 2);
}
diff --git a/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java b/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java
index 579ca031d461ed4327fe4fb45c5289565322e64e..95fa516910a3834bbd4db6d11279e13a1f0dac41 100644
--- a/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java
+++ b/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java
@@ -35,7 +35,7 @@ public class RemoveBlockGoal extends MoveToBlockGoal {
@Override
public boolean canUse() {
- if (!getServerLevel(this.removerMob).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (!getServerLevel(this.removerMob).purpurConfig.zombieBypassMobGriefing == !getServerLevel(this.removerMob).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur - Add mobGriefing bypass to everything affected
return false;
} else if (this.nextStartTick > 0) {
this.nextStartTick--;
diff --git a/net/minecraft/world/entity/animal/Fox.java b/net/minecraft/world/entity/animal/Fox.java
index 1acf9b8c9e6a5915b3f095e83d3f209708947093..3d94d5c9ecab0fe7332daf4cdac879385159eaa1 100644
--- a/net/minecraft/world/entity/animal/Fox.java
+++ b/net/minecraft/world/entity/animal/Fox.java
@@ -1038,7 +1038,7 @@ public class Fox extends Animal implements VariantHolder<Fox.Variant> {
}
protected void onReachedTarget() {
- if (getServerLevel(Fox.this.level()).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (getServerLevel(Fox.this.level()).purpurConfig.foxBypassMobGriefing ^ getServerLevel(Fox.this.level()).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur - Add mobGriefing bypass to everything affected
BlockState blockState = Fox.this.level().getBlockState(this.blockPos);
if (blockState.is(Blocks.SWEET_BERRY_BUSH)) {
this.pickSweetBerries(blockState);
diff --git a/net/minecraft/world/entity/animal/Rabbit.java b/net/minecraft/world/entity/animal/Rabbit.java
index bbdd06002b07699fffebdf6ed8148abdb69c24cc..7379def14f3f700fb8a746dc89d89e249e93b7b9 100644
--- a/net/minecraft/world/entity/animal/Rabbit.java
+++ b/net/minecraft/world/entity/animal/Rabbit.java
@@ -620,7 +620,7 @@ public class Rabbit extends Animal implements VariantHolder<Rabbit.Variant> {
@Override
public boolean canUse() {
if (this.nextStartTick <= 0) {
- if (!getServerLevel(this.rabbit).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (!getServerLevel(this.rabbit).purpurConfig.rabbitBypassMobGriefing == !getServerLevel(this.rabbit).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur - Add mobGriefing bypass to everything affected
return false;
}
diff --git a/net/minecraft/world/entity/animal/SnowGolem.java b/net/minecraft/world/entity/animal/SnowGolem.java
index d97a297db3bec0c86c6a82ef1c353015df2115f7..6ee73b798ab306f7c828c9f06ca5b1a96bd96139 100644
--- a/net/minecraft/world/entity/animal/SnowGolem.java
+++ b/net/minecraft/world/entity/animal/SnowGolem.java
@@ -136,7 +136,7 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
this.hurtServer(serverLevel, this.damageSources().melting(), 1.0F); // CraftBukkit - DamageSources.ON_FIRE -> CraftEventFactory.MELTING
}
- if (!serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (!serverLevel.purpurConfig.snowGolemBypassMobGriefing == !serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur - Add mobGriefing bypass to everything affected
return;
}
diff --git a/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
index ca900bb646e16c7b4342f23c3ffae786eab28145..724d259d4b793f2043e63dda9022bdfddc4dca38 100644
--- a/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
+++ b/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
@@ -547,7 +547,7 @@ public class EnderDragon extends Mob implements Enemy {
BlockPos blockPos = new BlockPos(i, i1, i2);
BlockState blockState = level.getBlockState(blockPos);
if (!blockState.isAir() && !blockState.is(BlockTags.DRAGON_TRANSPARENT)) {
- if (level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && !blockState.is(BlockTags.DRAGON_IMMUNE)) {
+ if (level.purpurConfig.enderDragonBypassMobGriefing ^ level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && !blockState.is(BlockTags.DRAGON_IMMUNE)) { // Purpur - Add mobGriefing bypass to everything affected
// CraftBukkit start - Add blocks to list rather than destroying them
//flag1 = level.removeBlock(blockPos, false) || flag1;
flag1 = true;
diff --git a/net/minecraft/world/entity/boss/wither/WitherBoss.java b/net/minecraft/world/entity/boss/wither/WitherBoss.java
index 60e666aa8afe14b519010b6d137a89e3d22f6c81..a325fa87e149e7f354ed4cf3dbb30a002c4ce32a 100644
--- a/net/minecraft/world/entity/boss/wither/WitherBoss.java
+++ b/net/minecraft/world/entity/boss/wither/WitherBoss.java
@@ -493,7 +493,7 @@ public class WitherBoss extends Monster implements RangedAttackMob {
if (this.destroyBlocksTick > 0) {
this.destroyBlocksTick--;
- if (this.destroyBlocksTick == 0 && level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (this.destroyBlocksTick == 0 && level.purpurConfig.witherBypassMobGriefing ^ level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur - Add mobGriefing bypass to everything affected
boolean flag = false;
int alternativeTarget = Mth.floor(this.getBbWidth() / 2.0F + 1.0F);
int floor = Mth.floor(this.getBbHeight());
diff --git a/net/minecraft/world/entity/monster/EnderMan.java b/net/minecraft/world/entity/monster/EnderMan.java
index f8d6935439b4e672ed655b2a458451d4b1fa8ffd..7b74322aef3d7d45a322abccc71d9168b3c0911b 100644
--- a/net/minecraft/world/entity/monster/EnderMan.java
+++ b/net/minecraft/world/entity/monster/EnderMan.java
@@ -516,7 +516,7 @@ public class EnderMan extends Monster implements NeutralMob {
public boolean canUse() {
if (!enderman.level().purpurConfig.endermanAllowGriefing) return false; // Purpur - Add enderman and creeper griefing controls
return this.enderman.getCarriedBlock() != null
- && getServerLevel(this.enderman).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)
+ && getServerLevel(this.enderman).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) == !this.enderman.level().purpurConfig.endermanBypassMobGriefing // Purpur - Add mobGriefing bypass to everything affected
&& this.enderman.getRandom().nextInt(reducedTickDelay(2000)) == 0;
}
@@ -666,7 +666,7 @@ public class EnderMan extends Monster implements NeutralMob {
public boolean canUse() {
if (!enderman.level().purpurConfig.endermanAllowGriefing) return false; // Purpur - Add enderman and creeper griefing controls
return this.enderman.getCarriedBlock() == null
- && getServerLevel(this.enderman).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)
+ && getServerLevel(this.enderman).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) == !this.enderman.level().purpurConfig.endermanBypassMobGriefing // Purpur - Add mobGriefing bypass to everything affected
&& this.enderman.getRandom().nextInt(reducedTickDelay(20)) == 0;
}
diff --git a/net/minecraft/world/entity/monster/Evoker.java b/net/minecraft/world/entity/monster/Evoker.java
index d3d7e11a12af404d83e81888a9a633dfb93412ec..91574baf7ca095eae909e8e7225ad500bde15af2 100644
--- a/net/minecraft/world/entity/monster/Evoker.java
+++ b/net/minecraft/world/entity/monster/Evoker.java
@@ -323,7 +323,7 @@ public class Evoker extends SpellcasterIllager {
return false;
} else {
ServerLevel serverLevel = getServerLevel(Evoker.this.level());
- if (!serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (!serverLevel.purpurConfig.evokerBypassMobGriefing == !serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur - Add mobGriefing bypass to everything affected
return false;
} else {
List<Sheep> nearbyEntities = serverLevel.getNearbyEntities(
diff --git a/net/minecraft/world/entity/monster/Ravager.java b/net/minecraft/world/entity/monster/Ravager.java
index 36ebfc1102a18e4050eb9a2441d75bafcf3784b8..3449628fb87fd760abd730d84699c3a09c6ec761 100644
--- a/net/minecraft/world/entity/monster/Ravager.java
+++ b/net/minecraft/world/entity/monster/Ravager.java
@@ -175,7 +175,7 @@ public class Ravager extends Raider {
if (this.level() instanceof ServerLevel serverLevel
&& this.horizontalCollision
- && serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ && serverLevel.purpurConfig.ravagerBypassMobGriefing ^ serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur - Add mobGriefing bypass to everything affected
boolean flag = false;
AABB aabb = this.getBoundingBox().inflate(0.2);
diff --git a/net/minecraft/world/entity/monster/Silverfish.java b/net/minecraft/world/entity/monster/Silverfish.java
index d3befe91bc65bbc2bc0d8651b78e8c9576cd0f75..0d3b8b64a23a19d67a1a4a01faaf6649a59f54ad 100644
--- a/net/minecraft/world/entity/monster/Silverfish.java
+++ b/net/minecraft/world/entity/monster/Silverfish.java
@@ -170,7 +170,7 @@ public class Silverfish extends Monster {
return false;
} else {
RandomSource random = this.mob.getRandom();
- if (getServerLevel(this.mob).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && random.nextInt(reducedTickDelay(10)) == 0) {
+ if (getServerLevel(this.mob).purpurConfig.silverfishBypassMobGriefing ^ getServerLevel(this.mob).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && random.nextInt(reducedTickDelay(10)) == 0) { // Purpur - Add mobGriefing bypass to everything affected
this.selectedDirection = Direction.getRandom(random);
BlockPos blockPos = BlockPos.containing(this.mob.getX(), this.mob.getY() + 0.5, this.mob.getZ()).relative(this.selectedDirection);
BlockState blockState = this.mob.level().getBlockState(blockPos);
@@ -247,7 +247,7 @@ public class Silverfish extends Monster {
Block block = blockState.getBlock();
if (block instanceof InfestedBlock) {
// CraftBukkit start
- BlockState afterState = getServerLevel(level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ? blockState.getFluidState().createLegacyBlock() : ((InfestedBlock) block).hostStateByInfested(level.getBlockState(blockPos1)); // Paper - fix wrong block state
+ BlockState afterState = getServerLevel(level).purpurConfig.silverfishBypassMobGriefing ^ getServerLevel(level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ? blockState.getFluidState().createLegacyBlock() : ((InfestedBlock) block).hostStateByInfested(level.getBlockState(blockPos1)); // Paper - fix wrong block state // Purpur - Add mobGriefing bypass to everything affected
if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.silverfish, blockPos1, afterState)) { // Paper - fix wrong block state
continue;
}
diff --git a/net/minecraft/world/entity/monster/piglin/Piglin.java b/net/minecraft/world/entity/monster/piglin/Piglin.java
index 897c57263ab7347987b289016a71d11f693bc8b2..d923a424e2b33b7d4e9e4ecdce8e0a8c825038de 100644
--- a/net/minecraft/world/entity/monster/piglin/Piglin.java
+++ b/net/minecraft/world/entity/monster/piglin/Piglin.java
@@ -473,7 +473,7 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento
@Override
public boolean wantsToPickUp(ServerLevel level, ItemStack stack) {
- return level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && this.canPickUpLoot() && PiglinAi.wantsToPickup(this, stack);
+ return level.purpurConfig.piglinBypassMobGriefing ^ level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && this.canPickUpLoot() && PiglinAi.wantsToPickup(this, stack); // Purpur - Add mobGriefing bypass to everything affected
}
protected boolean canReplaceCurrentItem(ItemStack candidate) {
diff --git a/net/minecraft/world/entity/projectile/LargeFireball.java b/net/minecraft/world/entity/projectile/LargeFireball.java
index 4a752ace041228f095af7b1b4878a03c5ed2381f..3e8b5d042eddb817dee2504ff9aa263f6195b1c7 100644
--- a/net/minecraft/world/entity/projectile/LargeFireball.java
+++ b/net/minecraft/world/entity/projectile/LargeFireball.java
@@ -18,20 +18,20 @@ public class LargeFireball extends Fireball {
public LargeFireball(EntityType<? extends LargeFireball> entityType, Level level) {
super(entityType, level);
- this.isIncendiary = (level instanceof ServerLevel serverLevel) && serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit
+ this.isIncendiary = (level instanceof ServerLevel serverLevel) && serverLevel.purpurConfig.fireballsBypassMobGriefing ^ serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit // Purpur - Add mobGriefing bypass to everything affected
}
public LargeFireball(Level level, LivingEntity owner, Vec3 movement, int explosionPower) {
super(EntityType.FIREBALL, owner, movement, level);
this.explosionPower = explosionPower;
- this.isIncendiary = (level instanceof ServerLevel serverLevel) && serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit
+ this.isIncendiary = (level instanceof ServerLevel serverLevel) && serverLevel.purpurConfig.fireballsBypassMobGriefing ^ serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit // Purpur - Add mobGriefing bypass to everything affected
}
@Override
protected void onHit(HitResult result) {
super.onHit(result);
if (this.level() instanceof ServerLevel serverLevel) {
- boolean _boolean = serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
+ boolean _boolean = serverLevel.purpurConfig.fireballsBypassMobGriefing ^ serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // Purpur - Add mobGriefing bypass to everything affected
// CraftBukkit start - fire ExplosionPrimeEvent
org.bukkit.event.entity.ExplosionPrimeEvent event = new org.bukkit.event.entity.ExplosionPrimeEvent((org.bukkit.entity.Explosive) this.getBukkitEntity());
this.level().getCraftServer().getPluginManager().callEvent(event);
diff --git a/net/minecraft/world/entity/projectile/Projectile.java b/net/minecraft/world/entity/projectile/Projectile.java
index ad0bb896d6ea669ce88bfe6490319e8ba7a29001..843f1396a6567672e5e8002d7e48fb18cf39d5de 100644
--- a/net/minecraft/world/entity/projectile/Projectile.java
+++ b/net/minecraft/world/entity/projectile/Projectile.java
@@ -454,7 +454,7 @@ public abstract class Projectile extends Entity implements TraceableEntity {
@Override
public boolean mayInteract(ServerLevel level, BlockPos pos) {
Entity owner = this.getOwner();
- return owner instanceof Player ? owner.mayInteract(level, pos) : owner == null || level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
+ return owner instanceof Player ? owner.mayInteract(level, pos) : owner == null || level.purpurConfig.projectilesBypassMobGriefing ^ level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // Purpur - Add mobGriefing bypass to everything affected
}
public boolean mayBreak(ServerLevel level) {
diff --git a/net/minecraft/world/entity/projectile/SmallFireball.java b/net/minecraft/world/entity/projectile/SmallFireball.java
index 8c84cea43fc0e42a576004663670977eac99f1a6..808aa5dcb27c87b6ba5c1eee639486067447e370 100644
--- a/net/minecraft/world/entity/projectile/SmallFireball.java
+++ b/net/minecraft/world/entity/projectile/SmallFireball.java
@@ -25,7 +25,7 @@ public class SmallFireball extends Fireball {
super(EntityType.SMALL_FIREBALL, owner, movement, level);
// CraftBukkit start
if (this.getOwner() != null && this.getOwner() instanceof Mob) {
- this.isIncendiary = (level instanceof ServerLevel serverLevel) && serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
+ this.isIncendiary = (level instanceof ServerLevel serverLevel) && serverLevel.purpurConfig.fireballsBypassMobGriefing ^ serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // Purpur - Add mobGriefing bypass to everything affected
}
// CraftBukkit end
}
diff --git a/net/minecraft/world/entity/raid/Raider.java b/net/minecraft/world/entity/raid/Raider.java
index 8270d76a753bfd26a4c8ef6610bee5c24ee59cfe..c06b589e669b055a26f662df60070d5908256220 100644
--- a/net/minecraft/world/entity/raid/Raider.java
+++ b/net/minecraft/world/entity/raid/Raider.java
@@ -399,7 +399,7 @@ public abstract class Raider extends PatrollingMonster {
}
private boolean cannotPickUpBanner() {
- if (!getServerLevel(this.mob).getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING) || !this.mob.canPickUpLoot()) return false; // Paper - respect game and entity rules for picking up items
+ if (!this.mob.level().purpurConfig.pillagerBypassMobGriefing == !getServerLevel(this.mob).getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING) || !this.mob.canPickUpLoot()) return false; // Paper - respect game and entity rules for picking up items // Purpur - Add mobGriefing bypass to everything affected
if (!this.mob.hasActiveRaid()) {
return true;
} else if (this.mob.getCurrentRaid().isOver()) {
diff --git a/net/minecraft/world/level/block/CropBlock.java b/net/minecraft/world/level/block/CropBlock.java
index b43f16297ac4441d78d0dc1fadb555698b0c3f6d..27f0c5c886a3f8b14ef9a00e2aaaabf4bf09c7db 100644
--- a/net/minecraft/world/level/block/CropBlock.java
+++ b/net/minecraft/world/level/block/CropBlock.java
@@ -182,7 +182,7 @@ public class CropBlock extends BushBlock implements BonemealableBlock {
@Override
protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) {
if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
- if (level instanceof ServerLevel serverLevel && entity instanceof Ravager && serverLevel.purpurConfig.ravagerGriefableBlocks.contains(serverLevel.getBlockState(pos).getBlock()) && org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Purpur - Configurable ravager griefable blocks list
+ if (level instanceof ServerLevel serverLevel && entity instanceof Ravager && serverLevel.purpurConfig.ravagerGriefableBlocks.contains(serverLevel.getBlockState(pos).getBlock()) && org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !serverLevel.purpurConfig.ravagerBypassMobGriefing == !serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Purpur - Configurable ravager griefable blocks list // Purpur - Add mobGriefing bypass to everything affected
serverLevel.destroyBlock(pos, true, entity);
}
diff --git a/net/minecraft/world/level/block/FarmBlock.java b/net/minecraft/world/level/block/FarmBlock.java
index 6ab9a1188ce60e114ef35e393d9f2f46d490af83..9a7ca836e54cc3f58001c85f0079747f4d4941ad 100644
--- a/net/minecraft/world/level/block/FarmBlock.java
+++ b/net/minecraft/world/level/block/FarmBlock.java
@@ -114,7 +114,7 @@ public class FarmBlock extends Block {
if (level instanceof ServerLevel serverLevel
&& (serverLevel.purpurConfig.farmlandTrampleHeight >= 0D ? fallDistance >= serverLevel.purpurConfig.farmlandTrampleHeight : level.random.nextFloat() < fallDistance - 0.5F) // // Purpur - Configurable farmland trample height
&& entity instanceof LivingEntity
- && (entity instanceof Player || serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))
+ && (entity instanceof Player || serverLevel.purpurConfig.farmlandBypassMobGriefing ^ serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))
&& entity.getBbWidth() * entity.getBbWidth() * entity.getBbHeight() > 0.512F) {
// CraftBukkit start - Interact soil
org.bukkit.event.Cancellable cancellable;
diff --git a/net/minecraft/world/level/block/PowderSnowBlock.java b/net/minecraft/world/level/block/PowderSnowBlock.java
index 9c0ded7ae7e3a520704033a866f80743ae85d772..4f3646961beb877520e257e11224c3045467d351 100644
--- a/net/minecraft/world/level/block/PowderSnowBlock.java
+++ b/net/minecraft/world/level/block/PowderSnowBlock.java
@@ -84,7 +84,7 @@ public class PowderSnowBlock extends Block implements BucketPickup {
// CraftBukkit - move down
&& entity.mayInteract(serverLevel, pos)) {
// CraftBukkit start
- if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !(serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) || entity instanceof Player))) {
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !(serverLevel.purpurConfig.powderSnowBypassMobGriefing ^ serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) || entity instanceof Player))) {
return;
}
// CraftBukkit end
diff --git a/net/minecraft/world/level/block/TurtleEggBlock.java b/net/minecraft/world/level/block/TurtleEggBlock.java
index c97d5bd7b4c1b6f8eccbe2d123292e913a285ef2..a3a093d95306baac22e5cf720f5b14f733b548d4 100644
--- a/net/minecraft/world/level/block/TurtleEggBlock.java
+++ b/net/minecraft/world/level/block/TurtleEggBlock.java
@@ -216,7 +216,7 @@ public class TurtleEggBlock extends Block {
// Purpur end - Option to disable turtle egg trampling with feather falling
if (entity instanceof Player) return true;
- return level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
+ return level.purpurConfig.turtleEggsBypassMobGriefing ^ level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // Purpur - Add mobGriefing bypass to everything affected
// Purpur end - Add turtle egg block options
}
}

View File

@@ -0,0 +1,72 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mariell Hoversholm <proximyst@proximyst.com>
Date: Sat, 9 Jan 2021 15:26:04 +0100
Subject: [PATCH] Add EntityTeleportHinderedEvent
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
diff --git a/net/minecraft/world/level/block/EndGatewayBlock.java b/net/minecraft/world/level/block/EndGatewayBlock.java
index 84a1bd5e40e635962d795506861447851e443eee..54abeb142e119edd1c1d1c263821b95b1f05c388 100644
--- a/net/minecraft/world/level/block/EndGatewayBlock.java
+++ b/net/minecraft/world/level/block/EndGatewayBlock.java
@@ -98,6 +98,13 @@ public class EndGatewayBlock extends BaseEntityBlock implements Portal {
org.bukkit.event.entity.EntityPortalEnterEvent event = new org.bukkit.event.entity.EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(level.getWorld(), pos.getX(), pos.getY(), pos.getZ()), org.bukkit.PortalType.END_GATEWAY); // Paper - add portal type
if (!event.callEvent()) return;
// Paper end - call EntityPortalEnterEvent
+ // Purpur start - Add EntityTeleportHinderedEvent
+ if (level.purpurConfig.imposeTeleportRestrictionsOnGateways && (entity.isVehicle() || entity.isPassenger())) {
+ if (!new org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent(entity.getBukkitEntity(), entity.isPassenger() ? org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_PASSENGER : org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_VEHICLE, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_GATEWAY).callEvent()) {
+ return;
+ }
+ }
+ // Purpur end - Add EntityTeleportHinderedEvent
entity.setAsInsidePortal(this, pos);
TheEndGatewayBlockEntity.triggerCooldown(level, pos, state, theEndGatewayBlockEntity);
}
diff --git a/net/minecraft/world/level/block/EndPortalBlock.java b/net/minecraft/world/level/block/EndPortalBlock.java
index 01cddd7001b4a7f99c1b1d147fac904d3064d733..7e60bcadd2d343e00fc554dba0b85c9191f7efb6 100644
--- a/net/minecraft/world/level/block/EndPortalBlock.java
+++ b/net/minecraft/world/level/block/EndPortalBlock.java
@@ -58,6 +58,13 @@ public class EndPortalBlock extends BaseEntityBlock implements Portal {
protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) {
if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
if (entity.canUsePortal(false)) {
+ // Purpur start - Add EntityTeleportHinderedEvent
+ if (level.purpurConfig.imposeTeleportRestrictionsOnEndPortals && (entity.isVehicle() || entity.isPassenger())) {
+ if (!new org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent(entity.getBukkitEntity(), entity.isPassenger() ? org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_PASSENGER : org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_VEHICLE, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_PORTAL).callEvent()) {
+ return;
+ }
+ }
+ // Purpur end - Add EntityTeleportHinderedEvent
// CraftBukkit start - Entity in portal
org.bukkit.event.entity.EntityPortalEnterEvent event = new org.bukkit.event.entity.EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(level.getWorld(), pos.getX(), pos.getY(), pos.getZ()), org.bukkit.PortalType.ENDER); // Paper - add portal type
level.getCraftServer().getPluginManager().callEvent(event);
diff --git a/net/minecraft/world/level/block/NetherPortalBlock.java b/net/minecraft/world/level/block/NetherPortalBlock.java
index 006444811c00a8820bddaf75950e794271efdd82..eb659209008209c0930770e5f9671a3d7a4abae6 100644
--- a/net/minecraft/world/level/block/NetherPortalBlock.java
+++ b/net/minecraft/world/level/block/NetherPortalBlock.java
@@ -117,6 +117,13 @@ public class NetherPortalBlock extends Block implements Portal {
protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) {
if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
if (entity.canUsePortal(false)) {
+ // Purpur start - Add EntityTeleportHinderedEvent
+ if (level.purpurConfig.imposeTeleportRestrictionsOnNetherPortals && (entity.isVehicle() || entity.isPassenger())) {
+ if (!new org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent(entity.getBukkitEntity(), entity.isPassenger() ? org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_PASSENGER : org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_VEHICLE, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.NETHER_PORTAL).callEvent()) {
+ return;
+ }
+ }
+ // Purpur end - Add EntityTeleportHinderedEvent
// CraftBukkit start - Entity in portal
org.bukkit.event.entity.EntityPortalEnterEvent event = new org.bukkit.event.entity.EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(level.getWorld(), pos.getX(), pos.getY(), pos.getZ()), org.bukkit.PortalType.NETHER); // Paper - add portal type
level.getCraftServer().getPluginManager().callEvent(event);

View File

@@ -0,0 +1,344 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ben Kerllenevich <ben@omega24.dev>
Date: Tue, 25 May 2021 16:31:09 -0400
Subject: [PATCH] API for any mob to burn daylight
Co-authored by: Encode42 <me@encode42.dev>
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 62a38ecedbd579b32a8fd9cff5a433bfe635fc62..8473a7d9af9d83e97387ddf4cc50f6ad22730def 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -530,6 +530,24 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
// Purpur end - Add canSaveToDisk to Entity
+ // Purpur start - copied from Mob - API for any mob to burn daylight
+ public boolean isSunBurnTick() {
+ if (this.level().isDay() && !this.level().isClientSide) {
+ float lightLevelDependentMagicValue = this.getLightLevelDependentMagicValue();
+ BlockPos blockPos = BlockPos.containing(this.getX(), this.getEyeY(), this.getZ());
+ boolean flag = this.isInWaterRainOrBubble() || this.isInPowderSnow || this.wasInPowderSnow;
+ if (lightLevelDependentMagicValue > 0.5F
+ && this.random.nextFloat() * 30.0F < (lightLevelDependentMagicValue - 0.4F) * 2.0F
+ && !flag
+ && this.level().canSeeSky(blockPos)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ // Purpur end - copied from Mob - API for any mob to burn daylight
+
public Entity(EntityType<?> entityType, Level level) {
this.type = entityType;
this.level = level;
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
index 2dc588e2d503c16ccd2589ce18abd2ecebbc8e74..db5a2227009bc4d655fc781d5850221f36f2d112 100644
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -301,6 +301,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
public org.bukkit.craftbukkit.entity.CraftLivingEntity getBukkitLivingEntity() { return (org.bukkit.craftbukkit.entity.CraftLivingEntity) super.getBukkitEntity(); } // Paper
public boolean silentDeath = false; // Paper - mark entity as dying silently for cancellable death event
public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API
+ protected boolean shouldBurnInDay = false; public boolean shouldBurnInDay() { return this.shouldBurnInDay; } public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; } // Purpur - API for any mob to burn daylight
@Override
public float getBukkitYaw() {
@@ -809,6 +810,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
});
DataResult<Tag> dataResult = this.brain.serializeStart(NbtOps.INSTANCE);
dataResult.resultOrPartial(LOGGER::error).ifPresent(brain -> compound.put("Brain", brain));
+ compound.putBoolean("Purpur.ShouldBurnInDay", this.shouldBurnInDay); // Purpur - API for any mob to burn daylight
}
@Override
@@ -892,6 +894,12 @@ public abstract class LivingEntity extends Entity implements Attackable {
if (compound.contains("Brain", 10)) {
this.brain = this.makeBrain(new Dynamic<>(NbtOps.INSTANCE, compound.get("Brain")));
}
+
+ // Purpur start - API for any mob to burn daylight
+ if (compound.contains("Purpur.ShouldBurnInDay")) {
+ this.shouldBurnInDay = compound.getBoolean("Purpur.ShouldBurnInDay");
+ }
+ // Purpur end - API for any mob to burn daylight
}
// CraftBukkit start
@@ -3574,6 +3582,32 @@ public abstract class LivingEntity extends Entity implements Attackable {
if (this.level() instanceof ServerLevel serverLevel && this.isSensitiveToWater() && this.isInWaterRainOrBubble()) {
this.hurtServer(serverLevel, this.damageSources().drown(), 1.0F);
}
+
+ // Purpur start - copied from Zombie - API for any mob to burn daylight
+ if (this.isAlive()) {
+ boolean flag = this.shouldBurnInDay() && this.isSunBurnTick(); // Paper - shouldBurnInDay API // Purpur - use shouldBurnInDay() method to handle Phantoms properly - API for any mob to burn daylight
+ if (flag) {
+ ItemStack itemBySlot = this.getItemBySlot(EquipmentSlot.HEAD);
+ if (!itemBySlot.isEmpty()) {
+ if (itemBySlot.isDamageableItem()) {
+ Item item = itemBySlot.getItem();
+ itemBySlot.setDamageValue(itemBySlot.getDamageValue() + this.random.nextInt(2));
+ if (itemBySlot.getDamageValue() >= itemBySlot.getMaxDamage()) {
+ this.onEquippedItemBroken(item, EquipmentSlot.HEAD);
+ this.setItemSlot(EquipmentSlot.HEAD, ItemStack.EMPTY);
+ }
+ }
+
+ flag = false;
+ }
+
+ if (flag) {
+ if (getRider() == null || !this.isControllable()) // Purpur - ignore mobs which are uncontrollable or without rider - API for any mob to burn daylight
+ this.igniteForSeconds(8.0F);
+ }
+ }
+ }
+ // Purpur end - copied from Zombie - API for any mob to burn daylight
}
public boolean isSensitiveToWater() {
diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java
index d93584c6793818463e8883ffe399bf16b03263a9..70ee86993d381445855ac7e7290da384d6675987 100644
--- a/net/minecraft/world/entity/Mob.java
+++ b/net/minecraft/world/entity/Mob.java
@@ -1655,19 +1655,8 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
}
public boolean isSunBurnTick() {
- if (this.level().isDay() && !this.level().isClientSide) {
- float lightLevelDependentMagicValue = this.getLightLevelDependentMagicValue();
- BlockPos blockPos = BlockPos.containing(this.getX(), this.getEyeY(), this.getZ());
- boolean flag = this.isInWaterRainOrBubble() || this.isInPowderSnow || this.wasInPowderSnow;
- if (lightLevelDependentMagicValue > 0.5F
- && this.random.nextFloat() * 30.0F < (lightLevelDependentMagicValue - 0.4F) * 2.0F
- && !flag
- && this.level().canSeeSky(blockPos)) {
- return true;
- }
- }
-
- return false;
+ // Purpur - implemented in Entity - API for any mob to burn daylight
+ return super.isSunBurnTick();
}
@Override
diff --git a/net/minecraft/world/entity/monster/AbstractSkeleton.java b/net/minecraft/world/entity/monster/AbstractSkeleton.java
index e186aee80b052b7fc4bfe02763010bfb2d55ea35..223739818e9ac6c9fe396b82bce53a3ab029610a 100644
--- a/net/minecraft/world/entity/monster/AbstractSkeleton.java
+++ b/net/minecraft/world/entity/monster/AbstractSkeleton.java
@@ -64,11 +64,12 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
AbstractSkeleton.this.setAggressive(true);
}
};
- private boolean shouldBurnInDay = true; // Paper - shouldBurnInDay API
+ //private boolean shouldBurnInDay = true; // Paper - shouldBurnInDay API // Purpur - moved to LivingEntity; keep methods for ABI compatibility - API for any mob to burn daylight
protected AbstractSkeleton(EntityType<? extends AbstractSkeleton> entityType, Level level) {
super(entityType, level);
this.reassessWeaponGoal();
+ this.setShouldBurnInDay(true); // Purpur - API for any mob to burn daylight
}
@Override
@@ -110,27 +111,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
@Override
public void aiStep() {
- boolean isSunBurnTick = this.shouldBurnInDay && this.isSunBurnTick(); // Paper - shouldBurnInDay API
- if (isSunBurnTick) {
- ItemStack itemBySlot = this.getItemBySlot(EquipmentSlot.HEAD);
- if (!itemBySlot.isEmpty()) {
- if (itemBySlot.isDamageableItem()) {
- Item item = itemBySlot.getItem();
- itemBySlot.setDamageValue(itemBySlot.getDamageValue() + this.random.nextInt(2));
- if (itemBySlot.getDamageValue() >= itemBySlot.getMaxDamage()) {
- this.onEquippedItemBroken(item, EquipmentSlot.HEAD);
- this.setItemSlot(EquipmentSlot.HEAD, ItemStack.EMPTY);
- }
- }
-
- isSunBurnTick = false;
- }
-
- if (isSunBurnTick) {
- this.igniteForSeconds(8.0F);
- }
- }
-
+ // Purpur - implemented in LivingEntity - API for any mob to burn daylight
super.aiStep();
}
@@ -243,7 +224,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
super.readAdditionalSaveData(compound);
this.reassessWeaponGoal();
// Paper start - shouldBurnInDay API
- if (compound.contains("Paper.ShouldBurnInDay")) {
+ if (false && compound.contains("Paper.ShouldBurnInDay")) { // Purpur - implemented in LivingEntity - API for any mob to burn daylight
this.shouldBurnInDay = compound.getBoolean("Paper.ShouldBurnInDay");
}
// Paper end - shouldBurnInDay API
@@ -252,7 +233,7 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
@Override
public void addAdditionalSaveData(final net.minecraft.nbt.CompoundTag nbt) {
super.addAdditionalSaveData(nbt);
- nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay);
+ //nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Purpur - implemented in LivingEntity - API for any mob to burn daylight
}
// Paper end - shouldBurnInDay API
diff --git a/net/minecraft/world/entity/monster/Husk.java b/net/minecraft/world/entity/monster/Husk.java
index 31eef2869945d9de565d627cac3fc1a5db380a2a..e618e716cb5ff3a3c5d284e985455694cc0edde0 100644
--- a/net/minecraft/world/entity/monster/Husk.java
+++ b/net/minecraft/world/entity/monster/Husk.java
@@ -19,6 +19,7 @@ import net.minecraft.world.level.ServerLevelAccessor;
public class Husk extends Zombie {
public Husk(EntityType<? extends Husk> entityType, Level level) {
super(entityType, level);
+ this.setShouldBurnInDay(false); // Purpur - API for any mob to burn daylight
}
// Purpur start - Ridables
@@ -82,7 +83,7 @@ public class Husk extends Zombie {
@Override
public boolean isSunSensitive() {
- return false;
+ return this.shouldBurnInDay; // Purpur - moved to LivingEntity; keep methods for ABI compatibility - API for any mob to burn daylight
}
@Override
diff --git a/net/minecraft/world/entity/monster/Phantom.java b/net/minecraft/world/entity/monster/Phantom.java
index 32b7c34d3c68dcfa936b628b2d038524204129a3..0ee817699fffbb929011465029182cc56befc30c 100644
--- a/net/minecraft/world/entity/monster/Phantom.java
+++ b/net/minecraft/world/entity/monster/Phantom.java
@@ -60,6 +60,7 @@ public class Phantom extends FlyingMob implements Enemy {
this.xpReward = 5;
this.moveControl = new Phantom.PhantomMoveControl(this);
this.lookControl = new Phantom.PhantomLookControl(this);
+ this.setShouldBurnInDay(true); // Purpur - API for any mob to burn daylight
}
// Purpur start - Ridables
@@ -146,6 +147,16 @@ public class Phantom extends FlyingMob implements Enemy {
}
// Purpur end - Toggle for water sensitive mob damage
+ //private boolean shouldBurnInDay = true; // Purpur - moved to LivingEntity; keep methods for ABI compatibility - API for any mob to burn daylight
+ // Purpur start - API for any mob to burn daylight
+ public boolean shouldBurnInDay() {
+ boolean burnFromDaylight = this.shouldBurnInDay && this.level().purpurConfig.phantomBurnInDaylight;
+ boolean burnFromLightSource = this.level().purpurConfig.phantomBurnInLight > 0 && this.level().getMaxLocalRawBrightness(blockPosition()) >= this.level().purpurConfig.phantomBurnInLight;
+ return burnFromDaylight || burnFromLightSource;
+ }
+ public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; }
+ // Purpur end - API for any mob to burn daylight
+
@Override
public boolean isFlapping() {
return (this.getUniqueFlapTickOffset() + this.tickCount) % TICKS_PER_FLAP == 0;
@@ -261,6 +272,7 @@ public class Phantom extends FlyingMob implements Enemy {
@Override
public void aiStep() {
+ // Purpur - implemented in LivingEntity; moved down to shouldBurnInDay() - API for any mob to burn daylight
// Purpur start - Phantoms burn in light
boolean burnFromDaylight = this.shouldBurnInDay && this.isSunBurnTick() && this.level().purpurConfig.phantomBurnInDaylight;
boolean burnFromLightSource = this.level().purpurConfig.phantomBurnInLight > 0 && this.level().getMaxLocalRawBrightness(blockPosition()) >= this.level().purpurConfig.phantomBurnInLight;
@@ -299,7 +311,7 @@ public class Phantom extends FlyingMob implements Enemy {
if (compound.hasUUID("Paper.SpawningEntity")) {
this.spawningEntity = compound.getUUID("Paper.SpawningEntity");
}
- if (compound.contains("Paper.ShouldBurnInDay")) {
+ if (false && compound.contains("Paper.ShouldBurnInDay")) { // Purpur - implemented in LivingEntity - API for any mob to burn daylight
this.shouldBurnInDay = compound.getBoolean("Paper.ShouldBurnInDay");
}
// Paper end
@@ -316,7 +328,7 @@ public class Phantom extends FlyingMob implements Enemy {
if (this.spawningEntity != null) {
compound.putUUID("Paper.SpawningEntity", this.spawningEntity);
}
- compound.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay);
+ //compound.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Purpur - implemented in LivingEntity - API for any mob to burn daylight
// Paper end
}
diff --git a/net/minecraft/world/entity/monster/Zombie.java b/net/minecraft/world/entity/monster/Zombie.java
index bb8c37c8348172947efe14d48ed9ae203409affa..b1da45df27f02395d793e7eafe576f5f92aa3a7b 100644
--- a/net/minecraft/world/entity/monster/Zombie.java
+++ b/net/minecraft/world/entity/monster/Zombie.java
@@ -89,11 +89,12 @@ public class Zombie extends Monster {
private boolean canBreakDoors;
private int inWaterTime;
public int conversionTime;
- private boolean shouldBurnInDay = true; // Paper - Add more Zombie API
+ //private boolean shouldBurnInDay = true; // Paper - Add more Zombie API // Purpur - implemented in LivingEntity - API for any mob to burn daylight
public Zombie(EntityType<? extends Zombie> entityType, Level level) {
super(entityType, level);
this.breakDoorGoal = new BreakDoorGoal(this, com.google.common.base.Predicates.in(level.paperConfig().entities.behavior.doorBreakingDifficulty.getOrDefault(entityType, level.paperConfig().entities.behavior.doorBreakingDifficulty.get(EntityType.ZOMBIE)))); // Paper - Configurable door breaking difficulty
+ this.setShouldBurnInDay(true); // Purpur - API for any mob to burn daylight
}
public Zombie(Level level) {
@@ -290,29 +291,7 @@ public class Zombie extends Monster {
@Override
public void aiStep() {
- if (this.isAlive()) {
- boolean flag = this.isSunSensitive() && this.isSunBurnTick();
- if (flag) {
- ItemStack itemBySlot = this.getItemBySlot(EquipmentSlot.HEAD);
- if (!itemBySlot.isEmpty()) {
- if (itemBySlot.isDamageableItem()) {
- Item item = itemBySlot.getItem();
- itemBySlot.setDamageValue(itemBySlot.getDamageValue() + this.random.nextInt(2));
- if (itemBySlot.getDamageValue() >= itemBySlot.getMaxDamage()) {
- this.onEquippedItemBroken(item, EquipmentSlot.HEAD);
- this.setItemSlot(EquipmentSlot.HEAD, ItemStack.EMPTY);
- }
- }
-
- flag = false;
- }
-
- if (flag) {
- this.igniteForSeconds(8.0F);
- }
- }
- }
-
+ // Purpur - implemented in LivingEntity - API for any mob to burn daylight
super.aiStep();
}
@@ -371,6 +350,7 @@ public class Zombie extends Monster {
// CraftBukkit end
}
+ public boolean shouldBurnInDay() { return this.isSunSensitive(); } // Purpur - for ABI compatibility - API for any mob to burn daylight
public boolean isSunSensitive() {
return this.shouldBurnInDay; // Paper - Add more Zombie API
}
@@ -509,7 +489,7 @@ public class Zombie extends Monster {
compound.putBoolean("CanBreakDoors", this.canBreakDoors());
compound.putInt("InWaterTime", this.isInWater() ? this.inWaterTime : -1);
compound.putInt("DrownedConversionTime", this.isUnderWaterConverting() ? this.conversionTime : -1);
- compound.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API
+ //compound.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API // Purpur - implemented in LivingEntity - API for any mob to burn daylight
}
@Override
@@ -522,7 +502,7 @@ public class Zombie extends Monster {
this.startUnderWaterConversion(compound.getInt("DrownedConversionTime"));
}
// Paper start - Add more Zombie API
- if (compound.contains("Paper.ShouldBurnInDay")) {
+ if (false && compound.contains("Paper.ShouldBurnInDay")) { // Purpur - implemented in LivingEntity - API for any mob to burn daylight
this.shouldBurnInDay = compound.getBoolean("Paper.ShouldBurnInDay");
}
// Paper end - Add more Zombie API

View File

@@ -0,0 +1,64 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Mon, 30 Aug 2021 22:49:53 -0500
Subject: [PATCH] Cows naturally aggressive to players chance
diff --git a/net/minecraft/world/entity/animal/Cow.java b/net/minecraft/world/entity/animal/Cow.java
index a8c76fcbbaa4afd2d0bd568874995b91d8d67c03..b62c4449047da36d8b4d4b87d03c77906d12dc31 100644
--- a/net/minecraft/world/entity/animal/Cow.java
+++ b/net/minecraft/world/entity/animal/Cow.java
@@ -32,6 +32,8 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
public class Cow extends Animal {
+ private boolean isNaturallyAggressiveToPlayers; // Purpur - Cows naturally aggressive to players chance
+
private static final EntityDimensions BABY_DIMENSIONS = EntityType.COW.getDimensions().scale(0.5F).withEyeHeight(0.665F);
public Cow(EntityType<? extends Cow> entityType, Level level) {
@@ -60,6 +62,7 @@ public class Cow extends Animal {
public void initAttributes() {
this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(this.level().purpurConfig.cowMaxHealth);
this.getAttribute(Attributes.SCALE).setBaseValue(this.level().purpurConfig.cowScale);
+ this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(this.level().purpurConfig.cowNaturallyAggressiveToPlayersDamage); // Purpur - Cows naturally aggressive to players chance
}
// Purpur end - Configurable entity base attributes
@@ -77,17 +80,27 @@ public class Cow extends Animal {
}
// Purpur end - Toggle for water sensitive mob damage
+ // Purpur start - Cows naturally aggressive to players chance
+ @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.SpawnGroupData entityData) {
+ this.isNaturallyAggressiveToPlayers = world.getLevel().purpurConfig.cowNaturallyAggressiveToPlayersChance > 0.0D && random.nextDouble() <= world.getLevel().purpurConfig.cowNaturallyAggressiveToPlayersChance;
+ return super.finalizeSpawn(world, difficulty, spawnReason, entityData);
+ }
+ // Purpur end - Cows naturally aggressive to players chance
+
@Override
protected void registerGoals() {
this.goalSelector.addGoal(0, new FloatGoal(this));
this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
this.goalSelector.addGoal(1, new PanicGoal(this, 2.0));
+ this.goalSelector.addGoal(1, new net.minecraft.world.entity.ai.goal.MeleeAttackGoal(this, 1.2000000476837158D, true)); // Purpur - Cows naturally aggressive to players chance
this.goalSelector.addGoal(2, new BreedGoal(this, 1.0));
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));
this.goalSelector.addGoal(7, new RandomLookAroundGoal(this));
+ this.targetSelector.addGoal(0, new net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (ignored, ignored2) -> isNaturallyAggressiveToPlayers)); // Purpur - Cows naturally aggressive to players chance
}
@Override
@@ -96,7 +109,7 @@ public class Cow extends Animal {
}
public static AttributeSupplier.Builder createAttributes() {
- return Animal.createAnimalAttributes().add(Attributes.MAX_HEALTH, 10.0).add(Attributes.MOVEMENT_SPEED, 0.2F);
+ return Animal.createAnimalAttributes().add(Attributes.MAX_HEALTH, 10.0).add(Attributes.MOVEMENT_SPEED, 0.2F).add(Attributes.ATTACK_DAMAGE, 0.0D); // Purpur - Cows naturally aggressive to players chance
}
@Override

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,184 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: granny <granny@purpurmc.org>
Date: Mon, 16 Oct 2023 21:54:47 -0700
Subject: [PATCH] config for turning bundles into functional quivers
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
index db5a2227009bc4d655fc781d5850221f36f2d112..c26846d3b92be4ed8ec40ce21128dfe912f19298 100644
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -4456,6 +4456,11 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
public ItemStack getProjectile(ItemStack weaponStack) {
+ // Purpur start - config for turning bundles into functional quivers
+ return getProjectile(weaponStack, false);
+ }
+ public ItemStack getProjectile(ItemStack weaponStack, boolean useBundleItemStack) {
+ // Purpur end - config for turning bundles into functional quivers
return ItemStack.EMPTY;
}
diff --git a/net/minecraft/world/entity/monster/Monster.java b/net/minecraft/world/entity/monster/Monster.java
index c1ebb74b0d4a8e2eb8880ccaf20f0f9bc1940094..4d0916c0ec6c199f9ef359a17cda0891448d07f6 100644
--- a/net/minecraft/world/entity/monster/Monster.java
+++ b/net/minecraft/world/entity/monster/Monster.java
@@ -144,6 +144,12 @@ public abstract class Monster extends PathfinderMob implements Enemy {
@Override
public ItemStack getProjectile(ItemStack shootable) {
+ // Purpur start - config for turning bundles into functional quivers
+ return getProjectile(shootable, false);
+ }
+ @Override
+ public ItemStack getProjectile(ItemStack shootable, boolean useBundleItemStack) {
+ // Purpur end - config for turning bundles into functional quivers
if (shootable.getItem() instanceof ProjectileWeaponItem) {
Predicate<ItemStack> supportedHeldProjectiles = ((ProjectileWeaponItem)shootable.getItem()).getSupportedHeldProjectiles();
ItemStack heldProjectile = ProjectileWeaponItem.getHeldProjectile(this, supportedHeldProjectiles);
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
index 43657822f0660613078e9afa512000b5255a1537..2363ec5b718b50cb178f231e544b89c00af79796 100644
--- a/net/minecraft/world/entity/player/Player.java
+++ b/net/minecraft/world/entity/player/Player.java
@@ -2294,6 +2294,12 @@ public abstract class Player extends LivingEntity {
@Override
public ItemStack getProjectile(ItemStack shootable) {
+ // Purpur start - config for turning bundles into functional quivers
+ return getProjectile(shootable, false);
+ }
+ @Override
+ public ItemStack getProjectile(ItemStack shootable, boolean useBundleItemStack) {
+ // Purpur end - config for turning bundles into functional quivers
if (!(shootable.getItem() instanceof ProjectileWeaponItem)) {
return ItemStack.EMPTY;
} else {
@@ -2306,6 +2312,39 @@ public abstract class Player extends LivingEntity {
for (int i = 0; i < this.inventory.getContainerSize(); i++) {
ItemStack item = this.inventory.getItem(i);
+
+ // Purpur start - config for turning bundles into functional quivers
+ if ((this.level().purpurConfig.bowUseBundleAsQuiver || this.level().purpurConfig.crossbowUseBundleAsQuiver) && item.getItem() instanceof net.minecraft.world.item.BundleItem) {
+ net.minecraft.world.item.component.BundleContents bundleContents = item.get(net.minecraft.core.component.DataComponents.BUNDLE_CONTENTS);
+ if (bundleContents == null || bundleContents.isEmpty()) {
+ continue;
+ }
+
+ Optional<ItemStack> first = bundleContents.itemCopyStream().filter(supportedHeldProjectiles).findFirst();
+
+ if (first.isEmpty()) {
+ continue;
+ }
+
+ ItemStack itemStack = first.get();
+ if (useBundleItemStack) {
+ net.minecraft.world.item.component.BundleContents.Mutable mutable = new net.minecraft.world.item.component.BundleContents.Mutable(bundleContents);
+ ItemStack itemStack2 = mutable.removeOne(itemStack);
+ if (itemStack2 == null) {
+ continue;
+ }
+
+ itemStack2.shrink(1);
+ if (itemStack2.getCount() != 0) {
+ mutable.tryInsert(itemStack2);
+ }
+ item.set(net.minecraft.core.component.DataComponents.BUNDLE_CONTENTS, mutable.toImmutable());
+ }
+ itemStack.setCount(1);
+ return itemStack;
+ }
+ // Purpur end - config for turning bundles into functional quivers
+
if (supportedHeldProjectiles.test(item)) {
return item;
}
diff --git a/net/minecraft/world/item/BowItem.java b/net/minecraft/world/item/BowItem.java
index b3e003694ce0da357e91ab3ce2b1380f9ab0a32a..186bd391ed3738734ca2d8e82339af0158ae4875 100644
--- a/net/minecraft/world/item/BowItem.java
+++ b/net/minecraft/world/item/BowItem.java
@@ -27,7 +27,7 @@ public class BowItem extends ProjectileWeaponItem {
if (!(entity instanceof Player player)) {
return false;
} else {
- ItemStack projectile = player.getProjectile(stack);
+ ItemStack projectile = player.getProjectile(stack, true); // Purpur - config for turning bundles into functional quivers
// Purpur start - Infinity bow settings
if (level.purpurConfig.infinityWorksWithoutArrows && projectile.isEmpty() && net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.INFINITY, stack) > 0) {
projectile = new ItemStack(Items.ARROW);
diff --git a/net/minecraft/world/item/BundleItem.java b/net/minecraft/world/item/BundleItem.java
index 966029b761bcb31113b167831fe7f4f2dea4b17d..eda25cc71b4804d805b1a7f875f823b20efc754b 100644
--- a/net/minecraft/world/item/BundleItem.java
+++ b/net/minecraft/world/item/BundleItem.java
@@ -131,7 +131,7 @@ public class BundleItem extends Item {
}
private void dropContent(Level level, Player player, ItemStack stack) {
- if (this.dropContent(stack, player)) {
+ if (!(level.purpurConfig.bowUseBundleAsQuiver || level.purpurConfig.bowUseBundleAsQuiver) && this.dropContent(stack, player)) { // Purpur - config for turning bundles into functional quivers
playDropContentsSound(level, player);
player.awardStat(Stats.ITEM_USED.get(this));
}
diff --git a/net/minecraft/world/item/CrossbowItem.java b/net/minecraft/world/item/CrossbowItem.java
index 1131e984fd30e40c1b99054b5db9462ffe55b5f1..c9dbe63316cad0437f50fa3f7ffe345ec1906752 100644
--- a/net/minecraft/world/item/CrossbowItem.java
+++ b/net/minecraft/world/item/CrossbowItem.java
@@ -72,7 +72,7 @@ public class CrossbowItem extends ProjectileWeaponItem {
if (chargedProjectiles != null && !chargedProjectiles.isEmpty()) {
this.performShooting(level, player, hand, itemInHand, getShootingPower(chargedProjectiles), (float) level.purpurConfig.crossbowProjectileOffset, null); // Purpur - Projectile offset config
return InteractionResult.CONSUME;
- } else if (!player.getProjectile(itemInHand).isEmpty()) {
+ } else if (!player.getProjectile(itemInHand).isEmpty()) { // Purpur - config for turning bundles into functional quivers
this.startSoundPlayed = false;
this.midLoadSoundPlayed = false;
player.startUsingItem(hand);
@@ -124,7 +124,7 @@ public class CrossbowItem extends ProjectileWeaponItem {
return CrossbowItem.tryLoadProjectiles(shooter, crossbowStack, true);
}
private static boolean tryLoadProjectiles(LivingEntity shooter, ItemStack crossbowStack, boolean consume) {
- List<ItemStack> list = draw(crossbowStack, shooter.getProjectile(crossbowStack), shooter, consume);
+ List<ItemStack> list = draw(crossbowStack, shooter.getProjectile(crossbowStack, true), shooter, consume); // Purpur - config for turning bundles into functional quivers
// Paper end - Add EntityLoadCrossbowEvent
if (!list.isEmpty()) {
crossbowStack.set(DataComponents.CHARGED_PROJECTILES, ChargedProjectiles.of(list));
diff --git a/net/minecraft/world/item/component/BundleContents.java b/net/minecraft/world/item/component/BundleContents.java
index fca2dd0fb9ff4ff795a01de722fbb31dc02682fa..6fb9becef49bd4161c7829d240dd9e786f2226b5 100644
--- a/net/minecraft/world/item/component/BundleContents.java
+++ b/net/minecraft/world/item/component/BundleContents.java
@@ -163,7 +163,12 @@ public final class BundleContents implements TooltipComponent {
}
private int findStackIndex(ItemStack stack) {
- if (!stack.isStackable()) {
+ // Purpur start - config for turning bundles into functional quivers
+ return this.findStackIndex(stack, false);
+ }
+ private int findStackIndex(ItemStack stack, boolean skipStackableCheck) {
+ if (!skipStackableCheck && !stack.isStackable()) {
+ // Purpur end - config for turning bundles into functional quivers
return -1;
} else {
for (int i = 0; i < this.items.size(); i++) {
@@ -223,11 +228,20 @@ public final class BundleContents implements TooltipComponent {
@Nullable
public ItemStack removeOne() {
+ // Purpur start - config for turning bundles into functional quivers
+ return this.removeOne(null);
+ }
+ @Nullable
+ public ItemStack removeOne(ItemStack itemStack2) {
+ // Purpur end - config for turning bundles into functional quivers
if (this.items.isEmpty()) {
return null;
} else {
int i = this.selectedItem != -1 && this.selectedItem < this.items.size() ? this.selectedItem : 0;
- ItemStack itemStack = this.items.remove(i).copy();
+ // Purpur start - config for turning bundles into functional quivers
+ int stackIndex = itemStack2 != null ? this.findStackIndex(itemStack2, true) : -1;
+ ItemStack itemStack = this.items.remove(stackIndex == -1 ? i : stackIndex).copy();
+ // Purpur end - config for turning bundles into functional quivers
this.weight = this.weight.subtract(BundleContents.getWeight(itemStack).multiplyBy(Fraction.getFraction(itemStack.getCount(), 1)));
this.toggleSelectedItem(-1);
return itemStack;