150 patches...

This commit is contained in:
granny
2024-10-25 22:58:50 -07:00
parent b14424ee72
commit a2899425e7
51 changed files with 955 additions and 958 deletions

View File

@@ -1,34 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Tue, 17 Nov 2020 13:12:09 -0800
Subject: [PATCH] Set name visible when using a Name Tag on an Armor Stand
diff --git a/src/main/java/net/minecraft/world/item/NameTagItem.java b/src/main/java/net/minecraft/world/item/NameTagItem.java
index 774c982f28b4f127fc3f036c19dfb47fb9ae3264..d49b60e7e643498b49c03593dc0da2f8e4459902 100644
--- a/src/main/java/net/minecraft/world/item/NameTagItem.java
+++ b/src/main/java/net/minecraft/world/item/NameTagItem.java
@@ -23,6 +23,7 @@ public class NameTagItem extends Item {
if (!event.callEvent()) return InteractionResult.PASS;
LivingEntity newEntity = ((org.bukkit.craftbukkit.entity.CraftLivingEntity) event.getEntity()).getHandle();
newEntity.setCustomName(event.getName() != null ? io.papermc.paper.adventure.PaperAdventure.asVanilla(event.getName()) : null);
+ if (user.level().purpurConfig.armorstandFixNametags && entity instanceof net.minecraft.world.entity.decoration.ArmorStand) entity.setCustomNameVisible(true); // Purpur
if (event.isPersistent() && newEntity instanceof Mob mob) {
// Paper end - Add PlayerNameEntityEvent
mob.setPersistenceRequired();
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index cc95e8ba5d847348afdd4263c9e84554cb2ec713..4294b5bbf24f63023dd3c63614de7d7a14c50857 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -99,9 +99,11 @@ public class PurpurWorldConfig {
public float armorstandStepHeight = 0.0F;
public boolean armorstandSetNameVisible = false;
+ public boolean armorstandFixNametags = false;
private void armorstandSettings() {
armorstandStepHeight = (float) getDouble("gameplay-mechanics.armorstand.step-height", armorstandStepHeight);
armorstandSetNameVisible = getBoolean("gameplay-mechanics.armorstand.set-name-visible-when-placing-with-custom-name", armorstandSetNameVisible);
+ armorstandFixNametags = getBoolean("gameplay-mechanics.armorstand.fix-nametags", armorstandFixNametags);
}
public boolean arrowMovementResetsDespawnCounter = true;

View File

@@ -1,42 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Sun, 22 Nov 2020 22:17:53 -0800
Subject: [PATCH] Add config for allowing Endermen to despawn even while
holding a block
This should help to reduce the amount of dirt, gravel, grass, and etc.
that Endermen like to randomly place all over the world.
diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
index b081ea3f272ec2dba426bf0ebdfbbba1cec718ee..3348b5a9e4e00ef7f4dabe10d0fe0a9c0456dbd7 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
@@ -487,7 +487,7 @@ public class EnderMan extends Monster implements NeutralMob {
@Override
public boolean requiresCustomPersistence() {
- return super.requiresCustomPersistence() || this.getCarriedBlock() != null;
+ return super.requiresCustomPersistence() || (!this.level().purpurConfig.endermanDespawnEvenWithBlock && this.getCarriedBlock() != null); // Purpur
}
private static class EndermanFreezeWhenLookedAt extends Goal {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 4294b5bbf24f63023dd3c63614de7d7a14c50857..35457d2d53d7497ab8e370b0059a67b8563e1eff 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -848,6 +848,7 @@ public class PurpurWorldConfig {
public double endermanMaxHealth = 40.0D;
public double endermanScale = 1.0D;
public boolean endermanAllowGriefing = true;
+ public boolean endermanDespawnEvenWithBlock = false;
private void endermanSettings() {
endermanRidable = getBoolean("mobs.enderman.ridable", endermanRidable);
endermanRidableInWater = getBoolean("mobs.enderman.ridable-in-water", endermanRidableInWater);
@@ -860,6 +861,7 @@ public class PurpurWorldConfig {
endermanMaxHealth = getDouble("mobs.enderman.attributes.max_health", endermanMaxHealth);
endermanScale = Mth.clamp(getDouble("mobs.enderman.attributes.scale", endermanScale), 0.0625D, 16.0D);
endermanAllowGriefing = getBoolean("mobs.enderman.allow-griefing", endermanAllowGriefing);
+ endermanDespawnEvenWithBlock = getBoolean("mobs.enderman.can-despawn-with-held-block", endermanDespawnEvenWithBlock);
}
public boolean endermiteRidable = false;

View File

@@ -1,35 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Tue, 24 Nov 2020 05:32:02 -0600
Subject: [PATCH] Add configurable snowball damage
diff --git a/src/main/java/net/minecraft/world/entity/projectile/Snowball.java b/src/main/java/net/minecraft/world/entity/projectile/Snowball.java
index 2b4d206c0d31ba38d7b2af654bd420e85145d441..f59a2903bfb8ae591a638ea5bb387caaa93ce664 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/Snowball.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/Snowball.java
@@ -58,7 +58,7 @@ public class Snowball extends ThrowableItemProjectile {
protected void onHitEntity(EntityHitResult entityHitResult) {
super.onHitEntity(entityHitResult);
Entity entity = entityHitResult.getEntity();
- int i = entity instanceof Blaze ? 3 : 0;
+ int i = entity.level().purpurConfig.snowballDamage >= 0 ? entity.level().purpurConfig.snowballDamage : entity instanceof Blaze ? 3 : 0; // Purpur
entity.hurt(this.damageSources().thrown(this, this.getOwner()), (float) i);
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 35457d2d53d7497ab8e370b0059a67b8563e1eff..e1efcfcddacf41e516dd297b99183fe8f8aabddc 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -338,6 +338,11 @@ public class PurpurWorldConfig {
});
}
+ public int snowballDamage = -1;
+ private void snowballSettings() {
+ snowballDamage = getInt("gameplay-mechanics.projectile-damage.snowball", snowballDamage);
+ }
+
public boolean anvilAllowColors = false;
public boolean anvilColorsUseMiniMessage;
private void anvilSettings() {

View File

@@ -1,34 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ben Kerllenevich <ben@omega24.dev>
Date: Mon, 30 Nov 2020 11:40:11 -0500
Subject: [PATCH] Changeable Mob Left Handed Chance
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
index 0d93a8cbf15fa84f422d61adddb420ba5dcb226a..d9743c9e0026d1f858aacc6a78dc39f144360b96 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
@@ -1441,7 +1441,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
attributemodifiable.addPermanentModifier(new AttributeModifier(Mob.RANDOM_SPAWN_BONUS_ID, randomsource.triangle(0.0D, 0.11485000000000001D), AttributeModifier.Operation.ADD_MULTIPLIED_BASE));
}
- this.setLeftHanded(randomsource.nextFloat() < 0.05F);
+ this.setLeftHanded(randomsource.nextFloat() < world.getLevel().purpurConfig.entityLeftHandedChance); // Purpur
return entityData;
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index e1efcfcddacf41e516dd297b99183fe8f8aabddc..fc218492aeca22efd869433b145699bf31e95aca 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -151,8 +151,10 @@ public class PurpurWorldConfig {
}
public int entityLifeSpan = 0;
+ public float entityLeftHandedChance = 0.05f;
private void entitySettings() {
entityLifeSpan = getInt("gameplay-mechanics.entity-lifespan", entityLifeSpan);
+ entityLeftHandedChance = (float) getDouble("gameplay-mechanics.entity-left-handed-chance", entityLeftHandedChance);
}
public boolean infinityWorksWithoutArrows = false;

View File

@@ -1,48 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Mon, 30 Nov 2020 19:36:35 -0600
Subject: [PATCH] Add boat fall damage config
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index aca60e21e7a191212d07a03a105fc4fb636359b2..0b57d9a2e2573bdb41c9e163d953130c3a4a1747 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -1182,7 +1182,16 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
if (this.isInvulnerableTo(source)) {
return false;
} else {
- if (source.is(DamageTypeTags.IS_FALL) && getRootVehicle() instanceof net.minecraft.world.entity.vehicle.AbstractMinecart && level().purpurConfig.minecartControllable && !level().purpurConfig.minecartControllableFallDamage) return false; // Purpur
+ // Purpur start
+ if (source.is(DamageTypeTags.IS_FALL)) { // Purpur
+ if (getRootVehicle() instanceof net.minecraft.world.entity.vehicle.AbstractMinecart && level().purpurConfig.minecartControllable && !level().purpurConfig.minecartControllableFallDamage) {
+ return false;
+ }
+ if (getRootVehicle() instanceof net.minecraft.world.entity.vehicle.Boat && !level().purpurConfig.boatsDoFallDamage) {
+ return false;
+ }
+ }
+ // Purpur end
boolean flag = this.server.isDedicatedServer() && this.isPvpAllowed() && source.is(DamageTypeTags.IS_FALL);
if (!flag && this.spawnInvulnerableTime > 0 && !source.is(DamageTypeTags.BYPASSES_INVULNERABILITY)) {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index fc218492aeca22efd869433b145699bf31e95aca..17df2ad9ec746736ca2968caa66a0bb1ff5a1151 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -113,6 +113,7 @@ public class PurpurWorldConfig {
public boolean useBetterMending = false;
public boolean boatEjectPlayersOnLand = false;
+ public boolean boatsDoFallDamage = false;
public boolean disableDropsOnCrammingDeath = false;
public boolean entitiesCanUsePortals = true;
public boolean milkCuresBadOmen = true;
@@ -123,6 +124,7 @@ public class PurpurWorldConfig {
private void miscGameplayMechanicsSettings() {
useBetterMending = getBoolean("gameplay-mechanics.use-better-mending", useBetterMending);
boatEjectPlayersOnLand = getBoolean("gameplay-mechanics.boat.eject-players-on-land", boatEjectPlayersOnLand);
+ boatsDoFallDamage = getBoolean("gameplay-mechanics.boat.do-fall-damage", boatsDoFallDamage);
disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath);
entitiesCanUsePortals = getBoolean("gameplay-mechanics.entities-can-use-portals", entitiesCanUsePortals);
milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen);

View File

@@ -1,50 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Simon Gardling <titaniumtown@gmail.com>
Date: Tue, 1 Dec 2020 16:50:36 -0500
Subject: [PATCH] Snow Golem rate of fire config
The formula used to determine the amount of ticks between shots is:
((sqrt(distanceToTarget) / snowGolemAttackDistance) / snowGolemSnowBallModifer) * (maxShootIntervalTicks - minShootIntervalTicks) + minShootIntervalTicks
If min-shoot-interval-ticks and max-shoot-interval-ticks are both set to
0, snow golems won't shoot any snowballs.
diff --git a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
index dc5af0b71ec82a8f22e64b03950e35845110a331..5b910b4168b7f7825916c14e402f7f00b651cd60 100644
--- a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
+++ b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
@@ -78,7 +78,7 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
@Override
protected void registerGoals() {
this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur
- this.goalSelector.addGoal(1, new RangedAttackGoal(this, 1.25D, 20, 10.0F));
+ this.goalSelector.addGoal(1, new RangedAttackGoal(this, level().purpurConfig.snowGolemAttackDistance, level().purpurConfig.snowGolemSnowBallMin, level().purpurConfig.snowGolemSnowBallMax, level().purpurConfig.snowGolemSnowBallModifier)); // Purpur
this.goalSelector.addGoal(2, new WaterAvoidingRandomStrollGoal(this, 1.0D, 1.0000001E-5F));
this.goalSelector.addGoal(3, new LookAtPlayerGoal(this, Player.class, 6.0F));
this.goalSelector.addGoal(4, new RandomLookAroundGoal(this));
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 17df2ad9ec746736ca2968caa66a0bb1ff5a1151..7cb8996240fe658fe5858f009fb1b8171c6de7de 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1685,6 +1685,10 @@ public class PurpurWorldConfig {
public double snowGolemMaxHealth = 4.0D;
public double snowGolemScale = 1.0D;
public boolean snowGolemPutPumpkinBack = false;
+ public int snowGolemSnowBallMin = 20;
+ public int snowGolemSnowBallMax = 20;
+ public float snowGolemSnowBallModifier = 10.0F;
+ public double snowGolemAttackDistance = 1.25D;
private void snowGolemSettings() {
snowGolemRidable = getBoolean("mobs.snow_golem.ridable", snowGolemRidable);
snowGolemRidableInWater = getBoolean("mobs.snow_golem.ridable-in-water", snowGolemRidableInWater);
@@ -1698,6 +1702,10 @@ public class PurpurWorldConfig {
snowGolemMaxHealth = getDouble("mobs.snow_golem.attributes.max_health", snowGolemMaxHealth);
snowGolemScale = Mth.clamp(getDouble("mobs.snow_golem.attributes.scale", snowGolemScale), 0.0625D, 16.0D);
snowGolemPutPumpkinBack = getBoolean("mobs.snow_golem.pumpkin-can-be-added-back", snowGolemPutPumpkinBack);
+ snowGolemSnowBallMin = getInt("mobs.snow_golem.min-shoot-interval-ticks", snowGolemSnowBallMin);
+ snowGolemSnowBallMax = getInt("mobs.snow_golem.max-shoot-interval-ticks", snowGolemSnowBallMax);
+ snowGolemSnowBallModifier = (float) getDouble("mobs.snow_golem.snow-ball-modifier", snowGolemSnowBallModifier);
+ snowGolemAttackDistance = getDouble("mobs.snow_golem.attack-distance", snowGolemAttackDistance);
}
public boolean snifferRidable = false;

View File

@@ -1,37 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Thu, 14 Jan 2016 00:49:14 -0500
Subject: [PATCH] EMC - Configurable disable give dropping
Modified version of a patch by Aikar from EMC. Adds a config option in
purpur.yml to disable the /give command from dropping items on the
floor when a player's inventory is full.
diff --git a/src/main/java/net/minecraft/server/commands/GiveCommand.java b/src/main/java/net/minecraft/server/commands/GiveCommand.java
index 0d9de4c61c7b26a6ff37c12fde629161fd0c3d5a..2f7897744f4aea718170698881773e9031a58a51 100644
--- a/src/main/java/net/minecraft/server/commands/GiveCommand.java
+++ b/src/main/java/net/minecraft/server/commands/GiveCommand.java
@@ -60,6 +60,7 @@ public class GiveCommand {
boolean flag = entityplayer.getInventory().add(itemstack1);
ItemEntity entityitem;
+ if (org.purpurmc.purpur.PurpurConfig.disableGiveCommandDrops) continue; // Purpur - add config option for toggling give command dropping
if (flag && itemstack1.isEmpty()) {
entityitem = entityplayer.drop(itemstack, false, false, false); // CraftBukkit - SPIGOT-2942: Add boolean to call event
if (entityitem != null) {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index d4371bebdcb3b55c412334491959835e2d52220f..e86e3ceb8c93b89a37aeb3829fea65430b387941 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -211,6 +211,11 @@ public class PurpurConfig {
useAlternateKeepAlive = getBoolean("settings.use-alternate-keepalive", useAlternateKeepAlive);
}
+ public static boolean disableGiveCommandDrops = false;
+ private static void disableGiveCommandDrops() {
+ disableGiveCommandDrops = getBoolean("settings.disable-give-dropping", disableGiveCommandDrops);
+ }
+
public static int barrelRows = 3;
public static boolean enderChestSixRows = false;
public static boolean enderChestPermissionRows = false;

View File

@@ -1,197 +0,0 @@
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/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java b/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java
index 2ade08d1466660ee1787fa97908002ef56389712..4fa4ec34963730507253182cad1c2bf04090ad50 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java
@@ -41,6 +41,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
public HarvestFarmland() {
super(ImmutableMap.of(MemoryModuleType.LOOK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.SECONDARY_JOB_SITE, MemoryStatus.VALUE_PRESENT));
@@ -49,9 +50,10 @@ public class HarvestFarmland extends Behavior<Villager> {
protected boolean checkExtraStartConditions(ServerLevel world, Villager entity) {
if (!world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
return false;
- } else if (entity.getVillagerData().getProfession() != VillagerProfession.FARMER) {
+ } else if (entity.getVillagerData().getProfession() != VillagerProfession.FARMER && !(world.purpurConfig.villagerClericsFarmWarts && entity.getVillagerData().getProfession() == VillagerProfession.CLERIC)) { // Purpur
return false;
} else {
+ if (!this.clericWartFarmer && entity.getVillagerData().getProfession() == VillagerProfession.CLERIC) this.clericWartFarmer = true; // Purpur
BlockPos.MutableBlockPos blockposition_mutableblockposition = entity.blockPosition().mutable();
this.validFarmlandAroundVillager.clear();
@@ -82,6 +84,7 @@ public class HarvestFarmland extends Behavior<Villager> {
Block block = iblockdata.getBlock();
Block block1 = world.getBlockState(pos.below()).getBlock();
+ if (this.clericWartFarmer) return block == Blocks.NETHER_WART && iblockdata.getValue(net.minecraft.world.level.block.NetherWartBlock.AGE) == 3 || iblockdata.isAir() && block1 == Blocks.SOUL_SAND; // Purpur
return block instanceof CropBlock && ((CropBlock) block).isMaxAge(iblockdata) || iblockdata.isAir() && block1 instanceof FarmBlock;
}
@@ -107,20 +110,20 @@ public class HarvestFarmland extends Behavior<Villager> {
Block block = iblockdata.getBlock();
Block block1 = world.getBlockState(this.aboveFarmlandPos.below()).getBlock();
- if (block instanceof CropBlock && ((CropBlock) block).isMaxAge(iblockdata)) {
+ if (block instanceof CropBlock && ((CropBlock) block).isMaxAge(iblockdata) && !this.clericWartFarmer || this.clericWartFarmer && block == Blocks.NETHER_WART && iblockdata.getValue(net.minecraft.world.level.block.NetherWartBlock.AGE) == 3) { // Purpur
if (CraftEventFactory.callEntityChangeBlockEvent(entity, this.aboveFarmlandPos, iblockdata.getFluidState().createLegacyBlock())) { // CraftBukkit // Paper - fix wrong block state
world.destroyBlock(this.aboveFarmlandPos, true, entity);
} // CraftBukkit
}
- if (iblockdata.isAir() && block1 instanceof FarmBlock && entity.hasFarmSeeds()) {
+ if (iblockdata.isAir() && (block1 instanceof FarmBlock && !this.clericWartFarmer || this.clericWartFarmer && block1 == Blocks.SOUL_SAND) && entity.hasFarmSeeds()) { // Purpur
SimpleContainer inventorysubcontainer = entity.getInventory();
for (int j = 0; j < inventorysubcontainer.getContainerSize(); ++j) {
ItemStack itemstack = inventorysubcontainer.getItem(j);
boolean flag = false;
- if (!itemstack.isEmpty() && itemstack.is(ItemTags.VILLAGER_PLANTABLE_SEEDS)) {
+ if (!itemstack.isEmpty() && (itemstack.is(ItemTags.VILLAGER_PLANTABLE_SEEDS) || this.clericWartFarmer && itemstack.getItem() == net.minecraft.world.item.Items.NETHER_WART)) {
Item item = itemstack.getItem();
if (item instanceof BlockItem) {
@@ -136,7 +139,7 @@ public class HarvestFarmland extends Behavior<Villager> {
}
if (flag) {
- world.playSound((Player) null, (double) this.aboveFarmlandPos.getX(), (double) this.aboveFarmlandPos.getY(), (double) this.aboveFarmlandPos.getZ(), SoundEvents.CROP_PLANTED, SoundSource.BLOCKS, 1.0F, 1.0F);
+ world.playSound((Player) null, (double) this.aboveFarmlandPos.getX(), (double) this.aboveFarmlandPos.getY(), (double) this.aboveFarmlandPos.getZ(), this.clericWartFarmer ? SoundEvents.NETHER_WART_PLANTED : SoundEvents.CROP_PLANTED, SoundSource.BLOCKS, 1.0F, 1.0F); // Purpur
itemstack.shrink(1);
if (itemstack.isEmpty()) {
inventorysubcontainer.setItem(j, ItemStack.EMPTY);
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java b/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java
index 8508ac7de8cda3127b73e11ff4aee62502e65ead..b1544e028d5a9b84b944e1fb5a12bb163067fb54 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java
@@ -59,6 +59,12 @@ public class TradeWithVillager extends Behavior<Villager> {
throwHalfStack(entity, ImmutableSet.of(Items.WHEAT), villager);
}
+ // Purpur start
+ if (world.purpurConfig.villagerClericsFarmWarts && world.purpurConfig.villagerClericFarmersThrowWarts && entity.getVillagerData().getProfession() == VillagerProfession.CLERIC && entity.getInventory().countItem(Items.NETHER_WART) > Items.NETHER_WART.getDefaultMaxStackSize() / 2) {
+ throwHalfStack(entity, ImmutableSet.of(Items.NETHER_WART), villager);
+ }
+ // Purpur end
+
if (!this.trades.isEmpty() && entity.getInventory().hasAnyOf(this.trades)) {
throwHalfStack(entity, this.trades, villager);
}
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java
index f000a6c1e61198e6dd06ae5f084d12fdf309f50a..3091d985ba9c55d404332576320718840538722e 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/VillagerGoalPackages.java
@@ -52,8 +52,13 @@ public class VillagerGoalPackages {
}
public static ImmutableList<Pair<Integer, ? extends BehaviorControl<? super Villager>>> getWorkPackage(VillagerProfession profession, float speed) {
+ // Purpur start
+ return getWorkPackage(profession, speed, false);
+ }
+ public static ImmutableList<Pair<Integer, ? extends BehaviorControl<? super Villager>>> getWorkPackage(VillagerProfession profession, float speed, boolean clericsFarmWarts) {
+ // Purpur end
WorkAtPoi workAtPoi;
- if (profession == VillagerProfession.FARMER) {
+ if (profession == VillagerProfession.FARMER || (clericsFarmWarts && profession == VillagerProfession.CLERIC)) { // Purpur
workAtPoi = new WorkAtComposter();
} else {
workAtPoi = new WorkAtPoi();
diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java
index a0e0692d17760f440fe81d52887284c787e562db..ab9bebc07b5228dbc0d3ba4b0f7d1bbe41814c9b 100644
--- a/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java
+++ b/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java
@@ -22,6 +22,13 @@ public class SecondaryPoiSensor extends Sensor<Villager> {
@Override
protected void doTick(ServerLevel world, Villager entity) {
+ // Purpur start - make sure clerics don't wander to soul sand when the option is off
+ Brain<?> brain = entity.getBrain();
+ if (!world.purpurConfig.villagerClericsFarmWarts && entity.getVillagerData().getProfession() == net.minecraft.world.entity.npc.VillagerProfession.CLERIC) {
+ brain.eraseMemory(MemoryModuleType.SECONDARY_JOB_SITE);
+ return;
+ }
+ // Purpur end
ResourceKey<Level> resourceKey = world.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 - moved up
if (!list.isEmpty()) {
brain.setMemory(MemoryModuleType.SECONDARY_JOB_SITE, list);
} else {
diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java
index 37aefffb16c43221e39ef0b41a16968a560968ea..730327d560075e28f0ba316c64311297a474f0ca 100644
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
@@ -226,7 +226,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
brain.addActivity(Activity.PLAY, VillagerGoalPackages.getPlayPackage(0.5F));
} else {
brain.setSchedule(Schedule.VILLAGER_DEFAULT);
- brain.addActivityWithConditions(Activity.WORK, VillagerGoalPackages.getWorkPackage(villagerprofession, 0.5F), ImmutableSet.of(Pair.of(MemoryModuleType.JOB_SITE, MemoryStatus.VALUE_PRESENT)));
+ brain.addActivityWithConditions(Activity.WORK, VillagerGoalPackages.getWorkPackage(villagerprofession, 0.5F, this.level().purpurConfig.villagerClericsFarmWarts), ImmutableSet.of(Pair.of(MemoryModuleType.JOB_SITE, MemoryStatus.VALUE_PRESENT))); // Purpur
}
brain.addActivity(Activity.CORE, VillagerGoalPackages.getCorePackage(villagerprofession, 0.5F));
@@ -975,6 +975,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
public boolean hasFarmSeeds() {
return this.getInventory().hasAnyMatching((itemstack) -> {
+ // Purpur start
+ if (this.level().purpurConfig.villagerClericsFarmWarts && this.getVillagerData().getProfession() == VillagerProfession.CLERIC) {
+ return itemstack.is(Items.NETHER_WART);
+ }
+ // Purpur end
return itemstack.is(ItemTags.VILLAGER_PLANTABLE_SEEDS);
});
}
diff --git a/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java b/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java
index 8734ab1bd8299bbf43906d81a349c2a13e0981a7..3ca83269311cbc18c9ef3ce62cff6a2d4dc0a683 100644
--- a/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java
+++ b/src/main/java/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
public static final VillagerProfession FARMER = register(
"farmer",
PoiTypes.FARMER,
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 7cb8996240fe658fe5858f009fb1b8171c6de7de..057877ee0430de3b14a3082f16e510e64f3663ae 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1905,6 +1905,8 @@ public class PurpurWorldConfig {
public boolean villagerCanBeLeashed = false;
public boolean villagerCanBreed = true;
public int villagerBreedingTicks = 6000;
+ public boolean villagerClericsFarmWarts = false;
+ public boolean villagerClericFarmersThrowWarts = true;
private void villagerSettings() {
villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable);
villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater);
@@ -1920,6 +1922,8 @@ public class PurpurWorldConfig {
villagerCanBeLeashed = getBoolean("mobs.villager.can-be-leashed", villagerCanBeLeashed);
villagerCanBreed = getBoolean("mobs.villager.can-breed", villagerCanBreed);
villagerBreedingTicks = getInt("mobs.villager.breeding-delay-ticks", villagerBreedingTicks);
+ villagerClericsFarmWarts = getBoolean("mobs.villager.clerics-farm-warts", villagerClericsFarmWarts);
+ villagerClericFarmersThrowWarts = getBoolean("mobs.villager.cleric-wart-farmers-throw-warts-at-villagers", villagerClericFarmersThrowWarts);
}
public boolean vindicatorRidable = false;

View File

@@ -1,55 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Sat, 5 Dec 2020 02:34:22 -0800
Subject: [PATCH] Toggle for Zombified Piglin death always counting as player
kill when angry
In Vanilla (as of 1.16.4), when Zombified Piglins die while angry, it will
count as a player kill regardless of whether a player has ever hit them,
meaning they will drop XP. This is abused in Zombified Piglin farms where
the player kills the entities through cramming, but they still drop XP due
to the Piglin being angry, even though the player never hit them.
This patch adds a toggle to disable this behavior.
diff --git a/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java b/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java
index 53b8f46bda60289ec310cb45513a2b729fcbea76..2756319fd1e53eca6a3dfa094d7c669014c383e9 100644
--- a/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java
+++ b/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java
@@ -148,7 +148,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob {
this.maybeAlertOthers();
}
- if (this.isAngry()) {
+ if (this.isAngry() && this.level().purpurConfig.zombifiedPiglinCountAsPlayerKillWhenAngry) { // Purpur
this.lastHurtByPlayerTime = this.tickCount;
}
@@ -203,7 +203,7 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob {
this.ticksUntilNextAlert = ZombifiedPiglin.ALERT_INTERVAL.sample(this.random);
}
- if (entityliving instanceof Player) {
+ if (entityliving instanceof Player && this.level().purpurConfig.zombifiedPiglinCountAsPlayerKillWhenAngry) { // Purpur
this.setLastHurtByPlayer((Player) entityliving);
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 057877ee0430de3b14a3082f16e510e64f3663ae..43f98be23b7da635f168b123f7e47c005707be77 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -2171,6 +2171,7 @@ public class PurpurWorldConfig {
public boolean zombifiedPiglinJockeyOnlyBaby = true;
public double zombifiedPiglinJockeyChance = 0.05D;
public boolean zombifiedPiglinJockeyTryExistingChickens = true;
+ public boolean zombifiedPiglinCountAsPlayerKillWhenAngry = true;
private void zombifiedPiglinSettings() {
zombifiedPiglinRidable = getBoolean("mobs.zombified_piglin.ridable", zombifiedPiglinRidable);
zombifiedPiglinRidableInWater = getBoolean("mobs.zombified_piglin.ridable-in-water", zombifiedPiglinRidableInWater);
@@ -2186,5 +2187,6 @@ public class PurpurWorldConfig {
zombifiedPiglinJockeyOnlyBaby = getBoolean("mobs.zombified_piglin.jockey.only-babies", zombifiedPiglinJockeyOnlyBaby);
zombifiedPiglinJockeyChance = getDouble("mobs.zombified_piglin.jockey.chance", zombifiedPiglinJockeyChance);
zombifiedPiglinJockeyTryExistingChickens = getBoolean("mobs.zombified_piglin.jockey.try-existing-chickens", zombifiedPiglinJockeyTryExistingChickens);
+ zombifiedPiglinCountAsPlayerKillWhenAngry = getBoolean("mobs.zombified_piglin.count-as-player-kill-when-angry", zombifiedPiglinCountAsPlayerKillWhenAngry);
}
}

View File

@@ -1,205 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Tue, 8 Dec 2020 17:15:15 -0500
Subject: [PATCH] Configurable chance for wolves to spawn rabid
Configurable chance to spawn a wolf that is rabid.
Rabid wolves attack all players, mobs, and animals.
diff --git a/src/main/java/net/minecraft/world/entity/animal/Wolf.java b/src/main/java/net/minecraft/world/entity/animal/Wolf.java
index 0647cee2d6a7c847ab923f819a092c9004eabc6c..d159d573d5f87c31cf61baacbaae193d24ab6801 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Wolf.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Wolf.java
@@ -107,6 +107,37 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder<Hol
return entitytypes == EntityType.SHEEP || entitytypes == EntityType.RABBIT || entitytypes == EntityType.FOX;
};
+ // Purpur start - rabid wolf spawn chance
+ private boolean isRabid = false;
+ private static final Predicate<LivingEntity> RABID_PREDICATE = entity -> entity instanceof net.minecraft.server.level.ServerPlayer || entity instanceof Mob;
+ private final net.minecraft.world.entity.ai.goal.Goal PATHFINDER_VANILLA = new NonTameRandomTargetGoal<>(this, Animal.class, false, PREY_SELECTOR);
+ private final net.minecraft.world.entity.ai.goal.Goal PATHFINDER_RABID = new NonTameRandomTargetGoal<>(this, LivingEntity.class, false, RABID_PREDICATE);
+ private static final class AvoidRabidWolfGoal extends AvoidEntityGoal<Wolf> {
+ private final Wolf wolf;
+
+ public AvoidRabidWolfGoal(Wolf wolf, float distance, double minSpeed, double maxSpeed) {
+ super(wolf, Wolf.class, distance, minSpeed, maxSpeed);
+ this.wolf = wolf;
+ }
+
+ @Override
+ public boolean canUse() {
+ return super.canUse() && !this.wolf.isRabid() && this.toAvoid != null && this.toAvoid.isRabid(); // wolves which are not rabid run away from rabid wolves
+ }
+
+ @Override
+ public void start() {
+ this.wolf.setTarget(null);
+ super.start();
+ }
+
+ @Override
+ public void tick() {
+ this.wolf.setTarget(null);
+ super.tick();
+ }
+ }
+ // Purpur end
private static final float START_HEALTH = 8.0F;
private static final float TAME_HEALTH = 40.0F;
private static final float ARMOR_REPAIR_UNIT = 0.125F;
@@ -160,6 +191,30 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder<Hol
return this.level().purpurConfig.wolfBreedingTicks;
}
+ public boolean isRabid() {
+ return this.isRabid;
+ }
+
+ public void setRabid(boolean isRabid) {
+ this.isRabid = isRabid;
+ updatePathfinders(true);
+ }
+
+ public void updatePathfinders(boolean modifyEffects) {
+ this.targetSelector.removeGoal(PATHFINDER_VANILLA);
+ this.targetSelector.removeGoal(PATHFINDER_RABID);
+ if (this.isRabid) {
+ setOwnerUUID(null);
+ setTame(false, true);
+ this.targetSelector.addGoal(5, PATHFINDER_RABID);
+ if (modifyEffects) this.addEffect(new net.minecraft.world.effect.MobEffectInstance(net.minecraft.world.effect.MobEffects.CONFUSION, 1200));
+ } else {
+ this.targetSelector.addGoal(5, PATHFINDER_VANILLA);
+ this.stopBeingAngry();
+ if (modifyEffects) this.removeEffect(net.minecraft.world.effect.MobEffects.CONFUSION);
+ }
+ }
+
@Override
protected void registerGoals() {
this.goalSelector.addGoal(1, new FloatGoal(this));
@@ -167,6 +222,7 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder<Hol
this.goalSelector.addGoal(1, new TamableAnimal.TamableAnimalPanicGoal(1.5D, DamageTypeTags.PANIC_ENVIRONMENTAL_CAUSES));
this.goalSelector.addGoal(2, new SitWhenOrderedToGoal(this));
this.goalSelector.addGoal(3, new Wolf.WolfAvoidEntityGoal<>(this, Llama.class, 24.0F, 1.5D, 1.5D));
+ this.goalSelector.addGoal(3, new AvoidRabidWolfGoal(this, 24.0F, 1.5D, 1.5D)); // Purpur
this.goalSelector.addGoal(4, new LeapAtTargetGoal(this, 0.4F));
this.goalSelector.addGoal(5, new MeleeAttackGoal(this, 1.0D, true));
this.goalSelector.addGoal(6, new FollowOwnerGoal(this, 1.0D, 10.0F, 2.0F));
@@ -180,7 +236,7 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder<Hol
this.targetSelector.addGoal(2, new OwnerHurtTargetGoal(this));
this.targetSelector.addGoal(3, (new HurtByTargetGoal(this, new Class[0])).setAlertOthers());
this.targetSelector.addGoal(4, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, this::isAngryAt));
- this.targetSelector.addGoal(5, new NonTameRandomTargetGoal<>(this, Animal.class, false, Wolf.PREY_SELECTOR));
+ // this.targetSelector.addGoal(5, new NonTameRandomTargetGoal<>(this, Animal.class, false, Wolf.PREY_SELECTOR)); // Purpur - moved to updatePathfinders()
this.targetSelector.addGoal(6, new NonTameRandomTargetGoal<>(this, Turtle.class, false, Turtle.BABY_ON_LAND_SELECTOR));
this.targetSelector.addGoal(7, new NearestAttackableTargetGoal<>(this, AbstractSkeleton.class, false));
this.targetSelector.addGoal(8, new ResetUniversalAngerTargetGoal<>(this, true));
@@ -229,6 +285,7 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder<Hol
public void addAdditionalSaveData(CompoundTag nbt) {
super.addAdditionalSaveData(nbt);
nbt.putByte("CollarColor", (byte) this.getCollarColor().getId());
+ nbt.putBoolean("Purpur.IsRabid", this.isRabid); // Purpur
this.getVariant().unwrapKey().ifPresent((resourcekey) -> {
nbt.putString("variant", resourcekey.location().toString());
});
@@ -246,6 +303,10 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder<Hol
if (nbt.contains("CollarColor", 99)) {
this.setCollarColor(DyeColor.byId(nbt.getInt("CollarColor")));
}
+ // Purpur start
+ this.isRabid = nbt.getBoolean("Purpur.IsRabid");
+ this.updatePathfinders(false);
+ // Purpur end
this.readPersistentAngerSaveData(this.level(), nbt);
}
@@ -264,6 +325,12 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder<Hol
}
this.setVariant(holder1);
+
+ // Purpur start
+ this.isRabid = world.getLevel().purpurConfig.wolfNaturalRabid > 0.0D && random.nextDouble() <= world.getLevel().purpurConfig.wolfNaturalRabid;
+ this.updatePathfinders(false);
+ // Purpur end
+
return super.finalizeSpawn(world, difficulty, spawnReason, (SpawnGroupData) entityData);
}
@@ -307,6 +374,11 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder<Hol
public void tick() {
super.tick();
if (this.isAlive()) {
+ // Purpur start
+ if (this.age % 300 == 0 && this.isRabid()) {
+ this.addEffect(new net.minecraft.world.effect.MobEffectInstance(net.minecraft.world.effect.MobEffects.CONFUSION, 400));
+ }
+ // Purpur end
this.interestedAngleO = this.interestedAngle;
if (this.isInterested()) {
this.interestedAngle += (1.0F - this.interestedAngle) * 0.4F;
@@ -552,6 +624,19 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder<Hol
itemstack.consume(1, player);
this.tryToTame(player);
return InteractionResult.SUCCESS;
+ // Purpur start
+ } else if (this.level().purpurConfig.wolfMilkCuresRabies && itemstack.getItem() == Items.MILK_BUCKET && this.isRabid()) {
+ if (!player.isCreative()) {
+ player.setItemInHand(hand, new ItemStack(Items.BUCKET));
+ }
+ this.setRabid(false);
+ for (int i = 0; i < 10; ++i) {
+ ((ServerLevel) level()).sendParticles(((ServerLevel) level()).players(), null, ParticleTypes.HAPPY_VILLAGER,
+ getX() + random.nextFloat(), getY() + (random.nextFloat() * 1.5), getZ() + random.nextFloat(), 1,
+ random.nextGaussian() * 0.05D, random.nextGaussian() * 0.05D, random.nextGaussian() * 0.05D, 0, true);
+ }
+ return InteractionResult.SUCCESS;
+ // Purpur end
} else {
return super.mobInteract(player, hand);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java
index 86574da257731de7646a712ed73384955fe35aa3..e223234dd64b0e41441c3b9f649f0b64dc6d98c4 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java
@@ -146,4 +146,16 @@ public class CraftWolf extends CraftTameableAnimal implements Wolf {
return this.getKey().hashCode();
}
}
+
+ // Purpur start
+ @Override
+ public boolean isRabid() {
+ return getHandle().isRabid();
+ }
+
+ @Override
+ public void setRabid(boolean isRabid) {
+ getHandle().setRabid(isRabid);
+ }
+ // Purpur end
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 43f98be23b7da635f168b123f7e47c005707be77..2b23ba7a29fb1fd0952e476fae4fe999609dfe6e 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -2046,6 +2046,8 @@ public class PurpurWorldConfig {
public boolean wolfControllable = true;
public double wolfMaxHealth = 8.0D;
public double wolfScale = 1.0D;
+ public boolean wolfMilkCuresRabies = true;
+ public double wolfNaturalRabid = 0.0D;
public int wolfBreedingTicks = 6000;
private void wolfSettings() {
wolfRidable = getBoolean("mobs.wolf.ridable", wolfRidable);
@@ -2058,6 +2060,8 @@ public class PurpurWorldConfig {
}
wolfMaxHealth = getDouble("mobs.wolf.attributes.max_health", wolfMaxHealth);
wolfScale = Mth.clamp(getDouble("mobs.wolf.attributes.scale", wolfScale), 0.0625D, 16.0D);
+ wolfMilkCuresRabies = getBoolean("mobs.wolf.milk-cures-rabid-wolves", wolfMilkCuresRabies);
+ wolfNaturalRabid = getDouble("mobs.wolf.spawn-rabid-chance", wolfNaturalRabid);
wolfBreedingTicks = getInt("mobs.wolf.breeding-delay-ticks", wolfBreedingTicks);
}

View File

@@ -1,88 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Thu, 10 Dec 2020 13:43:28 -0500
Subject: [PATCH] Configurable default collar color
This allows for the server to set a default collar color when a wolf or cat is tamed.
Resets to RED when the value is invalid.
diff --git a/src/main/java/net/minecraft/world/entity/animal/Cat.java b/src/main/java/net/minecraft/world/entity/animal/Cat.java
index c8266b1a6b609ef92bd83dcb0e86e3cf47ccce6d..356f3728fdadf8190cd6c806789f4fd70820ec94 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Cat.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Cat.java
@@ -348,6 +348,14 @@ public class Cat extends TamableAnimal implements VariantHolder<Holder<CatVarian
return Mth.lerp(tickDelta, this.relaxStateOneAmountO, this.relaxStateOneAmount);
}
+ // Purpur start
+ @Override
+ public void tame(Player player) {
+ setCollarColor(level().purpurConfig.catDefaultCollarColor);
+ super.tame(player);
+ }
+ // Purpur end
+
@Nullable
@Override
public Cat getBreedOffspring(ServerLevel world, AgeableMob entity) {
diff --git a/src/main/java/net/minecraft/world/entity/animal/Wolf.java b/src/main/java/net/minecraft/world/entity/animal/Wolf.java
index d159d573d5f87c31cf61baacbaae193d24ab6801..143717d64651ffd75124973ca7a15fc1fd007da3 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Wolf.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Wolf.java
@@ -215,6 +215,12 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder<Hol
}
}
+ @Override
+ public void tame(Player player) {
+ setCollarColor(level().purpurConfig.wolfDefaultCollarColor);
+ super.tame(player);
+ }
+
@Override
protected void registerGoals() {
this.goalSelector.addGoal(1, new FloatGoal(this));
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 2b23ba7a29fb1fd0952e476fae4fe999609dfe6e..ec7b78a2a9270ae5f0e37cfe559768adc41dab84 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -618,6 +618,7 @@ public class PurpurWorldConfig {
public int catSpawnSwampHutScanRange = 16;
public int catSpawnVillageScanRange = 48;
public int catBreedingTicks = 6000;
+ public DyeColor catDefaultCollarColor = DyeColor.RED;
private void catSettings() {
catRidable = getBoolean("mobs.cat.ridable", catRidable);
catRidableInWater = getBoolean("mobs.cat.ridable-in-water", catRidableInWater);
@@ -633,6 +634,11 @@ public class PurpurWorldConfig {
catSpawnSwampHutScanRange = getInt("mobs.cat.scan-range-for-other-cats.swamp-hut", catSpawnSwampHutScanRange);
catSpawnVillageScanRange = getInt("mobs.cat.scan-range-for-other-cats.village", catSpawnVillageScanRange);
catBreedingTicks = getInt("mobs.cat.breeding-delay-ticks", catBreedingTicks);
+ try {
+ catDefaultCollarColor = DyeColor.valueOf(getString("mobs.cat.default-collar-color", catDefaultCollarColor.name()));
+ } catch (IllegalArgumentException ignore) {
+ catDefaultCollarColor = DyeColor.RED;
+ }
}
public boolean caveSpiderRidable = false;
@@ -2046,6 +2052,7 @@ public class PurpurWorldConfig {
public boolean wolfControllable = true;
public double wolfMaxHealth = 8.0D;
public double wolfScale = 1.0D;
+ public DyeColor wolfDefaultCollarColor = DyeColor.RED;
public boolean wolfMilkCuresRabies = true;
public double wolfNaturalRabid = 0.0D;
public int wolfBreedingTicks = 6000;
@@ -2060,6 +2067,11 @@ public class PurpurWorldConfig {
}
wolfMaxHealth = getDouble("mobs.wolf.attributes.max_health", wolfMaxHealth);
wolfScale = Mth.clamp(getDouble("mobs.wolf.attributes.scale", wolfScale), 0.0625D, 16.0D);
+ try {
+ wolfDefaultCollarColor = DyeColor.valueOf(getString("mobs.wolf.default-collar-color", wolfDefaultCollarColor.name()));
+ } catch (IllegalArgumentException ignore) {
+ wolfDefaultCollarColor = DyeColor.RED;
+ }
wolfMilkCuresRabies = getBoolean("mobs.wolf.milk-cures-rabid-wolves", wolfMilkCuresRabies);
wolfNaturalRabid = getDouble("mobs.wolf.spawn-rabid-chance", wolfNaturalRabid);
wolfBreedingTicks = getInt("mobs.wolf.breeding-delay-ticks", wolfBreedingTicks);

View File

@@ -1,38 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Sat, 12 Dec 2020 09:10:59 -0600
Subject: [PATCH] Phantom flames on swoop
diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
index 8f221fe016ea7221eb3a2116a2213139cf961797..88725e6f8c6490253e110485f5a62e9d3d2c9aa9 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
@@ -237,6 +237,7 @@ public class Phantom extends FlyingMob implements Enemy {
this.level().addParticle(ParticleTypes.MYCELIUM, this.getX() - (double) f3, this.getY() + (double) f5, this.getZ() - (double) f4, 0.0D, 0.0D, 0.0D);
}
+ if (level().purpurConfig.phantomFlamesOnSwoop && attackPhase == AttackPhase.SWOOP) shoot(); // Purpur
}
@Override
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index ec7b78a2a9270ae5f0e37cfe559768adc41dab84..4dce5107ed9a2ae1148ccc5c51ec54d57426cb83 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1347,6 +1347,7 @@ public class PurpurWorldConfig {
public int phantomBurnInLight = 0;
public boolean phantomIgnorePlayersWithTorch = false;
public boolean phantomBurnInDaylight = true;
+ public boolean phantomFlamesOnSwoop = false;
private void phantomSettings() {
phantomRidable = getBoolean("mobs.phantom.ridable", phantomRidable);
phantomRidableInWater = getBoolean("mobs.phantom.ridable-in-water", phantomRidableInWater);
@@ -1380,6 +1381,7 @@ public class PurpurWorldConfig {
phantomBurnInLight = getInt("mobs.phantom.burn-in-light", phantomBurnInLight);
phantomBurnInDaylight = getBoolean("mobs.phantom.burn-in-daylight", phantomBurnInDaylight);
phantomIgnorePlayersWithTorch = getBoolean("mobs.phantom.ignore-players-with-torch", phantomIgnorePlayersWithTorch);
+ phantomFlamesOnSwoop = getBoolean("mobs.phantom.flames-on-swoop", phantomFlamesOnSwoop);
}
public boolean pigRidable = false;

View File

@@ -1,34 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Sat, 12 Dec 2020 14:34:18 -0800
Subject: [PATCH] Option for chests to open even with a solid block on top
diff --git a/src/main/java/net/minecraft/world/level/block/ChestBlock.java b/src/main/java/net/minecraft/world/level/block/ChestBlock.java
index 0b27baf10770cb3077c4e75da55209689d614513..485ea9892f257c6843db23bca43f9fdcd8fa1503 100644
--- a/src/main/java/net/minecraft/world/level/block/ChestBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/ChestBlock.java
@@ -342,6 +342,7 @@ public class ChestBlock extends AbstractChestBlock<ChestBlockEntity> implements
}
public static boolean isBlockedChestByBlock(BlockGetter world, BlockPos pos) {
+ if (world instanceof Level && ((Level) world).purpurConfig.chestOpenWithBlockOnTop) return false; // Purpur
BlockPos blockposition1 = pos.above();
return world.getBlockState(blockposition1).isRedstoneConductor(world, blockposition1);
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 4dce5107ed9a2ae1148ccc5c51ec54d57426cb83..a83719bd540910f799997e6593356d56bd097c42 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -375,6 +375,11 @@ public class PurpurWorldConfig {
}
}
+ public boolean chestOpenWithBlockOnTop = false;
+ private void chestSettings() {
+ chestOpenWithBlockOnTop = getBoolean("blocks.chest.open-with-solid-block-on-top", chestOpenWithBlockOnTop);
+ }
+
public boolean dispenserApplyCursedArmor = true;
public boolean dispenserPlaceAnvils = false;
private void dispenserSettings() {

View File

@@ -1,467 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Sat, 12 Dec 2020 21:19:05 -0600
Subject: [PATCH] Implement TPSBar
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
index 09e3c9dd08b6a5765d76390b2c8f62200fd3e27c..286f141255984dddbc3252304d6c11b0647cbbf4 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
@@ -253,6 +253,7 @@ public class Commands {
org.purpurmc.purpur.command.CreditsCommand.register(this.dispatcher); // Purpur
org.purpurmc.purpur.command.DemoCommand.register(this.dispatcher); // Purpur
org.purpurmc.purpur.command.PingCommand.register(this.dispatcher); // Purpur
+ org.purpurmc.purpur.command.TPSBarCommand.register(this.dispatcher); // Purpur
}
if (environment.includeIntegrated) {
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index f514c421b5ff7e46b2d211f895dcb0d7a375704f..b14bfa10927c1e0e93f1c3515947077f11eb3ece 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1137,6 +1137,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.safeShutdown(waitForShutdown, false);
}
public void safeShutdown(boolean waitForShutdown, boolean isRestarting) {
+ org.purpurmc.purpur.task.BossBarTask.stopAll(); // Purpur
this.isRestarting = isRestarting;
this.hasLoggedStop = true; // Paper - Debugging
if (isDebugging()) io.papermc.paper.util.TraceUtil.dumpTraceForThread("Server stopped"); // Paper - Debugging
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index ea89f36bb1ecb8a7a8b88d6f46bc24554609647f..e093ef5b2712776767db6b9b78e46bbee5b91ee5 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -371,6 +371,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
}
if (gg.pufferfish.pufferfish.PufferfishConfig.enableAsyncMobSpawning) mobSpawnExecutor.start(); // Pufferfish
+ org.purpurmc.purpur.task.BossBarTask.startAll(); // Purpur
return true;
}
}
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 0b57d9a2e2573bdb41c9e163d953130c3a4a1747..6100c35a54a9f597bb7e4925bf2c63aa7e0d64d3 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -303,6 +303,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
public @Nullable String clientBrandName = null; // Paper - Brand support
public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event
public boolean purpurClient = false; // Purpur
+ private boolean tpsBar = false; // Purpur
// Paper start - rewrite chunk system
private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader;
@@ -600,6 +601,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
});
}
+ if (nbt.contains("Purpur.TPSBar")) { this.tpsBar = nbt.getBoolean("Purpur.TPSBar"); } // Purpur
}
@Override
@@ -676,6 +678,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
});
}
+ nbt.putBoolean("Purpur.TPSBar", this.tpsBar); // Purpur
}
// CraftBukkit start - World fallback code, either respawn location or global spawn
@@ -3067,5 +3070,13 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
this.server.getPlayerList().respawn(this, true, RemovalReason.KILLED, org.bukkit.event.player.PlayerRespawnEvent.RespawnReason.DEATH, to);
}
}
+
+ public boolean tpsBar() {
+ return this.tpsBar;
+ }
+
+ public void tpsBar(boolean tpsBar) {
+ this.tpsBar = tpsBar;
+ }
// Purpur end
}
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 2f476929f5dc521ff76b27586cf2a919fc09b7fa..338bf471d9214c77653eb69510b722b552e60172 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -480,6 +480,7 @@ public abstract class PlayerList {
scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam);
}
// Paper end - Configurable player collision
+ org.purpurmc.purpur.task.BossBarTask.addToAll(player); // Purpur
PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), s1, player.getId(), worldserver1.serverLevelData.getLevelName(), player.getX(), player.getY(), player.getZ());
}
@@ -591,6 +592,7 @@ public abstract class PlayerList {
}
public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer, net.kyori.adventure.text.Component leaveMessage) {
// Paper end - Fix kick event leave message not being sent
+ org.purpurmc.purpur.task.BossBarTask.removeFromAll(entityplayer.getBukkitEntity()); // Purpur
ServerLevel worldserver = entityplayer.serverLevel();
entityplayer.awardStat(Stats.LEAVE_GAME);
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index e86e3ceb8c93b89a37aeb3829fea65430b387941..2685a3e5e4d0a1559f2d28152bab73b8982362fd 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -184,6 +184,7 @@ public class PurpurConfig {
public static String creditsCommandOutput = "<green>%s has been shown the end credits";
public static String demoCommandOutput = "<green>%s has been shown the demo screen";
public static String pingCommandOutput = "<green>%s's ping is %sms";
+ public static String tpsbarCommandOutput = "<green>Tpsbar toggled <onoff> for <target>";
private static void messages() {
cannotRideMob = getString("settings.messages.cannot-ride-mob", cannotRideMob);
afkBroadcastAway = getString("settings.messages.afk-broadcast-away", afkBroadcastAway);
@@ -194,6 +195,7 @@ public class PurpurConfig {
creditsCommandOutput = getString("settings.messages.credits-command-output", creditsCommandOutput);
demoCommandOutput = getString("settings.messages.demo-command-output", demoCommandOutput);
pingCommandOutput = getString("settings.messages.ping-command-output", pingCommandOutput);
+ tpsbarCommandOutput = getString("settings.messages.tpsbar-command-output", tpsbarCommandOutput);
}
public static String serverModName = io.papermc.paper.ServerBuildInfo.buildInfo().brandName();
@@ -216,6 +218,29 @@ public class PurpurConfig {
disableGiveCommandDrops = getBoolean("settings.disable-give-dropping", disableGiveCommandDrops);
}
+ public static String commandTPSBarTitle = "<gray>TPS<yellow>:</yellow> <tps> MSPT<yellow>:</yellow> <mspt> Ping<yellow>:</yellow> <ping>ms";
+ public static BossBar.Overlay commandTPSBarProgressOverlay = BossBar.Overlay.NOTCHED_20;
+ public static TPSBarTask.FillMode commandTPSBarProgressFillMode = TPSBarTask.FillMode.MSPT;
+ public static BossBar.Color commandTPSBarProgressColorGood = BossBar.Color.GREEN;
+ public static BossBar.Color commandTPSBarProgressColorMedium = BossBar.Color.YELLOW;
+ public static BossBar.Color commandTPSBarProgressColorLow = BossBar.Color.RED;
+ public static String commandTPSBarTextColorGood = "<gradient:#55ff55:#00aa00><text></gradient>";
+ public static String commandTPSBarTextColorMedium = "<gradient:#ffff55:#ffaa00><text></gradient>";
+ public static String commandTPSBarTextColorLow = "<gradient:#ff5555:#aa0000><text></gradient>";
+ public static int commandTPSBarTickInterval = 20;
+ private static void commandSettings() {
+ commandTPSBarTitle = getString("settings.command.tpsbar.title", commandTPSBarTitle);
+ commandTPSBarProgressOverlay = BossBar.Overlay.valueOf(getString("settings.command.tpsbar.overlay", commandTPSBarProgressOverlay.name()));
+ commandTPSBarProgressFillMode = TPSBarTask.FillMode.valueOf(getString("settings.command.tpsbar.fill-mode", commandTPSBarProgressFillMode.name()));
+ commandTPSBarProgressColorGood = BossBar.Color.valueOf(getString("settings.command.tpsbar.progress-color.good", commandTPSBarProgressColorGood.name()));
+ commandTPSBarProgressColorMedium = BossBar.Color.valueOf(getString("settings.command.tpsbar.progress-color.medium", commandTPSBarProgressColorMedium.name()));
+ commandTPSBarProgressColorLow = BossBar.Color.valueOf(getString("settings.command.tpsbar.progress-color.low", commandTPSBarProgressColorLow.name()));
+ commandTPSBarTextColorGood = getString("settings.command.tpsbar.text-color.good", commandTPSBarTextColorGood);
+ commandTPSBarTextColorMedium = getString("settings.command.tpsbar.text-color.medium", commandTPSBarTextColorMedium);
+ commandTPSBarTextColorLow = getString("settings.command.tpsbar.text-color.low", commandTPSBarTextColorLow);
+ commandTPSBarTickInterval = getInt("settings.command.tpsbar.tick-interval", commandTPSBarTickInterval);
+ }
+
public static int barrelRows = 3;
public static boolean enderChestSixRows = false;
public static boolean enderChestPermissionRows = false;
diff --git a/src/main/java/org/purpurmc/purpur/command/TPSBarCommand.java b/src/main/java/org/purpurmc/purpur/command/TPSBarCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..d8f9b044107ff7c29a83eb5378aa9f5465ba1995
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/command/TPSBarCommand.java
@@ -0,0 +1,44 @@
+package org.purpurmc.purpur.command;
+
+import com.mojang.brigadier.CommandDispatcher;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor;
+import net.kyori.adventure.text.minimessage.MiniMessage;
+import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
+import net.minecraft.commands.CommandSourceStack;
+import net.minecraft.commands.Commands;
+import net.minecraft.commands.arguments.EntityArgument;
+import net.minecraft.server.level.ServerPlayer;
+import org.purpurmc.purpur.PurpurConfig;
+import org.purpurmc.purpur.task.TPSBarTask;
+
+import java.util.Collection;
+import java.util.Collections;
+
+public class TPSBarCommand {
+ public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
+ dispatcher.register(Commands.literal("tpsbar")
+ .requires(listener -> listener.hasPermission(2, "bukkit.command.tpsbar"))
+ .executes(context -> execute(context.getSource(), Collections.singleton(context.getSource().getPlayerOrException())))
+ .then(Commands.argument("targets", EntityArgument.players())
+ .requires(listener -> listener.hasPermission(2, "bukkit.command.tpsbar.other"))
+ .executes((context) -> execute(context.getSource(), EntityArgument.getPlayers(context, "targets")))
+ )
+ );
+ }
+
+ private static int execute(CommandSourceStack sender, Collection<ServerPlayer> targets) {
+ for (ServerPlayer player : targets) {
+ boolean result = TPSBarTask.instance().togglePlayer(player.getBukkitEntity());
+ player.tpsBar(result);
+
+ Component output = MiniMessage.miniMessage().deserialize(PurpurConfig.tpsbarCommandOutput,
+ Placeholder.component("onoff", Component.translatable(result ? "options.on" : "options.off")
+ .color(result ? NamedTextColor.GREEN : NamedTextColor.RED)),
+ Placeholder.parsed("target", player.getGameProfile().getName()));
+
+ sender.sendSuccess(output, false);
+ }
+ return targets.size();
+ }
+}
diff --git a/src/main/java/org/purpurmc/purpur/task/BossBarTask.java b/src/main/java/org/purpurmc/purpur/task/BossBarTask.java
new file mode 100644
index 0000000000000000000000000000000000000000..6796fd6a936212a6eb768d9cf0fa5e74132c89e8
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/task/BossBarTask.java
@@ -0,0 +1,109 @@
+package org.purpurmc.purpur.task;
+
+import net.kyori.adventure.bossbar.BossBar;
+import net.minecraft.server.level.ServerPlayer;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.scheduler.BukkitRunnable;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.UUID;
+import org.purpurmc.purpur.util.MinecraftInternalPlugin;
+
+public abstract class BossBarTask extends BukkitRunnable {
+ private final Map<UUID, BossBar> bossbars = new HashMap<>();
+ private boolean started;
+
+ abstract BossBar createBossBar();
+
+ abstract void updateBossBar(BossBar bossbar, Player player);
+
+ @Override
+ public void run() {
+ Iterator<Map.Entry<UUID, BossBar>> iter = bossbars.entrySet().iterator();
+ while (iter.hasNext()) {
+ Map.Entry<UUID, BossBar> entry = iter.next();
+ Player player = Bukkit.getPlayer(entry.getKey());
+ if (player == null) {
+ iter.remove();
+ continue;
+ }
+ updateBossBar(entry.getValue(), player);
+ }
+ }
+
+ @Override
+ public void cancel() {
+ super.cancel();
+ new HashSet<>(this.bossbars.keySet()).forEach(uuid -> {
+ Player player = Bukkit.getPlayer(uuid);
+ if (player != null) {
+ removePlayer(player);
+ }
+ });
+ this.bossbars.clear();
+ }
+
+ public boolean removePlayer(Player player) {
+ BossBar bossbar = this.bossbars.remove(player.getUniqueId());
+ if (bossbar != null) {
+ player.hideBossBar(bossbar);
+ return true;
+ }
+ return false;
+ }
+
+ public void addPlayer(Player player) {
+ removePlayer(player);
+ BossBar bossbar = createBossBar();
+ this.bossbars.put(player.getUniqueId(), bossbar);
+ this.updateBossBar(bossbar, player);
+ player.showBossBar(bossbar);
+ }
+
+ public boolean hasPlayer(UUID uuid) {
+ return this.bossbars.containsKey(uuid);
+ }
+
+ public boolean togglePlayer(Player player) {
+ if (removePlayer(player)) {
+ return false;
+ }
+ addPlayer(player);
+ return true;
+ }
+
+ public void start() {
+ stop();
+ this.runTaskTimerAsynchronously(new MinecraftInternalPlugin(), 1, 1);
+ started = true;
+ }
+
+ public void stop() {
+ if (started) {
+ cancel();
+ }
+ }
+
+ public static void startAll() {
+ TPSBarTask.instance().start();
+ }
+
+ public static void stopAll() {
+ TPSBarTask.instance().stop();
+ }
+
+ public static void addToAll(ServerPlayer player) {
+ Player bukkit = player.getBukkitEntity();
+ if (player.tpsBar()) {
+ TPSBarTask.instance().addPlayer(bukkit);
+ }
+ }
+
+ public static void removeFromAll(Player player) {
+ TPSBarTask.instance().removePlayer(player);
+ }
+}
diff --git a/src/main/java/org/purpurmc/purpur/task/TPSBarTask.java b/src/main/java/org/purpurmc/purpur/task/TPSBarTask.java
new file mode 100644
index 0000000000000000000000000000000000000000..8769993e7ca59da309087051a3cd38fc562c15d1
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/task/TPSBarTask.java
@@ -0,0 +1,142 @@
+package org.purpurmc.purpur.task;
+
+import net.kyori.adventure.bossbar.BossBar;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.minimessage.MiniMessage;
+import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
+import org.purpurmc.purpur.PurpurConfig;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+
+public class TPSBarTask extends BossBarTask {
+ private static TPSBarTask instance;
+ private double tps = 20.0D;
+ private double mspt = 0.0D;
+ private int tick = 0;
+
+ public static TPSBarTask instance() {
+ if (instance == null) {
+ instance = new TPSBarTask();
+ }
+ return instance;
+ }
+
+ @Override
+ BossBar createBossBar() {
+ return BossBar.bossBar(Component.text(""), 0.0F, instance().getBossBarColor(), PurpurConfig.commandTPSBarProgressOverlay);
+ }
+
+ @Override
+ void updateBossBar(BossBar bossbar, Player player) {
+ bossbar.progress(getBossBarProgress());
+ bossbar.color(getBossBarColor());
+ bossbar.name(MiniMessage.miniMessage().deserialize(PurpurConfig.commandTPSBarTitle,
+ Placeholder.component("tps", getTPSColor()),
+ Placeholder.component("mspt", getMSPTColor()),
+ Placeholder.component("ping", getPingColor(player.getPing()))
+ ));
+ }
+
+ @Override
+ public void run() {
+ if (++tick < PurpurConfig.commandTPSBarTickInterval) {
+ return;
+ }
+ tick = 0;
+
+ this.tps = Math.max(Math.min(Bukkit.getTPS()[0], 20.0D), 0.0D);
+ this.mspt = Bukkit.getAverageTickTime();
+
+ super.run();
+ }
+
+ private float getBossBarProgress() {
+ if (PurpurConfig.commandTPSBarProgressFillMode == FillMode.MSPT) {
+ return Math.max(Math.min((float) mspt / 50.0F, 1.0F), 0.0F);
+ } else {
+ return Math.max(Math.min((float) tps / 20.0F, 1.0F), 0.0F);
+ }
+ }
+
+ private BossBar.Color getBossBarColor() {
+ if (isGood(PurpurConfig.commandTPSBarProgressFillMode)) {
+ return PurpurConfig.commandTPSBarProgressColorGood;
+ } else if (isMedium(PurpurConfig.commandTPSBarProgressFillMode)) {
+ return PurpurConfig.commandTPSBarProgressColorMedium;
+ } else {
+ return PurpurConfig.commandTPSBarProgressColorLow;
+ }
+ }
+
+ private boolean isGood(FillMode mode) {
+ return isGood(mode, 0);
+ }
+
+ private boolean isGood(FillMode mode, int ping) {
+ if (mode == FillMode.MSPT) {
+ return mspt < 40;
+ } else if (mode == FillMode.TPS) {
+ return tps >= 19;
+ } else if (mode == FillMode.PING) {
+ return ping < 100;
+ } else {
+ return false;
+ }
+ }
+
+ private boolean isMedium(FillMode mode) {
+ return isMedium(mode, 0);
+ }
+
+ private boolean isMedium(FillMode mode, int ping) {
+ if (mode == FillMode.MSPT) {
+ return mspt < 50;
+ } else if (mode == FillMode.TPS) {
+ return tps >= 15;
+ } else if (mode == FillMode.PING) {
+ return ping < 200;
+ } else {
+ return false;
+ }
+ }
+
+ private Component getTPSColor() {
+ String color;
+ if (isGood(FillMode.TPS)) {
+ color = PurpurConfig.commandTPSBarTextColorGood;
+ } else if (isMedium(FillMode.TPS)) {
+ color = PurpurConfig.commandTPSBarTextColorMedium;
+ } else {
+ color = PurpurConfig.commandTPSBarTextColorLow;
+ }
+ return MiniMessage.miniMessage().deserialize(color, Placeholder.parsed("text", String.format("%.2f", tps)));
+ }
+
+ private Component getMSPTColor() {
+ String color;
+ if (isGood(FillMode.MSPT)) {
+ color = PurpurConfig.commandTPSBarTextColorGood;
+ } else if (isMedium(FillMode.MSPT)) {
+ color = PurpurConfig.commandTPSBarTextColorMedium;
+ } else {
+ color = PurpurConfig.commandTPSBarTextColorLow;
+ }
+ return MiniMessage.miniMessage().deserialize(color, Placeholder.parsed("text", String.format("%.2f", mspt)));
+ }
+
+ private Component getPingColor(int ping) {
+ String color;
+ if (isGood(FillMode.PING, ping)) {
+ color = PurpurConfig.commandTPSBarTextColorGood;
+ } else if (isMedium(FillMode.PING, ping)) {
+ color = PurpurConfig.commandTPSBarTextColorMedium;
+ } else {
+ color = PurpurConfig.commandTPSBarTextColorLow;
+ }
+ return MiniMessage.miniMessage().deserialize(color, Placeholder.parsed("text", String.format("%s", ping)));
+ }
+
+ public enum FillMode {
+ TPS, MSPT, PING
+ }
+}

View File

@@ -1,50 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ben Kerllenevich <ben@omega24.dev>
Date: Sun, 13 Dec 2020 20:40:57 -0500
Subject: [PATCH] Striders give saddle back
diff --git a/src/main/java/net/minecraft/world/entity/monster/Strider.java b/src/main/java/net/minecraft/world/entity/monster/Strider.java
index 8c233a90d07db7959b778a84c4ed0589a6a10dd4..d534eaa9231602f8fa73d0230223f08348aae95b 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Strider.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Strider.java
@@ -485,6 +485,19 @@ public class Strider extends Animal implements ItemSteerable, Saddleable {
public InteractionResult mobInteract(Player player, InteractionHand hand) {
boolean flag = this.isFood(player.getItemInHand(hand));
+ // Purpur start
+ if (level().purpurConfig.striderGiveSaddleBack && player.isSecondaryUseActive() && !flag && isSaddled() && !isVehicle()) {
+ this.steering.setSaddle(false);
+ if (!player.getAbilities().instabuild) {
+ ItemStack saddle = new ItemStack(Items.SADDLE);
+ if (!player.getInventory().add(saddle)) {
+ player.drop(saddle, false);
+ }
+ }
+ return InteractionResult.SUCCESS;
+ }
+ // Purpur end
+
if (!flag && this.isSaddled() && !this.isVehicle() && !player.isSecondaryUseActive()) {
if (!this.level().isClientSide) {
player.startRiding(this);
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index a83719bd540910f799997e6593356d56bd097c42..cef84202cfd5a74a722994be58c46619ae7cb951 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1800,6 +1800,7 @@ public class PurpurWorldConfig {
public double striderMaxHealth = 20.0D;
public double striderScale = 1.0D;
public int striderBreedingTicks = 6000;
+ public boolean striderGiveSaddleBack = false;
private void striderSettings() {
striderRidable = getBoolean("mobs.strider.ridable", striderRidable);
striderRidableInWater = getBoolean("mobs.strider.ridable-in-water", striderRidableInWater);
@@ -1812,6 +1813,7 @@ public class PurpurWorldConfig {
striderMaxHealth = getDouble("mobs.strider.attributes.max_health", striderMaxHealth);
striderScale = Mth.clamp(getDouble("mobs.strider.attributes.scale", striderScale), 0.0625D, 16.0D);
striderBreedingTicks = getInt("mobs.strider.breeding-delay-ticks", striderBreedingTicks);
+ striderGiveSaddleBack = getBoolean("mobs.strider.give-saddle-back", striderGiveSaddleBack);
}
public boolean tadpoleRidable = false;

View File

@@ -1,31 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Wed, 23 Dec 2020 00:43:59 -0600
Subject: [PATCH] PlayerBookTooLargeEvent
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 5c9e35d9b645774e0d96c9a089ab071034827ea2..ef55fc102b06e6fec0c39c86a5b32d3b170e0a6f 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1188,6 +1188,10 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
final int maxBookPageSize = pageMax.intValue();
final double multiplier = Math.clamp(io.papermc.paper.configuration.GlobalConfiguration.get().itemValidation.bookSize.totalMultiplier, 0.3D, 1D);
long byteAllowed = maxBookPageSize;
+ // Purpur start
+ int slot = packet.slot();
+ ItemStack itemstack = Inventory.isHotbarSlot(slot) || slot == Inventory.SLOT_OFFHAND ? this.player.getInventory().getItem(slot) : ItemStack.EMPTY;
+ // Purpur end
for (final String page : pageList) {
final int byteLength = page.getBytes(java.nio.charset.StandardCharsets.UTF_8).length;
byteTotal += byteLength;
@@ -1212,7 +1216,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
}
if (byteTotal > byteAllowed) {
- ServerGamePacketListenerImpl.LOGGER.warn("{} tried to send a book too large. Book size: {} - Allowed: {} - Pages: {}", this.player.getScoreboardName(), byteTotal, byteAllowed, pageList.size());
+ ServerGamePacketListenerImpl.LOGGER.warn("{} tried to send too large of a book. Book size: {} - Allowed: {} - Pages: {}", this.player.getScoreboardName(), byteTotal, byteAllowed, pageList.size());
+ org.purpurmc.purpur.event.player.PlayerBookTooLargeEvent event = new org.purpurmc.purpur.event.player.PlayerBookTooLargeEvent(player.getBukkitEntity(), itemstack.asBukkitCopy()); if (event.shouldKickPlayer()) // Purpur
this.disconnectAsync(Component.literal("Book too large!"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause // Paper - add proper async disconnect
return;
}

View File

@@ -1,51 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Thu, 24 Dec 2020 11:00:15 -0600
Subject: [PATCH] Full netherite armor grants fire resistance
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
index 9dd8dc8f0dc218c5a021d84649f364cd2f1b3a45..33c1b2b387e7412a001841d1bcbb3966c188c1a3 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -387,6 +387,16 @@ public abstract class Player extends LivingEntity {
this.addEffect(new MobEffectInstance(MobEffects.WATER_BREATHING, 200, 0, false, false, true), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.TURTLE_HELMET); // CraftBukkit
}
+ // Purpur start
+ if (this.level().purpurConfig.playerNetheriteFireResistanceDuration > 0 && this.level().getGameTime() % 20 == 0) {
+ if (itemstack.is(Items.NETHERITE_HELMET)
+ && this.getItemBySlot(EquipmentSlot.CHEST).is(Items.NETHERITE_CHESTPLATE)
+ && this.getItemBySlot(EquipmentSlot.LEGS).is(Items.NETHERITE_LEGGINGS)
+ && this.getItemBySlot(EquipmentSlot.FEET).is(Items.NETHERITE_BOOTS)) {
+ this.addEffect(new MobEffectInstance(MobEffects.FIRE_RESISTANCE, this.level().purpurConfig.playerNetheriteFireResistanceDuration, this.level().purpurConfig.playerNetheriteFireResistanceAmplifier, this.level().purpurConfig.playerNetheriteFireResistanceAmbient, this.level().purpurConfig.playerNetheriteFireResistanceShowParticles, this.level().purpurConfig.playerNetheriteFireResistanceShowIcon), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.NETHERITE_ARMOR);
+ }
+ }
+ // Purpur end
}
protected ItemCooldowns createItemCooldowns() {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index cef84202cfd5a74a722994be58c46619ae7cb951..38a3ea0784a0797f26b8d3b9adb1d825b0c8058b 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -284,6 +284,19 @@ public class PurpurWorldConfig {
villageSiegeSpawning = getBoolean("gameplay-mechanics.mob-spawning.village-sieges", predicate);
}
+ public int playerNetheriteFireResistanceDuration = 0;
+ public int playerNetheriteFireResistanceAmplifier = 0;
+ public boolean playerNetheriteFireResistanceAmbient = false;
+ public boolean playerNetheriteFireResistanceShowParticles = false;
+ public boolean playerNetheriteFireResistanceShowIcon = true;
+ private void playerNetheriteFireResistance() {
+ playerNetheriteFireResistanceDuration = getInt("gameplay-mechanics.player.netherite-fire-resistance.duration", playerNetheriteFireResistanceDuration);
+ playerNetheriteFireResistanceAmplifier = getInt("gameplay-mechanics.player.netherite-fire-resistance.amplifier", playerNetheriteFireResistanceAmplifier);
+ playerNetheriteFireResistanceAmbient = getBoolean("gameplay-mechanics.player.netherite-fire-resistance.ambient", playerNetheriteFireResistanceAmbient);
+ playerNetheriteFireResistanceShowParticles = getBoolean("gameplay-mechanics.player.netherite-fire-resistance.show-particles", playerNetheriteFireResistanceShowParticles);
+ playerNetheriteFireResistanceShowIcon = getBoolean("gameplay-mechanics.player.netherite-fire-resistance.show-icon", playerNetheriteFireResistanceShowIcon);
+ }
+
public boolean idleTimeoutKick = true;
public boolean idleTimeoutTickNearbyEntities = true;
public boolean idleTimeoutCountAsSleeping = false;

View File

@@ -1,681 +0,0 @@
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/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index cd2775bf0b59056a8329b1e7e2649f4b3cd92b2a..4f172f9a0ec61a10b0b1411b9d0eb82d49bd0c57 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -1857,7 +1857,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
boolean flag = false;
if (this.dead && adversary instanceof WitherBoss) { // Paper
- if (this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (this.level().purpurConfig.witherBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur
BlockPos blockposition = this.blockPosition();
BlockState iblockdata = Blocks.WITHER_ROSE.defaultBlockState();
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
index d9743c9e0026d1f858aacc6a78dc39f144360b96..70ace6f2a42c0d4181cb22a08dd923bd77c08295 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
@@ -707,7 +707,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
public void aiStep() {
super.aiStep();
this.level().getProfiler().push("looting");
- if (!this.level().isClientSide && this.canPickUpLoot() && this.isAlive() && !this.dead && this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (!this.level().isClientSide && this.canPickUpLoot() && this.isAlive() && !this.dead && (this.level().purpurConfig.entitiesPickUpLootBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) {
Vec3i baseblockposition = this.getPickupReach();
List<ItemEntity> list = this.level().getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate((double) baseblockposition.getX(), (double) baseblockposition.getY(), (double) baseblockposition.getZ()));
Iterator iterator = list.iterator();
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java b/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java
index 4fa4ec34963730507253182cad1c2bf04090ad50..8d4e206aa05b95b7bfec5d23496085cf55a3e1de 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/HarvestFarmland.java
@@ -48,7 +48,7 @@ public class HarvestFarmland extends Behavior<Villager> {
}
protected boolean checkExtraStartConditions(ServerLevel world, Villager entity) {
- if (!world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (!world.purpurConfig.villagerBypassMobGriefing && !world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur
return false;
} else if (entity.getVillagerData().getProfession() != VillagerProfession.FARMER && !(world.purpurConfig.villagerClericsFarmWarts && entity.getVillagerData().getProfession() == VillagerProfession.CLERIC)) { // Purpur
return false;
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java
index a85885ee51df585fa11ae9f8fcd67ff2a71c5a18..d81509e08e70ec5b2f837c9dc66b1254c86854e4 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java
@@ -32,7 +32,7 @@ public class BreakDoorGoal extends DoorInteractGoal {
@Override
public boolean canUse() {
- return !super.canUse() ? false : (!this.mob.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ? false : this.isValidDifficulty(this.mob.level().getDifficulty()) && !this.isOpen());
+ return !super.canUse() ? false : ((!this.mob.level().purpurConfig.zombieBypassMobGriefing && !this.mob.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) ? false : this.isValidDifficulty(this.mob.level().getDifficulty()) && !this.isOpen()); // Purpur
}
@Override
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java
index 4e2c23ccdf4e4a4d65b291dbe20952bae1838bff..0da884a833f6c707fea512e826658c3bb73f7a77 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/EatBlockGoal.java
@@ -74,7 +74,7 @@ public class EatBlockGoal extends Goal {
final BlockState blockState = this.level.getBlockState(blockposition); // Paper - fix wrong block state
if (EatBlockGoal.IS_TALL_GRASS.test(blockState)) { // Paper - fix wrong block state
- if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition, blockState.getFluidState().createLegacyBlock(), !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Paper - fix wrong block state
+ if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition, blockState.getFluidState().createLegacyBlock(), !this.level.purpurConfig.sheepBypassMobGriefing && !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Paper - fix wrong block state // Purpur
this.level.destroyBlock(blockposition, false);
}
@@ -83,7 +83,7 @@ public class EatBlockGoal extends Goal {
BlockPos blockposition1 = blockposition.below();
if (this.level.getBlockState(blockposition1).is(Blocks.GRASS_BLOCK)) {
- if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition1, Blocks.DIRT.defaultBlockState(), !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Paper - Fix wrong block state
+ if (CraftEventFactory.callEntityChangeBlockEvent(this.mob, blockposition1, Blocks.DIRT.defaultBlockState(), !this.level.purpurConfig.sheepBypassMobGriefing && !this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Paper - Fix wrong block state // Purpur
this.level.levelEvent(2001, blockposition1, Block.getId(Blocks.GRASS_BLOCK.defaultBlockState()));
this.level.setBlock(blockposition1, Blocks.DIRT.defaultBlockState(), 2);
}
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java
index 6634228ef002cbef67980272a26be4a75c954116..a61abba840a55fb4fbc9716a5e05eb2778068785 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java
@@ -40,7 +40,7 @@ public class RemoveBlockGoal extends MoveToBlockGoal {
@Override
public boolean canUse() {
- if (!this.removerMob.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (!this.removerMob.level().purpurConfig.zombieBypassMobGriefing && !this.removerMob.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur
return false;
} else if (this.nextStartTick > 0) {
--this.nextStartTick;
diff --git a/src/main/java/net/minecraft/world/entity/animal/Fox.java b/src/main/java/net/minecraft/world/entity/animal/Fox.java
index 252df18c369d5e556632ed5a287dab04e4e9b58d..6c56c51a89928ba52b1fb5f66f6169fa94fffed0 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Fox.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Fox.java
@@ -1385,7 +1385,7 @@ public class Fox extends Animal implements VariantHolder<Fox.Type> {
}
protected void onReachedTarget() {
- if (Fox.this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (Fox.this.level().purpurConfig.foxBypassMobGriefing || Fox.this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur
BlockState iblockdata = Fox.this.level().getBlockState(this.blockPos);
if (iblockdata.is(Blocks.SWEET_BERRY_BUSH)) {
diff --git a/src/main/java/net/minecraft/world/entity/animal/Rabbit.java b/src/main/java/net/minecraft/world/entity/animal/Rabbit.java
index 7e509458134340bd05d15f5f51b6d1fce3206d6a..db9ed247a2a2c2316a9dcc06a8961345c40752a9 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Rabbit.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Rabbit.java
@@ -636,7 +636,7 @@ public class Rabbit extends Animal implements VariantHolder<Rabbit.Variant> {
@Override
public boolean canUse() {
if (this.nextStartTick <= 0) {
- if (!this.rabbit.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (!this.rabbit.level().purpurConfig.rabbitBypassMobGriefing && !this.rabbit.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur
return false;
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
index 5b910b4168b7f7825916c14e402f7f00b651cd60..09be2e9651a736bf44f3f06f1d4e6a5b4dcf230b 100644
--- a/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
+++ b/src/main/java/net/minecraft/world/entity/animal/SnowGolem.java
@@ -126,7 +126,7 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
this.hurt(this.damageSources().melting(), 1.0F); // CraftBukkit - DamageSources.ON_FIRE -> CraftEventFactory.MELTING
}
- if (!this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (!this.level().purpurConfig.snowGolemBypassMobGriefing && !this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur
return;
}
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
index cc5fd3d020187adcbd20d4947beb353b291bdfd1..f80319504d70580f977acccd935af489f7d8f712 100644
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
@@ -621,7 +621,7 @@ public class EnderDragon extends Mob implements Enemy {
BlockState iblockdata = this.level().getBlockState(blockposition);
if (!iblockdata.isAir() && !iblockdata.is(BlockTags.DRAGON_TRANSPARENT)) {
- if (this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && !iblockdata.is(BlockTags.DRAGON_IMMUNE)) {
+ if ((this.level().purpurConfig.enderDragonBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) && !iblockdata.is(BlockTags.DRAGON_IMMUNE)) { // Purpur
// CraftBukkit start - Add blocks to list rather than destroying them
// flag1 = this.level().removeBlock(blockposition, false) || flag1;
flag1 = true;
diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
index 0d753a16c77251b421735f9e38202af00baf46f9..24677d1a9750f5757a983c4f6ecef42a442932c6 100644
--- a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
+++ b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
@@ -502,7 +502,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
if (this.destroyBlocksTick > 0) {
--this.destroyBlocksTick;
- if (this.destroyBlocksTick == 0 && this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (this.destroyBlocksTick == 0 && (this.level().purpurConfig.witherBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // Purpur
boolean flag = false;
j = Mth.floor(this.getBbWidth() / 2.0F + 1.0F);
diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
index 3348b5a9e4e00ef7f4dabe10d0fe0a9c0456dbd7..e71db58a2824d0a6a8df1a3d13ad5ac14604ad99 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
@@ -535,7 +535,15 @@ public class EnderMan extends Monster implements NeutralMob {
@Override
public boolean canUse() {
if (!enderman.level().purpurConfig.endermanAllowGriefing) return false; // Purpur
- return this.enderman.getCarriedBlock() == null ? false : (!this.enderman.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ? false : this.enderman.getRandom().nextInt(reducedTickDelay(2000)) == 0);
+ // Purpur start
+ if (this.enderman.getCarriedBlock() == null) {
+ return false;
+ }
+ if (!this.enderman.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && !this.enderman.level().purpurConfig.endermanBypassMobGriefing) {
+ return false;
+ }
+ return this.enderman.getRandom().nextInt(reducedTickDelay(2000)) == 0;
+ // Purpur end
}
@Override
@@ -581,7 +589,15 @@ public class EnderMan extends Monster implements NeutralMob {
@Override
public boolean canUse() {
if (!enderman.level().purpurConfig.endermanAllowGriefing) return false; // Purpur
- return this.enderman.getCarriedBlock() != null ? false : (!this.enderman.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ? false : this.enderman.getRandom().nextInt(reducedTickDelay(20)) == 0);
+ // Purpur start
+ if (this.enderman.getCarriedBlock() != null) {
+ return false;
+ }
+ if (!this.enderman.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && !this.enderman.level().purpurConfig.endermanBypassMobGriefing) {
+ return false;
+ }
+ return this.enderman.getRandom().nextInt(reducedTickDelay(20)) == 0;
+ // Purpur end
}
@Override
diff --git a/src/main/java/net/minecraft/world/entity/monster/Evoker.java b/src/main/java/net/minecraft/world/entity/monster/Evoker.java
index 8aa91f45d3a863308ce1fce1fde40a6c9a2042db..a7976b5d8548277061aa6a4e1147922e283d5a7d 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Evoker.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Evoker.java
@@ -365,7 +365,7 @@ public class Evoker extends SpellcasterIllager {
return false;
} else if (Evoker.this.tickCount < this.nextAttackTickCount) {
return false;
- } else if (!Evoker.this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ } else if (!Evoker.this.level().purpurConfig.evokerBypassMobGriefing && !Evoker.this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur
return false;
} else {
List<Sheep> list = Evoker.this.level().getNearbyEntities(Sheep.class, this.wololoTargeting, Evoker.this, Evoker.this.getBoundingBox().inflate(16.0D, 4.0D, 16.0D));
diff --git a/src/main/java/net/minecraft/world/entity/monster/Ravager.java b/src/main/java/net/minecraft/world/entity/monster/Ravager.java
index f3b57f58738d7cb84bd25f0ce7752ce859f03c96..5d9e85b22c0fe8d0b9d9fc06fc1f3cd170931e17 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Ravager.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Ravager.java
@@ -170,7 +170,7 @@ public class Ravager extends Raider {
this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(Mth.lerp(0.1D, d1, d0));
}
- if (this.horizontalCollision && this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (this.horizontalCollision && (this.level().purpurConfig.ravagerBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // Purpur
boolean flag = false;
AABB axisalignedbb = this.getBoundingBox().inflate(0.2D);
Iterator iterator = BlockPos.betweenClosed(Mth.floor(axisalignedbb.minX), Mth.floor(axisalignedbb.minY), Mth.floor(axisalignedbb.minZ), Mth.floor(axisalignedbb.maxX), Mth.floor(axisalignedbb.maxY), Mth.floor(axisalignedbb.maxZ)).iterator();
diff --git a/src/main/java/net/minecraft/world/entity/monster/Silverfish.java b/src/main/java/net/minecraft/world/entity/monster/Silverfish.java
index e59ee35faa8b4ec35021074ce67666569c27da63..4325dc4889fb4c514798b85ef4d06725b0c5faa7 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Silverfish.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Silverfish.java
@@ -194,7 +194,7 @@ public class Silverfish extends Monster {
continue;
}
// CraftBukkit end
- if (world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
+ if (world.purpurConfig.silverfishBypassMobGriefing || world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { // Purpur
world.destroyBlock(blockposition1, true, this.silverfish);
} else {
world.setBlock(blockposition1, ((InfestedBlock) block).hostStateByInfested(world.getBlockState(blockposition1)), 3);
@@ -232,7 +232,7 @@ public class Silverfish extends Monster {
} else {
RandomSource randomsource = this.mob.getRandom();
- if (this.mob.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && randomsource.nextInt(reducedTickDelay(10)) == 0) {
+ if ((this.mob.level().purpurConfig.silverfishBypassMobGriefing || this.mob.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) && randomsource.nextInt(reducedTickDelay(10)) == 0) { // Purpur
this.selectedDirection = Direction.getRandom(randomsource);
BlockPos blockposition = BlockPos.containing(this.mob.getX(), this.mob.getY() + 0.5D, this.mob.getZ()).relative(this.selectedDirection);
BlockState iblockdata = this.mob.level().getBlockState(blockposition);
diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java
index 65bb3045cd74ef1695eb8c1edd71f8b72b2d9378..ed312ed8c668ee6b02ae6e89b5a44bb4fe6d4b48 100644
--- a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java
+++ b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java
@@ -413,7 +413,7 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento
@Override
public boolean wantsToPickUp(ItemStack stack) {
- return this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && this.canPickUpLoot() && PiglinAi.wantsToPickup(this, stack);
+ return (this.level().purpurConfig.piglinBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) && this.canPickUpLoot() && PiglinAi.wantsToPickup(this, stack);
}
protected boolean canReplaceCurrentItem(ItemStack stack) {
diff --git a/src/main/java/net/minecraft/world/entity/projectile/LargeFireball.java b/src/main/java/net/minecraft/world/entity/projectile/LargeFireball.java
index 28a65f2a9ef441ae96a7a635e0695b14ce2ee367..7b6c58a31d37896daccb5f570d3cb9247cea2cd6 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/LargeFireball.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/LargeFireball.java
@@ -23,20 +23,20 @@ public class LargeFireball extends Fireball {
public LargeFireball(EntityType<? extends LargeFireball> type, Level world) {
super(type, world);
- this.isIncendiary = this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit
+ this.isIncendiary = this.level().purpurConfig.fireballsBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit // Purpur
}
public LargeFireball(Level world, LivingEntity owner, Vec3 velocity, int explosionPower) {
super(EntityType.FIREBALL, owner, velocity, world);
this.explosionPower = explosionPower;
- this.isIncendiary = this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit
+ this.isIncendiary = this.level().purpurConfig.fireballsBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // CraftBukkit // Purpur
}
@Override
protected void onHit(HitResult hitResult) {
super.onHit(hitResult);
if (!this.level().isClientSide) {
- boolean flag = this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
+ boolean flag = this.level().purpurConfig.fireballsBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // Purpur
// CraftBukkit start - fire ExplosionPrimeEvent
ExplosionPrimeEvent event = new ExplosionPrimeEvent((org.bukkit.entity.Explosive) this.getBukkitEntity());
diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
index 710e67ff9c57a6b1dc46abf5de98d54da1410136..9ededdbb5db39e9dff7376d80e93f41e93efdf5d 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
@@ -394,7 +394,7 @@ public abstract class Projectile extends Entity implements TraceableEntity {
public boolean mayInteract(Level world, BlockPos pos) {
Entity entity = this.getOwner();
- return entity instanceof Player ? entity.mayInteract(world, pos) : entity == null || world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
+ return entity instanceof Player ? entity.mayInteract(world, pos) : entity == null || world.purpurConfig.projectilesBypassMobGriefing || world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
}
public boolean mayBreak(Level world) {
diff --git a/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java b/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java
index 1711ad457e7d1233fd32edc3e9e3b9f1e3be9980..554d3c4db6ed07e3d12af23a9a18c28480bf77c0 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/SmallFireball.java
@@ -30,7 +30,7 @@ public class SmallFireball extends Fireball {
super(EntityType.SMALL_FIREBALL, owner, velocity, world);
// CraftBukkit start
if (this.getOwner() != null && this.getOwner() instanceof Mob) {
- this.isIncendiary = this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
+ this.isIncendiary = this.level().purpurConfig.fireballsBypassMobGriefing || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); // Purpur
}
// CraftBukkit end
}
diff --git a/src/main/java/net/minecraft/world/entity/raid/Raider.java b/src/main/java/net/minecraft/world/entity/raid/Raider.java
index bbf21ea433f9e3963aac0ede597ed8d3c8e50ed8..06487fc9ea416d8256e0c2cd1969d4e0283ffb05 100644
--- a/src/main/java/net/minecraft/world/entity/raid/Raider.java
+++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java
@@ -299,7 +299,7 @@ public abstract class Raider extends PatrollingMonster {
@Override
public boolean canUse() {
- if (!this.mob.level().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 && !this.mob.level().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
Raid raid = this.mob.getCurrentRaid();
if (this.mob.hasActiveRaid() && !this.mob.getCurrentRaid().isOver() && this.mob.canBeLeader() && !ItemStack.matches(this.mob.getItemBySlot(EquipmentSlot.HEAD), Raid.getLeaderBannerInstance(this.mob.registryAccess().lookupOrThrow(Registries.BANNER_PATTERN)))) {
diff --git a/src/main/java/net/minecraft/world/level/block/CropBlock.java b/src/main/java/net/minecraft/world/level/block/CropBlock.java
index 112d2feba5f75a2a873b595617780515945c10e4..2af4c365743b2956939335512f74e0a1d84298f7 100644
--- a/src/main/java/net/minecraft/world/level/block/CropBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/CropBlock.java
@@ -179,7 +179,7 @@ public class CropBlock extends BushBlock implements BonemealableBlock {
@Override
protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
- if (entity instanceof Ravager && CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit
+ if (entity instanceof Ravager && CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), (!world.purpurConfig.ravagerBypassMobGriefing && !world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)))) { // CraftBukkit // Purpur
world.destroyBlock(pos, true, entity);
}
diff --git a/src/main/java/net/minecraft/world/level/block/FarmBlock.java b/src/main/java/net/minecraft/world/level/block/FarmBlock.java
index dc356bd0931af9bdab9ec71e3de66e88a67375ad..99798220b6e0ad06db2ba5c9b74bfb72af185fee 100644
--- a/src/main/java/net/minecraft/world/level/block/FarmBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/FarmBlock.java
@@ -111,7 +111,7 @@ public class FarmBlock extends Block {
@Override
public void fallOn(Level world, BlockState state, BlockPos pos, Entity entity, float fallDistance) {
super.fallOn(world, state, pos, entity, fallDistance); // CraftBukkit - moved here as game rules / events shouldn't affect fall damage.
- if (!world.isClientSide && world.random.nextFloat() < fallDistance - 0.5F && entity instanceof LivingEntity && (entity instanceof Player || world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) && entity.getBbWidth() * entity.getBbWidth() * entity.getBbHeight() > 0.512F) {
+ if (!world.isClientSide && world.random.nextFloat() < fallDistance - 0.5F && entity instanceof LivingEntity && (entity instanceof Player || world.purpurConfig.farmlandBypassMobGriefing || world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) && entity.getBbWidth() * entity.getBbWidth() * entity.getBbHeight() > 0.512F) { // Purpur
// CraftBukkit start - Interact soil
org.bukkit.event.Cancellable cancellable;
if (entity instanceof Player) {
diff --git a/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java b/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java
index a6e6545402904141ffc6218a0158b0e9c67217c8..5eac1a54398dfa5571b98fb6eefca9d2bf9b2793 100644
--- a/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java
@@ -80,7 +80,7 @@ public class PowderSnowBlock extends Block implements BucketPickup {
if (!world.isClientSide) {
// CraftBukkit start
if (entity.isOnFire() && entity.mayInteract(world, pos)) {
- if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !(world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) || entity instanceof Player))) {
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !((world.purpurConfig.powderSnowBypassMobGriefing || world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) || entity instanceof Player))) {
return;
}
// CraftBukkit end
diff --git a/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java b/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java
index c7377d04ceac3ea624117439783a443c6d6f6d08..0c732cfbd9ce50198a3f85ae8ef2263d7ae0bc1a 100644
--- a/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java
@@ -221,7 +221,7 @@ public class TurtleEggBlock extends Block {
}
if (entity instanceof Player) return true;
- return world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
+ return world.purpurConfig.turtleEggsBypassMobGriefing || world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
// Purpur end
}
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 38a3ea0784a0797f26b8d3b9adb1d825b0c8058b..c38e6078eca2628dcd3cc3640a869550a95f2f49 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -116,8 +116,11 @@ public class PurpurWorldConfig {
public boolean boatsDoFallDamage = false;
public boolean disableDropsOnCrammingDeath = false;
public boolean entitiesCanUsePortals = true;
+ public boolean entitiesPickUpLootBypassMobGriefing = false;
+ public boolean fireballsBypassMobGriefing = false;
public boolean milkCuresBadOmen = true;
public boolean persistentDroppableEntityDisplayNames = true;
+ public boolean projectilesBypassMobGriefing = false;
public double tridentLoyaltyVoidReturnHeight = 0.0D;
public int raidCooldownSeconds = 0;
public int animalBreedingCooldownSeconds = 0;
@@ -127,8 +130,11 @@ public class PurpurWorldConfig {
boatsDoFallDamage = getBoolean("gameplay-mechanics.boat.do-fall-damage", boatsDoFallDamage);
disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath);
entitiesCanUsePortals = getBoolean("gameplay-mechanics.entities-can-use-portals", entitiesCanUsePortals);
+ entitiesPickUpLootBypassMobGriefing = getBoolean("gameplay-mechanics.entities-pick-up-loot-bypass-mob-griefing", entitiesPickUpLootBypassMobGriefing);
+ fireballsBypassMobGriefing = getBoolean("gameplay-mechanics.fireballs-bypass-mob-griefing", fireballsBypassMobGriefing);
milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen);
persistentDroppableEntityDisplayNames = getBoolean("gameplay-mechanics.persistent-droppable-entity-display-names", persistentDroppableEntityDisplayNames);
+ projectilesBypassMobGriefing = getBoolean("gameplay-mechanics.projectiles-bypass-mob-griefing", projectilesBypassMobGriefing);
tridentLoyaltyVoidReturnHeight = getDouble("gameplay-mechanics.trident-loyalty-void-return-height", tridentLoyaltyVoidReturnHeight);
raidCooldownSeconds = getInt("gameplay-mechanics.raid-cooldown-seconds", raidCooldownSeconds);
animalBreedingCooldownSeconds = getInt("gameplay-mechanics.animal-breeding-cooldown-seconds", animalBreedingCooldownSeconds);
@@ -400,9 +406,11 @@ public class PurpurWorldConfig {
dispenserPlaceAnvils = getBoolean("blocks.dispenser.place-anvils", dispenserPlaceAnvils);
}
+ public boolean farmlandBypassMobGriefing = false;
public boolean farmlandGetsMoistFromBelow = false;
public boolean farmlandAlpha = false;
private void farmlandSettings() {
+ farmlandBypassMobGriefing = getBoolean("blocks.farmland.bypass-mob-griefing", farmlandBypassMobGriefing);
farmlandGetsMoistFromBelow = getBoolean("blocks.farmland.gets-moist-from-below", farmlandGetsMoistFromBelow);
farmlandAlpha = getBoolean("blocks.farmland.use-alpha-farmland", farmlandAlpha);
}
@@ -427,6 +435,11 @@ public class PurpurWorldConfig {
lavaSpeedNotNether = getInt("blocks.lava.speed.not-nether", lavaSpeedNotNether);
}
+ public boolean powderSnowBypassMobGriefing = false;
+ private void powderSnowSettings() {
+ powderSnowBypassMobGriefing = getBoolean("blocks.powder_snow.bypass-mob-griefing", powderSnowBypassMobGriefing);
+ }
+
public boolean respawnAnchorExplode = true;
public double respawnAnchorExplosionPower = 5.0D;
public boolean respawnAnchorExplosionFire = true;
@@ -456,10 +469,12 @@ public class PurpurWorldConfig {
public boolean turtleEggsBreakFromExpOrbs = false;
public boolean turtleEggsBreakFromItems = false;
public boolean turtleEggsBreakFromMinecarts = false;
+ public boolean turtleEggsBypassMobGriefing = false;
private void turtleEggSettings() {
turtleEggsBreakFromExpOrbs = getBoolean("blocks.turtle_egg.break-from-exp-orbs", turtleEggsBreakFromExpOrbs);
turtleEggsBreakFromItems = getBoolean("blocks.turtle_egg.break-from-items", turtleEggsBreakFromItems);
turtleEggsBreakFromMinecarts = getBoolean("blocks.turtle_egg.break-from-minecarts", turtleEggsBreakFromMinecarts);
+ turtleEggsBypassMobGriefing = getBoolean("blocks.turtle_egg.bypass-mob-griefing", turtleEggsBypassMobGriefing);
}
public int waterInfiniteRequiredSources = 2;
@@ -744,6 +759,7 @@ public class PurpurWorldConfig {
public double creeperScale = 1.0D;
public double creeperChargedChance = 0.0D;
public boolean creeperAllowGriefing = true;
+ public boolean creeperBypassMobGriefing = false;
private void creeperSettings() {
creeperRidable = getBoolean("mobs.creeper.ridable", creeperRidable);
creeperRidableInWater = getBoolean("mobs.creeper.ridable-in-water", creeperRidableInWater);
@@ -757,6 +773,7 @@ public class PurpurWorldConfig {
creeperScale = Mth.clamp(getDouble("mobs.creeper.attributes.scale", creeperScale), 0.0625D, 16.0D);
creeperChargedChance = getDouble("mobs.creeper.naturally-charged-chance", creeperChargedChance);
creeperAllowGriefing = getBoolean("mobs.creeper.allow-griefing", creeperAllowGriefing);
+ creeperBypassMobGriefing = getBoolean("mobs.creeper.bypass-mob-griefing", creeperBypassMobGriefing);
}
public boolean dolphinRidable = false;
@@ -857,6 +874,7 @@ public class PurpurWorldConfig {
public double enderDragonMaxY = 320D;
public double enderDragonMaxHealth = 200.0D;
public boolean enderDragonAlwaysDropsFullExp = false;
+ public boolean enderDragonBypassMobGriefing = false;
private void enderDragonSettings() {
enderDragonRidable = getBoolean("mobs.ender_dragon.ridable", enderDragonRidable);
enderDragonRidableInWater = getBoolean("mobs.ender_dragon.ridable-in-water", enderDragonRidableInWater);
@@ -873,6 +891,7 @@ public class PurpurWorldConfig {
}
enderDragonMaxHealth = getDouble("mobs.ender_dragon.attributes.max_health", enderDragonMaxHealth);
enderDragonAlwaysDropsFullExp = getBoolean("mobs.ender_dragon.always-drop-full-exp", enderDragonAlwaysDropsFullExp);
+ enderDragonBypassMobGriefing = getBoolean("mobs.ender_dragon.bypass-mob-griefing", enderDragonBypassMobGriefing);
}
public boolean endermanRidable = false;
@@ -882,6 +901,7 @@ public class PurpurWorldConfig {
public double endermanScale = 1.0D;
public boolean endermanAllowGriefing = true;
public boolean endermanDespawnEvenWithBlock = false;
+ public boolean endermanBypassMobGriefing = false;
private void endermanSettings() {
endermanRidable = getBoolean("mobs.enderman.ridable", endermanRidable);
endermanRidableInWater = getBoolean("mobs.enderman.ridable-in-water", endermanRidableInWater);
@@ -895,6 +915,7 @@ public class PurpurWorldConfig {
endermanScale = Mth.clamp(getDouble("mobs.enderman.attributes.scale", endermanScale), 0.0625D, 16.0D);
endermanAllowGriefing = getBoolean("mobs.enderman.allow-griefing", endermanAllowGriefing);
endermanDespawnEvenWithBlock = getBoolean("mobs.enderman.can-despawn-with-held-block", endermanDespawnEvenWithBlock);
+ endermanBypassMobGriefing = getBoolean("mobs.enderman.bypass-mob-griefing", endermanBypassMobGriefing);
}
public boolean endermiteRidable = false;
@@ -920,6 +941,7 @@ public class PurpurWorldConfig {
public boolean evokerControllable = true;
public double evokerMaxHealth = 24.0D;
public double evokerScale = 1.0D;
+ public boolean evokerBypassMobGriefing = false;
private void evokerSettings() {
evokerRidable = getBoolean("mobs.evoker.ridable", evokerRidable);
evokerRidableInWater = getBoolean("mobs.evoker.ridable-in-water", evokerRidableInWater);
@@ -931,6 +953,7 @@ public class PurpurWorldConfig {
}
evokerMaxHealth = getDouble("mobs.evoker.attributes.max_health", evokerMaxHealth);
evokerScale = Mth.clamp(getDouble("mobs.evoker.attributes.scale", evokerScale), 0.0625D, 16.0D);
+ evokerBypassMobGriefing = getBoolean("mobs.evoker.bypass-mob-griefing", evokerBypassMobGriefing);
}
public boolean foxRidable = false;
@@ -940,6 +963,7 @@ public class PurpurWorldConfig {
public double foxScale = 1.0D;
public boolean foxTypeChangesWithTulips = false;
public int foxBreedingTicks = 6000;
+ public boolean foxBypassMobGriefing = false;
private void foxSettings() {
foxRidable = getBoolean("mobs.fox.ridable", foxRidable);
foxRidableInWater = getBoolean("mobs.fox.ridable-in-water", foxRidableInWater);
@@ -953,6 +977,7 @@ public class PurpurWorldConfig {
foxScale = Mth.clamp(getDouble("mobs.fox.attributes.scale", foxScale), 0.0625D, 16.0D);
foxTypeChangesWithTulips = getBoolean("mobs.fox.tulips-change-type", foxTypeChangesWithTulips);
foxBreedingTicks = getInt("mobs.fox.breeding-delay-ticks", foxBreedingTicks);
+ foxBypassMobGriefing = getBoolean("mobs.fox.bypass-mob-griefing", foxBypassMobGriefing);
}
public boolean frogRidable = false;
@@ -1429,6 +1454,7 @@ public class PurpurWorldConfig {
public boolean piglinControllable = true;
public double piglinMaxHealth = 16.0D;
public double piglinScale = 1.0D;
+ public boolean piglinBypassMobGriefing = false;
private void piglinSettings() {
piglinRidable = getBoolean("mobs.piglin.ridable", piglinRidable);
piglinRidableInWater = getBoolean("mobs.piglin.ridable-in-water", piglinRidableInWater);
@@ -1440,6 +1466,7 @@ public class PurpurWorldConfig {
}
piglinMaxHealth = getDouble("mobs.piglin.attributes.max_health", piglinMaxHealth);
piglinScale = Mth.clamp(getDouble("mobs.piglin.attributes.scale", piglinScale), 0.0625D, 16.0D);
+ piglinBypassMobGriefing = getBoolean("mobs.piglin.bypass-mob-griefing", piglinBypassMobGriefing);
}
public boolean piglinBruteRidable = false;
@@ -1465,6 +1492,7 @@ public class PurpurWorldConfig {
public boolean pillagerControllable = true;
public double pillagerMaxHealth = 24.0D;
public double pillagerScale = 1.0D;
+ public boolean pillagerBypassMobGriefing = false;
private void pillagerSettings() {
pillagerRidable = getBoolean("mobs.pillager.ridable", pillagerRidable);
pillagerRidableInWater = getBoolean("mobs.pillager.ridable-in-water", pillagerRidableInWater);
@@ -1476,6 +1504,7 @@ public class PurpurWorldConfig {
}
pillagerMaxHealth = getDouble("mobs.pillager.attributes.max_health", pillagerMaxHealth);
pillagerScale = Mth.clamp(getDouble("mobs.pillager.attributes.scale", pillagerScale), 0.0625D, 16.0D);
+ pillagerBypassMobGriefing = getBoolean("mobs.pillager.bypass-mob-griefing", pillagerBypassMobGriefing);
}
public boolean polarBearRidable = false;
@@ -1527,6 +1556,7 @@ public class PurpurWorldConfig {
public double rabbitNaturalToast = 0.0D;
public double rabbitNaturalKiller = 0.0D;
public int rabbitBreedingTicks = 6000;
+ public boolean rabbitBypassMobGriefing = false;
private void rabbitSettings() {
rabbitRidable = getBoolean("mobs.rabbit.ridable", rabbitRidable);
rabbitRidableInWater = getBoolean("mobs.rabbit.ridable-in-water", rabbitRidableInWater);
@@ -1541,6 +1571,7 @@ public class PurpurWorldConfig {
rabbitNaturalToast = getDouble("mobs.rabbit.spawn-toast-chance", rabbitNaturalToast);
rabbitNaturalKiller = getDouble("mobs.rabbit.spawn-killer-rabbit-chance", rabbitNaturalKiller);
rabbitBreedingTicks = getInt("mobs.rabbit.breeding-delay-ticks", rabbitBreedingTicks);
+ rabbitBypassMobGriefing = getBoolean("mobs.rabbit.bypass-mob-griefing", rabbitBypassMobGriefing);
}
public boolean ravagerRidable = false;
@@ -1548,6 +1579,7 @@ public class PurpurWorldConfig {
public boolean ravagerControllable = true;
public double ravagerMaxHealth = 100.0D;
public double ravagerScale = 1.0D;
+ public boolean ravagerBypassMobGriefing = false;
private void ravagerSettings() {
ravagerRidable = getBoolean("mobs.ravager.ridable", ravagerRidable);
ravagerRidableInWater = getBoolean("mobs.ravager.ridable-in-water", ravagerRidableInWater);
@@ -1559,6 +1591,7 @@ public class PurpurWorldConfig {
}
ravagerMaxHealth = getDouble("mobs.ravager.attributes.max_health", ravagerMaxHealth);
ravagerScale = Mth.clamp(getDouble("mobs.ravager.attributes.scale", ravagerScale), 0.0625D, 16.0D);
+ ravagerBypassMobGriefing = getBoolean("mobs.ravager.bypass-mob-griefing", ravagerBypassMobGriefing);
}
public boolean salmonRidable = false;
@@ -1583,6 +1616,7 @@ public class PurpurWorldConfig {
public double sheepMaxHealth = 8.0D;
public double sheepScale = 1.0D;
public int sheepBreedingTicks = 6000;
+ public boolean sheepBypassMobGriefing = false;
private void sheepSettings() {
sheepRidable = getBoolean("mobs.sheep.ridable", sheepRidable);
sheepRidableInWater = getBoolean("mobs.sheep.ridable-in-water", sheepRidableInWater);
@@ -1595,6 +1629,7 @@ public class PurpurWorldConfig {
sheepMaxHealth = getDouble("mobs.sheep.attributes.max_health", sheepMaxHealth);
sheepScale = Mth.clamp(getDouble("mobs.sheep.attributes.scale", sheepScale), 0.0625D, 16.0D);
sheepBreedingTicks = getInt("mobs.sheep.breeding-delay-ticks", sheepBreedingTicks);
+ sheepBypassMobGriefing = getBoolean("mobs.sheep.bypass-mob-griefing", sheepBypassMobGriefing);
}
public boolean shulkerRidable = false;
@@ -1622,6 +1657,7 @@ public class PurpurWorldConfig {
public double silverfishScale = 1.0D;
public double silverfishMovementSpeed = 0.25D;
public double silverfishAttackDamage = 1.0D;
+ public boolean silverfishBypassMobGriefing = false;
private void silverfishSettings() {
silverfishRidable = getBoolean("mobs.silverfish.ridable", silverfishRidable);
silverfishRidableInWater = getBoolean("mobs.silverfish.ridable-in-water", silverfishRidableInWater);
@@ -1635,6 +1671,7 @@ public class PurpurWorldConfig {
silverfishScale = Mth.clamp(getDouble("mobs.silverfish.attributes.scale", silverfishScale), 0.0625D, 16.0D);
silverfishMovementSpeed = getDouble("mobs.silverfish.attributes.movement_speed", silverfishMovementSpeed);
silverfishAttackDamage = getDouble("mobs.silverfish.attributes.attack_damage", silverfishAttackDamage);
+ silverfishBypassMobGriefing = getBoolean("mobs.silverfish.bypass-mob-griefing", silverfishBypassMobGriefing);
}
public boolean skeletonRidable = false;
@@ -1715,6 +1752,7 @@ public class PurpurWorldConfig {
public int snowGolemSnowBallMax = 20;
public float snowGolemSnowBallModifier = 10.0F;
public double snowGolemAttackDistance = 1.25D;
+ public boolean snowGolemBypassMobGriefing = false;
private void snowGolemSettings() {
snowGolemRidable = getBoolean("mobs.snow_golem.ridable", snowGolemRidable);
snowGolemRidableInWater = getBoolean("mobs.snow_golem.ridable-in-water", snowGolemRidableInWater);
@@ -1732,6 +1770,7 @@ public class PurpurWorldConfig {
snowGolemSnowBallMax = getInt("mobs.snow_golem.max-shoot-interval-ticks", snowGolemSnowBallMax);
snowGolemSnowBallModifier = (float) getDouble("mobs.snow_golem.snow-ball-modifier", snowGolemSnowBallModifier);
snowGolemAttackDistance = getDouble("mobs.snow_golem.attack-distance", snowGolemAttackDistance);
+ snowGolemBypassMobGriefing = getBoolean("mobs.snow_golem.bypass-mob-griefing", snowGolemBypassMobGriefing);
}
public boolean snifferRidable = false;
@@ -1935,6 +1974,7 @@ public class PurpurWorldConfig {
public int villagerBreedingTicks = 6000;
public boolean villagerClericsFarmWarts = false;
public boolean villagerClericFarmersThrowWarts = true;
+ public boolean villagerBypassMobGriefing = false;
private void villagerSettings() {
villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable);
villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater);
@@ -1952,6 +1992,7 @@ public class PurpurWorldConfig {
villagerBreedingTicks = getInt("mobs.villager.breeding-delay-ticks", villagerBreedingTicks);
villagerClericsFarmWarts = getBoolean("mobs.villager.clerics-farm-warts", villagerClericsFarmWarts);
villagerClericFarmersThrowWarts = getBoolean("mobs.villager.cleric-wart-farmers-throw-warts-at-villagers", villagerClericFarmersThrowWarts);
+ villagerBypassMobGriefing = getBoolean("mobs.villager.bypass-mob-griefing", villagerBypassMobGriefing);
}
public boolean vindicatorRidable = false;
@@ -2031,6 +2072,7 @@ public class PurpurWorldConfig {
public double witherScale = 1.0D;
public float witherHealthRegenAmount = 1.0f;
public int witherHealthRegenDelay = 20;
+ public boolean witherBypassMobGriefing = false;
private void witherSettings() {
witherRidable = getBoolean("mobs.wither.ridable", witherRidable);
witherRidableInWater = getBoolean("mobs.wither.ridable-in-water", witherRidableInWater);
@@ -2049,6 +2091,7 @@ public class PurpurWorldConfig {
witherScale = Mth.clamp(getDouble("mobs.wither.attributes.scale", witherScale), 0.0625D, 16.0D);
witherHealthRegenAmount = (float) getDouble("mobs.wither.health-regen-amount", witherHealthRegenAmount);
witherHealthRegenDelay = getInt("mobs.wither.health-regen-delay", witherHealthRegenDelay);
+ witherBypassMobGriefing = getBoolean("mobs.wither.bypass-mob-griefing", witherBypassMobGriefing);
}
public boolean witherSkeletonRidable = false;
@@ -2127,6 +2170,7 @@ public class PurpurWorldConfig {
public double zombieJockeyChance = 0.05D;
public boolean zombieJockeyTryExistingChickens = true;
public boolean zombieAggressiveTowardsVillagerWhenLagging = true;
+ public boolean zombieBypassMobGriefing = false;
private void zombieSettings() {
zombieRidable = getBoolean("mobs.zombie.ridable", zombieRidable);
zombieRidableInWater = getBoolean("mobs.zombie.ridable-in-water", zombieRidableInWater);
@@ -2143,6 +2187,7 @@ public class PurpurWorldConfig {
zombieJockeyChance = getDouble("mobs.zombie.jockey.chance", zombieJockeyChance);
zombieJockeyTryExistingChickens = getBoolean("mobs.zombie.jockey.try-existing-chickens", zombieJockeyTryExistingChickens);
zombieAggressiveTowardsVillagerWhenLagging = getBoolean("mobs.zombie.aggressive-towards-villager-when-lagging", zombieAggressiveTowardsVillagerWhenLagging);
+ zombieBypassMobGriefing = getBoolean("mobs.zombie.bypass-mob-griefing", zombieBypassMobGriefing);
}
public boolean zombieHorseRidable = false;

View File

@@ -1,43 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Fri, 8 Jan 2021 16:07:32 -0500
Subject: [PATCH] Config to allow Note Block sounds when blocked
Allows for Note Blocks to ignore whether or not there's air above them to play.
Normally, the sounds will only play when the block directly above is air.
With this patch enabled, players can place any block above the Note Block and it will still work.
diff --git a/src/main/java/net/minecraft/world/level/block/NoteBlock.java b/src/main/java/net/minecraft/world/level/block/NoteBlock.java
index 1d82cfe7af0dc42f88901fb0c44896771fdf8a93..43dd972b374daa1072608f3a68e812e7fb733a2b 100644
--- a/src/main/java/net/minecraft/world/level/block/NoteBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/NoteBlock.java
@@ -95,7 +95,7 @@ public class NoteBlock extends Block {
}
private void playNote(@Nullable Entity entity, BlockState state, Level world, BlockPos pos) {
- if (((NoteBlockInstrument) state.getValue(NoteBlock.INSTRUMENT)).worksAboveNoteBlock() || world.getBlockState(pos.above()).isAir()) {
+ if (world.purpurConfig.noteBlockIgnoreAbove || ((NoteBlockInstrument) state.getValue(NoteBlock.INSTRUMENT)).worksAboveNoteBlock() || world.getBlockState(pos.above()).isAir()) { // Purpur
// CraftBukkit start
// org.bukkit.event.block.NotePlayEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callNotePlayEvent(world, pos, state.getValue(NoteBlock.INSTRUMENT), state.getValue(NoteBlock.NOTE));
// if (event.isCancelled()) {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index c38e6078eca2628dcd3cc3640a869550a95f2f49..d7ea0c68b93dee2bf43e8b863b680f060bda0869 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -119,6 +119,7 @@ public class PurpurWorldConfig {
public boolean entitiesPickUpLootBypassMobGriefing = false;
public boolean fireballsBypassMobGriefing = false;
public boolean milkCuresBadOmen = true;
+ public boolean noteBlockIgnoreAbove = false;
public boolean persistentDroppableEntityDisplayNames = true;
public boolean projectilesBypassMobGriefing = false;
public double tridentLoyaltyVoidReturnHeight = 0.0D;
@@ -133,6 +134,7 @@ public class PurpurWorldConfig {
entitiesPickUpLootBypassMobGriefing = getBoolean("gameplay-mechanics.entities-pick-up-loot-bypass-mob-griefing", entitiesPickUpLootBypassMobGriefing);
fireballsBypassMobGriefing = getBoolean("gameplay-mechanics.fireballs-bypass-mob-griefing", fireballsBypassMobGriefing);
milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen);
+ noteBlockIgnoreAbove = getBoolean("gameplay-mechanics.note-block-ignore-above", noteBlockIgnoreAbove);
persistentDroppableEntityDisplayNames = getBoolean("gameplay-mechanics.persistent-droppable-entity-display-names", persistentDroppableEntityDisplayNames);
projectilesBypassMobGriefing = getBoolean("gameplay-mechanics.projectiles-bypass-mob-griefing", projectilesBypassMobGriefing);
tridentLoyaltyVoidReturnHeight = getDouble("gameplay-mechanics.trident-loyalty-void-return-height", tridentLoyaltyVoidReturnHeight);

View File

@@ -1,120 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mariell Hoversholm <proximyst@proximyst.com>
Date: Sat, 9 Jan 2021 15:27:46 +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/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java b/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java
index 3f5bb5c9ceb5b31fcc9ef0a7a6157e1e1cb2a09f..9bd56c48119fe630f272427a2ec99ffe19eefdfb 100644
--- a/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java
@@ -102,6 +102,13 @@ public class EndGatewayBlock extends BaseEntityBlock implements Portal {
TheEndGatewayBlockEntity tileentityendgateway = (TheEndGatewayBlockEntity) tileentity;
if (!tileentityendgateway.isCoolingDown()) {
+ // Purpur start
+ if (world.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, PlayerTeleportEvent.TeleportCause.END_GATEWAY).callEvent()) {
+ return;
+ }
+ }
+ // Purpur end
entity.setAsInsidePortal(this, pos);
TheEndGatewayBlockEntity.triggerCooldown(world, pos, state, tileentityendgateway);
}
diff --git a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
index a35a426cc7778a51523f26057b5d61b8a3e23d5d..28d8c8a879badc97cd1168e1847e2fafdc40e4bd 100644
--- a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
@@ -65,6 +65,13 @@ public class EndPortalBlock extends BaseEntityBlock implements Portal {
protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
if (entity.canUsePortal(false) && Shapes.joinIsNotEmpty(Shapes.create(entity.getBoundingBox().move((double) (-pos.getX()), (double) (-pos.getY()), (double) (-pos.getZ()))), state.getShape(world, pos), BooleanOp.AND)) {
+ // Purpur start
+ if (world.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, PlayerTeleportEvent.TeleportCause.END_PORTAL).callEvent()) {
+ return;
+ }
+ }
+ // Purpur end
// CraftBukkit start - Entity in portal
EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()), org.bukkit.PortalType.ENDER); // Paper - add portal type
world.getCraftServer().getPluginManager().callEvent(event);
diff --git a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
index 0fdbcab175b51a8b77646e0e4a267d987b133a35..e8cccf3d89ecef13c0523c2357ef4b07e30a25b4 100644
--- a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
@@ -109,6 +109,13 @@ public class NetherPortalBlock extends Block implements Portal {
protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
if (entity.canUsePortal(false)) {
+ // Purpur start
+ if (world.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
// CraftBukkit start - Entity in portal
EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()), org.bukkit.PortalType.NETHER); // Paper - add portal type
world.getCraftServer().getPluginManager().callEvent(event);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index 0883ac705b507c839246a50bd99f7230f9f3a56f..af3ab1eb9af64605203e7bb671ff08a38be9e6a6 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -245,6 +245,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
boolean ignorePassengers = flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_PASSENGERS);
// Don't allow teleporting between worlds while keeping passengers
if (flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_PASSENGERS) && this.entity.isVehicle() && location.getWorld() != this.getWorld()) {
+ if (!new org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent(entity.getBukkitEntity(), org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_VEHICLE, cause).callEvent()) // Purpur
return false;
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 82b8fca9ca46f24d71b357ed5eab89c6b27ecd8a..9df9b518f6188a758d9a712def36dadb9dd94f21 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1440,6 +1440,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
// Paper start - Teleport passenger API
// Don't allow teleporting between worlds while keeping passengers
if (ignorePassengers && entity.isVehicle() && location.getWorld() != this.getWorld()) {
+ if (!new org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent(entity.getBukkitEntity(), org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_VEHICLE, cause).callEvent()) // Purpur start
return false;
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index d7ea0c68b93dee2bf43e8b863b680f060bda0869..c348b5570aa8a311198569a2024aec12e21a3e40 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -118,6 +118,9 @@ public class PurpurWorldConfig {
public boolean entitiesCanUsePortals = true;
public boolean entitiesPickUpLootBypassMobGriefing = false;
public boolean fireballsBypassMobGriefing = false;
+ public boolean imposeTeleportRestrictionsOnGateways = false;
+ public boolean imposeTeleportRestrictionsOnNetherPortals = false;
+ public boolean imposeTeleportRestrictionsOnEndPortals = false;
public boolean milkCuresBadOmen = true;
public boolean noteBlockIgnoreAbove = false;
public boolean persistentDroppableEntityDisplayNames = true;
@@ -133,6 +136,9 @@ public class PurpurWorldConfig {
entitiesCanUsePortals = getBoolean("gameplay-mechanics.entities-can-use-portals", entitiesCanUsePortals);
entitiesPickUpLootBypassMobGriefing = getBoolean("gameplay-mechanics.entities-pick-up-loot-bypass-mob-griefing", entitiesPickUpLootBypassMobGriefing);
fireballsBypassMobGriefing = getBoolean("gameplay-mechanics.fireballs-bypass-mob-griefing", fireballsBypassMobGriefing);
+ imposeTeleportRestrictionsOnGateways = getBoolean("gameplay-mechanics.impose-teleport-restrictions-on-gateways", imposeTeleportRestrictionsOnGateways);
+ imposeTeleportRestrictionsOnNetherPortals = getBoolean("gameplay-mechanics.impose-teleport-restrictions-on-nether-portals", imposeTeleportRestrictionsOnNetherPortals);
+ imposeTeleportRestrictionsOnEndPortals = getBoolean("gameplay-mechanics.impose-teleport-restrictions-on-end-portals", imposeTeleportRestrictionsOnEndPortals);
milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen);
noteBlockIgnoreAbove = getBoolean("gameplay-mechanics.note-block-ignore-above", noteBlockIgnoreAbove);
persistentDroppableEntityDisplayNames = getBoolean("gameplay-mechanics.persistent-droppable-entity-display-names", persistentDroppableEntityDisplayNames);

View File

@@ -1,59 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mariell Hoversholm <proximyst@proximyst.com>
Date: Sat, 9 Jan 2021 16:06:40 +0100
Subject: [PATCH] Farmland trampling changes
This lets us choose if farmland trampling is fully disabled or only
players may trample farmland.
This lets us choose if entities can stop trampling if they fall a
distance equal to their feather falling level, plus the extra block
necessary to trample in the first place. Feather Falling 1 requires
you to fall over 3+ blocks to trample. FF 2 requires 4+, etc.
diff --git a/src/main/java/net/minecraft/world/level/block/FarmBlock.java b/src/main/java/net/minecraft/world/level/block/FarmBlock.java
index 99798220b6e0ad06db2ba5c9b74bfb72af185fee..12a0c69f8fec30fad64cbb00af2ca1bbf0ea5153 100644
--- a/src/main/java/net/minecraft/world/level/block/FarmBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/FarmBlock.java
@@ -126,12 +126,20 @@ public class FarmBlock extends Block {
}
// Purpur start
+ if (world.purpurConfig.farmlandTramplingDisabled) return;
+ if (world.purpurConfig.farmlandTramplingOnlyPlayers && !(entity instanceof Player)) return;
if (world.purpurConfig.farmlandAlpha) {
Block block = world.getBlockState(pos.below()).getBlock();
if (block instanceof FenceBlock || block instanceof WallBlock) {
return;
}
}
+ if (world.purpurConfig.farmlandTramplingFeatherFalling) {
+ Iterator<net.minecraft.world.item.ItemStack> armor = ((LivingEntity) entity).getArmorSlots().iterator();
+ if (armor.hasNext() && net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.FEATHER_FALLING, armor.next()) >= (int) entity.fallDistance) {
+ return;
+ }
+ }
// Purpur end
if (!CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.DIRT.defaultBlockState())) {
return;
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index c348b5570aa8a311198569a2024aec12e21a3e40..0bc350c73ecbaa253cf126c3b4071b07593643fe 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -417,10 +417,16 @@ public class PurpurWorldConfig {
public boolean farmlandBypassMobGriefing = false;
public boolean farmlandGetsMoistFromBelow = false;
public boolean farmlandAlpha = false;
+ public boolean farmlandTramplingDisabled = false;
+ public boolean farmlandTramplingOnlyPlayers = false;
+ public boolean farmlandTramplingFeatherFalling = false;
private void farmlandSettings() {
farmlandBypassMobGriefing = getBoolean("blocks.farmland.bypass-mob-griefing", farmlandBypassMobGriefing);
farmlandGetsMoistFromBelow = getBoolean("blocks.farmland.gets-moist-from-below", farmlandGetsMoistFromBelow);
farmlandAlpha = getBoolean("blocks.farmland.use-alpha-farmland", farmlandAlpha);
+ farmlandTramplingDisabled = getBoolean("blocks.farmland.disable-trampling", farmlandTramplingDisabled);
+ farmlandTramplingOnlyPlayers = getBoolean("blocks.farmland.only-players-trample", farmlandTramplingOnlyPlayers);
+ farmlandTramplingFeatherFalling = getBoolean("blocks.farmland.feather-fall-distance-affects-trampling", farmlandTramplingFeatherFalling);
}
public boolean furnaceUseLavaFromUnderneath = false;

View File

@@ -1,88 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mariell Hoversholm <proximyst@proximyst.com>
Date: Sat, 9 Jan 2021 22:22:59 +0100
Subject: [PATCH] Movement options for armor stands
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/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index acf10656ea445554ee537dcb2f23164ee77e4d60..b8b38d6b544261038905c97e8c600625f5ce2bda 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -1937,7 +1937,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return this.isInWater() || flag;
}
- void updateInWaterStateAndDoWaterCurrentPushing() {
+ public void updateInWaterStateAndDoWaterCurrentPushing() { // Purpur - package-private -> public
Entity entity = this.getVehicle();
if (entity instanceof Boat entityboat) {
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
index 4d6df7ec1bffbd30d4aac906f393ead0dfd8f69d..7180d65afee6216a0bc6ff2dc7888f64b9b6c22d 100644
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
@@ -102,10 +102,12 @@ public class ArmorStand extends LivingEntity {
private boolean noTickPoseDirty = false;
private boolean noTickEquipmentDirty = false;
// Paper end - Allow ArmorStands not to tick
+ public boolean canMovementTick = true; // Purpur
public ArmorStand(EntityType<? extends ArmorStand> type, Level world) {
super(type, world);
if (world != null) this.canTick = world.paperConfig().entities.armorStands.tick; // Paper - Allow ArmorStands not to tick
+ if (world != null) this.canMovementTick = world.purpurConfig.armorstandMovement; // Purpur
this.handItems = NonNullList.withSize(2, ItemStack.EMPTY);
this.armorItems = NonNullList.withSize(4, ItemStack.EMPTY);
this.headPose = ArmorStand.DEFAULT_HEAD_POSE;
@@ -1017,4 +1019,18 @@ public class ArmorStand extends LivingEntity {
}
}
// Paper end
+
+ // Purpur start
+ @Override
+ public void updateInWaterStateAndDoWaterCurrentPushing() {
+ if (this.level().purpurConfig.armorstandWaterMovement &&
+ (this.level().purpurConfig.armorstandWaterFence || !(level().getBlockState(blockPosition().below()).getBlock() instanceof net.minecraft.world.level.block.FenceBlock)))
+ super.updateInWaterStateAndDoWaterCurrentPushing();
+ }
+
+ @Override
+ public void aiStep() {
+ if (this.canMovementTick && this.canMove) super.aiStep();
+ }
+ // Purpur end
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 0bc350c73ecbaa253cf126c3b4071b07593643fe..fd1dfddc41e27d065f3eb429d2217c5eaa77f3b0 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -100,10 +100,16 @@ public class PurpurWorldConfig {
public float armorstandStepHeight = 0.0F;
public boolean armorstandSetNameVisible = false;
public boolean armorstandFixNametags = false;
+ public boolean armorstandMovement = true;
+ public boolean armorstandWaterMovement = true;
+ public boolean armorstandWaterFence = true;
private void armorstandSettings() {
armorstandStepHeight = (float) getDouble("gameplay-mechanics.armorstand.step-height", armorstandStepHeight);
armorstandSetNameVisible = getBoolean("gameplay-mechanics.armorstand.set-name-visible-when-placing-with-custom-name", armorstandSetNameVisible);
armorstandFixNametags = getBoolean("gameplay-mechanics.armorstand.fix-nametags", armorstandFixNametags);
+ armorstandMovement = getBoolean("gameplay-mechanics.armorstand.can-movement-tick", armorstandMovement);
+ armorstandWaterMovement = getBoolean("gameplay-mechanics.armorstand.can-move-in-water", armorstandWaterMovement);
+ armorstandWaterFence = getBoolean("gameplay-mechanics.armorstand.can-move-in-water-over-fence", armorstandWaterFence);
}
public boolean arrowMovementResetsDespawnCounter = true;

View File

@@ -1,59 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Thu, 14 Jan 2021 16:48:10 -0600
Subject: [PATCH] Fix stuck in portals
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 6100c35a54a9f597bb7e4925bf2c63aa7e0d64d3..d677c1308412e5a12046225ce2449af136b7665f 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -1424,6 +1424,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
worldserver1.removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION);
this.unsetRemoved();
// CraftBukkit end
+ this.portalPos = io.papermc.paper.util.MCUtil.toBlockPosition(exit); // Purpur - Fix stuck in portals
this.setServerLevel(worldserver);
this.connection.teleport(exit); // CraftBukkit - use internal teleport without event
this.connection.resetPosition();
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index b8b38d6b544261038905c97e8c600625f5ce2bda..901080dd8431b83b20aa5604e931519dcba82b22 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -3274,13 +3274,16 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return Vec3.directionFromRotation(this.getRotationVector());
}
+ public BlockPos portalPos = BlockPos.ZERO; // Purpur
public void setAsInsidePortal(Portal portal, BlockPos pos) {
if (this.isOnPortalCooldown()) {
+ if (!(level().purpurConfig.playerFixStuckPortal && this instanceof Player && !pos.equals(this.portalPos))) // Purpur - Fix stuck in portals
this.setPortalCooldown();
} else if (this.level.purpurConfig.entitiesCanUsePortals || this instanceof ServerPlayer) { // Purpur - Entities can use portals
if (this.portalProcess != null && this.portalProcess.isSamePortal(portal)) {
this.portalProcess.updateEntryPosition(pos.immutable());
this.portalProcess.setAsInsidePortalThisTick(true);
+ this.portalPos = BlockPos.ZERO; // Purpur - Fix stuck in portals
} else {
this.portalProcess = new PortalProcessor(portal, pos.immutable());
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index fd1dfddc41e27d065f3eb429d2217c5eaa77f3b0..f8717837f1fb25b244e38f4b32c73e57158a2bb9 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -326,6 +326,7 @@ public class PurpurWorldConfig {
public int playerDeathExpDropMax = 100;
public boolean teleportIfOutsideBorder = false;
public boolean totemOfUndyingWorksInInventory = false;
+ public boolean playerFixStuckPortal = false;
private void playerSettings() {
if (PurpurConfig.version < 19) {
boolean oldVal = getBoolean("gameplay-mechanics.player.idle-timeout.mods-target", idleTimeoutTargetPlayer);
@@ -341,6 +342,7 @@ public class PurpurWorldConfig {
playerDeathExpDropMax = getInt("gameplay-mechanics.player.exp-dropped-on-death.maximum", playerDeathExpDropMax);
teleportIfOutsideBorder = getBoolean("gameplay-mechanics.player.teleport-if-outside-border", teleportIfOutsideBorder);
totemOfUndyingWorksInInventory = getBoolean("gameplay-mechanics.player.totem-of-undying-works-in-inventory", totemOfUndyingWorksInInventory);
+ playerFixStuckPortal = getBoolean("gameplay-mechanics.player.fix-stuck-in-portal", playerFixStuckPortal);
}
public boolean silkTouchEnabled = false;

View File

@@ -1,80 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Tue, 9 Feb 2021 21:23:37 -0500
Subject: [PATCH] Config to always tame in Creative
Adds a configuration option that ensures a player in Creative always tames a tameable entity.
This essentially allows Creative mode players to tame animals on their first try.
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/RunAroundLikeCrazyGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/RunAroundLikeCrazyGoal.java
index b0944fa1f3849dd24cd010fa0a6638f5fd7179d1..d409ae987088df3d47192128401d7491aaabc87c 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/RunAroundLikeCrazyGoal.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/RunAroundLikeCrazyGoal.java
@@ -67,7 +67,7 @@ public class RunAroundLikeCrazyGoal extends Goal {
int i = this.horse.getTemper();
int j = this.horse.getMaxTemper();
- if (j > 0 && this.horse.getRandom().nextInt(j) < i && !CraftEventFactory.callEntityTameEvent(this.horse, ((CraftHumanEntity) this.horse.getBukkitEntity().getPassenger()).getHandle()).isCancelled()) { // CraftBukkit - fire EntityTameEvent
+ if ((this.horse.level().purpurConfig.alwaysTameInCreative && entityhuman.hasInfiniteMaterials()) || (j > 0 && this.horse.getRandom().nextInt(j) < i && !CraftEventFactory.callEntityTameEvent(this.horse, ((CraftHumanEntity) this.horse.getBukkitEntity().getPassenger()).getHandle()).isCancelled())) { // CraftBukkit - fire EntityTameEvent // Purpur
this.horse.tameWithName(entityhuman);
return;
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/Cat.java b/src/main/java/net/minecraft/world/entity/animal/Cat.java
index 4476fb2764bccdb0868e6e43f3a803971982effb..2cbaebbdc6bf4ce9131e67d891a612ec6ce86275 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Cat.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Cat.java
@@ -513,7 +513,7 @@ public class Cat extends TamableAnimal implements VariantHolder<Holder<CatVarian
}
private void tryToTame(Player player) {
- if (this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit
+ if ((this.level().purpurConfig.alwaysTameInCreative && player.hasInfiniteMaterials()) || this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit
this.tame(player);
this.setOrderedToSit(true);
this.level().broadcastEntityEvent(this, (byte) 7);
diff --git a/src/main/java/net/minecraft/world/entity/animal/Parrot.java b/src/main/java/net/minecraft/world/entity/animal/Parrot.java
index 0711b1c38b4bef53aeb0d447774db4a639704e8d..884fc114ef70d49fd0d64fcea46fb277950962a1 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Parrot.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Parrot.java
@@ -322,7 +322,7 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder<Parrot
}
if (!this.level().isClientSide) {
- if (this.random.nextInt(10) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) { // CraftBukkit
+ if ((this.level().purpurConfig.alwaysTameInCreative && player.hasInfiniteMaterials()) || (this.random.nextInt(10) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, player).isCancelled())) { // CraftBukkit // Purpur
this.tame(player);
this.level().broadcastEntityEvent(this, (byte) 7);
} else {
diff --git a/src/main/java/net/minecraft/world/entity/animal/Wolf.java b/src/main/java/net/minecraft/world/entity/animal/Wolf.java
index b6602362b7b450749ae1768572658b756c4e7840..2949adfbe7c71d552a4afb6aca1c166a718716f4 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Wolf.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Wolf.java
@@ -655,7 +655,7 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder<Hol
private void tryToTame(Player player) {
// CraftBukkit - added event call and isCancelled check.
- if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) {
+ if ((this.level().purpurConfig.alwaysTameInCreative && player.hasInfiniteMaterials()) || this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, player).isCancelled()) {
this.tame(player);
this.navigation.stop();
this.setTarget((LivingEntity) null);
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 791b12dd28c0a56cc9ce6a4e4414b85ea641efd0..0f2d27f3ceea7fc87bf63b10d94f4ccf339e59b9 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -118,6 +118,7 @@ public class PurpurWorldConfig {
}
public boolean useBetterMending = false;
+ public boolean alwaysTameInCreative = false;
public boolean boatEjectPlayersOnLand = false;
public boolean boatsDoFallDamage = false;
public boolean disableDropsOnCrammingDeath = false;
@@ -136,6 +137,7 @@ public class PurpurWorldConfig {
public int animalBreedingCooldownSeconds = 0;
private void miscGameplayMechanicsSettings() {
useBetterMending = getBoolean("gameplay-mechanics.use-better-mending", useBetterMending);
+ alwaysTameInCreative = getBoolean("gameplay-mechanics.always-tame-in-creative", alwaysTameInCreative);
boatEjectPlayersOnLand = getBoolean("gameplay-mechanics.boat.eject-players-on-land", boatEjectPlayersOnLand);
boatsDoFallDamage = getBoolean("gameplay-mechanics.boat.do-fall-damage", boatsDoFallDamage);
disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath);

View File

@@ -1,102 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ben Kerllenevich <ben@omega24.dev>
Date: Sat, 13 Feb 2021 09:28:56 -0500
Subject: [PATCH] End crystal explosion options
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
index 72122333cf0247e4a8511ac633487f170b89586c..02f1d0418395b100cabfad7294466aaad34ac7c6 100644
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
@@ -49,6 +49,22 @@ public class EndCrystal extends Entity {
this.setPos(x, y, z);
}
+ public boolean shouldExplode() {
+ return showsBottom() ? level().purpurConfig.basedEndCrystalExplode : level().purpurConfig.baselessEndCrystalExplode;
+ }
+
+ public float getExplosionPower() {
+ return (float) (showsBottom() ? level().purpurConfig.basedEndCrystalExplosionPower : level().purpurConfig.baselessEndCrystalExplosionPower);
+ }
+
+ public boolean hasExplosionFire() {
+ return showsBottom() ? level().purpurConfig.basedEndCrystalExplosionFire : level().purpurConfig.baselessEndCrystalExplosionFire;
+ }
+
+ public Level.ExplosionInteraction getExplosionEffect() {
+ return showsBottom() ? level().purpurConfig.basedEndCrystalExplosionEffect : level().purpurConfig.baselessEndCrystalExplosionEffect;
+ }
+
@Override
protected Entity.MovementEmission getMovementEmission() {
return Entity.MovementEmission.NONE;
@@ -172,16 +188,18 @@ public class EndCrystal extends Entity {
}
// CraftBukkit end
if (!source.is(DamageTypeTags.IS_EXPLOSION)) {
+ if (shouldExplode()) {// Purpur
DamageSource damagesource1 = source.getEntity() != null ? this.damageSources().explosion(this, source.getEntity()) : null;
// CraftBukkit start
- ExplosionPrimeEvent event = CraftEventFactory.callExplosionPrimeEvent(this, 6.0F, false);
+ ExplosionPrimeEvent event = CraftEventFactory.callExplosionPrimeEvent(this, getExplosionPower(), hasExplosionFire()); // Purpur
if (event.isCancelled()) {
return false;
}
this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause
- this.level().explode(this, damagesource1, (ExplosionDamageCalculator) null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.BLOCK);
+ this.level().explode(this, damagesource1, (ExplosionDamageCalculator) null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), getExplosionEffect()); // Purpur
+ } else this.unsetRemoved(); // Purpur
} else {
this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 0f2d27f3ceea7fc87bf63b10d94f4ccf339e59b9..4c35cab67704690ce54f412ea145537171ba0ebf 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -424,6 +424,43 @@ public class PurpurWorldConfig {
dispenserPlaceAnvils = getBoolean("blocks.dispenser.place-anvils", dispenserPlaceAnvils);
}
+ public boolean baselessEndCrystalExplode = true;
+ public double baselessEndCrystalExplosionPower = 6.0D;
+ public boolean baselessEndCrystalExplosionFire = false;
+ public net.minecraft.world.level.Level.ExplosionInteraction baselessEndCrystalExplosionEffect = net.minecraft.world.level.Level.ExplosionInteraction.BLOCK;
+ public boolean basedEndCrystalExplode = true;
+ public double basedEndCrystalExplosionPower = 6.0D;
+ public boolean basedEndCrystalExplosionFire = false;
+ public net.minecraft.world.level.Level.ExplosionInteraction basedEndCrystalExplosionEffect = net.minecraft.world.level.Level.ExplosionInteraction.BLOCK;
+ private void endCrystalSettings() {
+ if (PurpurConfig.version < 31) {
+ if ("DESTROY".equals(getString("blocks.end-crystal.baseless.explosion-effect", baselessEndCrystalExplosionEffect.name()))) {
+ set("blocks.end-crystal.baseless.explosion-effect", "BLOCK");
+ }
+ if ("DESTROY".equals(getString("blocks.end-crystal.base.explosion-effect", basedEndCrystalExplosionEffect.name()))) {
+ set("blocks.end-crystal.base.explosion-effect", "BLOCK");
+ }
+ }
+ baselessEndCrystalExplode = getBoolean("blocks.end-crystal.baseless.explode", baselessEndCrystalExplode);
+ baselessEndCrystalExplosionPower = getDouble("blocks.end-crystal.baseless.explosion-power", baselessEndCrystalExplosionPower);
+ baselessEndCrystalExplosionFire = getBoolean("blocks.end-crystal.baseless.explosion-fire", baselessEndCrystalExplosionFire);
+ try {
+ baselessEndCrystalExplosionEffect = net.minecraft.world.level.Level.ExplosionInteraction.valueOf(getString("blocks.end-crystal.baseless.explosion-effect", baselessEndCrystalExplosionEffect.name()));
+ } catch (IllegalArgumentException e) {
+ log(Level.SEVERE, "Unknown value for `blocks.end-crystal.baseless.explosion-effect`! Using default of `BLOCK`");
+ baselessEndCrystalExplosionEffect = net.minecraft.world.level.Level.ExplosionInteraction.BLOCK;
+ }
+ basedEndCrystalExplode = getBoolean("blocks.end-crystal.base.explode", basedEndCrystalExplode);
+ basedEndCrystalExplosionPower = getDouble("blocks.end-crystal.base.explosion-power", basedEndCrystalExplosionPower);
+ basedEndCrystalExplosionFire = getBoolean("blocks.end-crystal.base.explosion-fire", basedEndCrystalExplosionFire);
+ try {
+ basedEndCrystalExplosionEffect = net.minecraft.world.level.Level.ExplosionInteraction.valueOf(getString("blocks.end-crystal.base.explosion-effect", basedEndCrystalExplosionEffect.name()));
+ } catch (IllegalArgumentException e) {
+ log(Level.SEVERE, "Unknown value for `blocks.end-crystal.base.explosion-effect`! Using default of `BLOCK`");
+ basedEndCrystalExplosionEffect = net.minecraft.world.level.Level.ExplosionInteraction.BLOCK;
+ }
+ }
+
public boolean farmlandBypassMobGriefing = false;
public boolean farmlandGetsMoistFromBelow = false;
public boolean farmlandAlpha = false;

View File

@@ -1,66 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Sat, 20 Feb 2021 14:47:08 -0800
Subject: [PATCH] Configs for if Wither/Ender Dragon can ride vehicles
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
index 0d0f999ab361db9a839bc7e57bfeca21aed4c523..573ec75b5fed1c3d30aa9dc64cf3a8a77ddfbcae 100644
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
@@ -1204,6 +1204,7 @@ public class EnderDragon extends Mob implements Enemy {
@Override
protected boolean canRide(Entity entity) {
+ if (this.level().purpurConfig.enderDragonCanRideVehicles) return this.boardingCooldown <= 0; // Purpur
return false;
}
diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
index 6fedac6f92193d7031b6265f897d9688fd2c8780..8809b88dec7beffa569de6832f5b458116b143cc 100644
--- a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
+++ b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
@@ -739,6 +739,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
@Override
protected boolean canRide(Entity entity) {
+ if (this.level().purpurConfig.witherCanRideVehicles) return this.boardingCooldown <= 0; // Purpur
return false;
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 4c35cab67704690ce54f412ea145537171ba0ebf..caeaf92e383cb5aa7e2e2c053adc7aee391f38a7 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -965,6 +965,7 @@ public class PurpurWorldConfig {
public boolean enderDragonAlwaysDropsFullExp = false;
public boolean enderDragonBypassMobGriefing = false;
public boolean enderDragonTakeDamageFromWater = false;
+ public boolean enderDragonCanRideVehicles = false;
private void enderDragonSettings() {
enderDragonRidable = getBoolean("mobs.ender_dragon.ridable", enderDragonRidable);
enderDragonRidableInWater = getBoolean("mobs.ender_dragon.ridable-in-water", enderDragonRidableInWater);
@@ -983,6 +984,7 @@ public class PurpurWorldConfig {
enderDragonAlwaysDropsFullExp = getBoolean("mobs.ender_dragon.always-drop-full-exp", enderDragonAlwaysDropsFullExp);
enderDragonBypassMobGriefing = getBoolean("mobs.ender_dragon.bypass-mob-griefing", enderDragonBypassMobGriefing);
enderDragonTakeDamageFromWater = getBoolean("mobs.ender_dragon.takes-damage-from-water", enderDragonTakeDamageFromWater);
+ enderDragonCanRideVehicles = getBoolean("mobs.ender_dragon.can-ride-vehicles", enderDragonCanRideVehicles);
}
public boolean endermanRidable = false;
@@ -2265,6 +2267,7 @@ public class PurpurWorldConfig {
public int witherHealthRegenDelay = 20;
public boolean witherBypassMobGriefing = false;
public boolean witherTakeDamageFromWater = false;
+ public boolean witherCanRideVehicles = false;
private void witherSettings() {
witherRidable = getBoolean("mobs.wither.ridable", witherRidable);
witherRidableInWater = getBoolean("mobs.wither.ridable-in-water", witherRidableInWater);
@@ -2285,6 +2288,7 @@ public class PurpurWorldConfig {
witherHealthRegenDelay = getInt("mobs.wither.health-regen-delay", witherHealthRegenDelay);
witherBypassMobGriefing = getBoolean("mobs.wither.bypass-mob-griefing", witherBypassMobGriefing);
witherTakeDamageFromWater = getBoolean("mobs.wither.takes-damage-from-water", witherTakeDamageFromWater);
+ witherCanRideVehicles = getBoolean("mobs.wither.can-ride-vehicles", witherCanRideVehicles);
}
public boolean witherSkeletonRidable = false;

View File

@@ -1,176 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: JustDoom <justdoomdev@gmail.com>
Date: Fri, 5 Mar 2021 14:23:16 -0500
Subject: [PATCH] Dont run with scissors!
inspired by https://modrinth.com/mod/dont-run-with-scissors
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index bbec4b963ca4b0804bce0c4cde49e1e88c0ae9f0..b7f8499cabbd28c0679d0c775b009c9cdf53b5f8 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1654,6 +1654,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
this.player.tryResetCurrentImpulseContext();
}
+ // Purpur Start
+ if (this.player.level().purpurConfig.dontRunWithScissors && this.player.isSprinting() && !(this.player.level().purpurConfig.ignoreScissorsInWater && this.player.isInWater()) && !(this.player.level().purpurConfig.ignoreScissorsInLava && this.player.isInLava()) && (isScissor(this.player.getItemInHand(InteractionHand.MAIN_HAND)) || isScissor(this.player.getItemInHand(InteractionHand.OFF_HAND))) && (int) (Math.random() * 10) == 0) {
+ this.player.hurt(this.player.damageSources().scissors(), (float) this.player.level().purpurConfig.scissorsRunningDamage);
+ if (!org.purpurmc.purpur.PurpurConfig.dontRunWithScissors.isBlank()) this.player.sendActionBarMessage(org.purpurmc.purpur.PurpurConfig.dontRunWithScissors);
+ }
+ // Purpur End
+
this.player.checkMovementStatistics(this.player.getX() - d3, this.player.getY() - d4, this.player.getZ() - d5);
this.lastGoodX = this.player.getX();
this.lastGoodY = this.player.getY();
@@ -1681,6 +1688,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
}
}
+ // Purpur start
+ public boolean isScissor(ItemStack stack) {
+ if (!stack.is(Items.SHEARS)) return false;
+ net.minecraft.world.item.component.CustomModelData customModelData = stack.get(net.minecraft.core.component.DataComponents.CUSTOM_MODEL_DATA);
+ return customModelData == null || customModelData.value() == 0;
+ }
+ // Purpur end
+
// Paper start - optimise out extra getCubes
private boolean hasNewCollision(final ServerLevel world, final Entity entity, final AABB oldBox, final AABB newBox) {
final List<AABB> collisionsBB = new java.util.ArrayList<>();
diff --git a/src/main/java/net/minecraft/world/damagesource/CombatTracker.java b/src/main/java/net/minecraft/world/damagesource/CombatTracker.java
index 99a7e9eb75231c15bd8bb24fbb4e296bc9fdedff..a375d40ec6365ba8704ba3ece22dd5b2de9857b5 100644
--- a/src/main/java/net/minecraft/world/damagesource/CombatTracker.java
+++ b/src/main/java/net/minecraft/world/damagesource/CombatTracker.java
@@ -98,6 +98,11 @@ public class CombatTracker {
Component component = ComponentUtils.wrapInSquareBrackets(Component.translatable(string + ".link")).withStyle(INTENTIONAL_GAME_DESIGN_STYLE);
return Component.translatable(string + ".message", this.mob.getDisplayName(), component);
} else {
+ // Purpur start
+ if (damageSource.isScissors()) {
+ return damageSource.getLocalizedDeathMessage(org.purpurmc.purpur.PurpurConfig.deathMsgRunWithScissors, this.mob);
+ }
+ // Purpur end
return damageSource.getLocalizedDeathMessage(this.mob);
}
}
diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSource.java b/src/main/java/net/minecraft/world/damagesource/DamageSource.java
index c83e80ebdbbfb2d0e08561a44486a308d16f50af..aa65f4bf60172a2629daf6e15f7f48d29b250ee0 100644
--- a/src/main/java/net/minecraft/world/damagesource/DamageSource.java
+++ b/src/main/java/net/minecraft/world/damagesource/DamageSource.java
@@ -29,6 +29,7 @@ public class DamageSource {
private boolean sweep = false;
private boolean melting = false;
private boolean poison = false;
+ private boolean scissors = false; // Purpur
@Nullable
private Entity customEventDamager = null; // This field is a helper for when causing entity damage is not set by vanilla // Paper - fix DamageSource API
@@ -59,6 +60,17 @@ public class DamageSource {
return this.poison;
}
+ // Purpur start
+ public DamageSource scissors() {
+ this.scissors = true;
+ return this;
+ }
+
+ public boolean isScissors() {
+ return this.scissors;
+ }
+ // Purpur end
+
// Paper start - fix DamageSource API
@Nullable
public Entity getCustomEventDamager() {
@@ -117,6 +129,7 @@ public class DamageSource {
damageSource.sweep = this.isSweep();
damageSource.poison = this.isPoison();
damageSource.melting = this.isMelting();
+ damageSource.scissors = this.isScissors(); // Purpur
return damageSource;
}
// CraftBukkit end
diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSources.java b/src/main/java/net/minecraft/world/damagesource/DamageSources.java
index e34584e4780f343d6c946af5377088d53818e88e..da790aac3bd8981f351b7e241015ff42bd0da73b 100644
--- a/src/main/java/net/minecraft/world/damagesource/DamageSources.java
+++ b/src/main/java/net/minecraft/world/damagesource/DamageSources.java
@@ -45,11 +45,13 @@ public class DamageSources {
// CraftBukkit start
private final DamageSource melting;
private final DamageSource poison;
+ private final DamageSource scissors; // Purpur
public DamageSources(RegistryAccess registryManager) {
this.damageTypes = registryManager.registryOrThrow(Registries.DAMAGE_TYPE);
this.melting = this.source(DamageTypes.ON_FIRE).melting();
this.poison = this.source(DamageTypes.MAGIC).poison();
+ this.scissors = this.source(DamageTypes.MAGIC).scissors(); // Purpur
// CraftBukkit end
this.inFire = this.source(DamageTypes.IN_FIRE);
this.campfire = this.source(DamageTypes.CAMPFIRE);
@@ -99,6 +101,12 @@ public class DamageSources {
}
// CraftBukkit end
+ // Purpur start
+ public DamageSource scissors() {
+ return this.scissors;
+ }
+ // Purpur end
+
public DamageSource inFire() {
return this.inFire;
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index 2685a3e5e4d0a1559f2d28152bab73b8982362fd..6fcb2db92a38e862da288518ce34d16aa4b856e0 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -185,6 +185,7 @@ public class PurpurConfig {
public static String demoCommandOutput = "<green>%s has been shown the demo screen";
public static String pingCommandOutput = "<green>%s's ping is %sms";
public static String tpsbarCommandOutput = "<green>Tpsbar toggled <onoff> for <target>";
+ public static String dontRunWithScissors = "<red><italic>Don't run with scissors!";
private static void messages() {
cannotRideMob = getString("settings.messages.cannot-ride-mob", cannotRideMob);
afkBroadcastAway = getString("settings.messages.afk-broadcast-away", afkBroadcastAway);
@@ -196,6 +197,12 @@ public class PurpurConfig {
demoCommandOutput = getString("settings.messages.demo-command-output", demoCommandOutput);
pingCommandOutput = getString("settings.messages.ping-command-output", pingCommandOutput);
tpsbarCommandOutput = getString("settings.messages.tpsbar-command-output", tpsbarCommandOutput);
+ dontRunWithScissors = getString("settings.messages.dont-run-with-scissors", dontRunWithScissors);
+ }
+
+ public static String deathMsgRunWithScissors = "<player> slipped and fell on their shears";
+ private static void deathMessages() {
+ deathMsgRunWithScissors = getString("settings.messages.death-message.run-with-scissors", deathMsgRunWithScissors);
}
public static String serverModName = io.papermc.paper.ServerBuildInfo.buildInfo().brandName();
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index caeaf92e383cb5aa7e2e2c053adc7aee391f38a7..1cf04d5acd6a252762f643f5933f22846930c1a0 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -190,6 +190,10 @@ public class PurpurWorldConfig {
public List<Item> itemImmuneToExplosion = new ArrayList<>();
public List<Item> itemImmuneToFire = new ArrayList<>();
public List<Item> itemImmuneToLightning = new ArrayList<>();
+ public boolean dontRunWithScissors = false;
+ public boolean ignoreScissorsInWater = false;
+ public boolean ignoreScissorsInLava = false;
+ public double scissorsRunningDamage = 1D;
private void itemSettings() {
itemImmuneToCactus.clear();
getList("gameplay-mechanics.item.immune.cactus", new ArrayList<>()).forEach(key -> {
@@ -227,6 +231,10 @@ public class PurpurWorldConfig {
Item item = BuiltInRegistries.ITEM.get(ResourceLocation.parse(key.toString()));
if (item != Items.AIR) itemImmuneToLightning.add(item);
});
+ dontRunWithScissors = getBoolean("gameplay-mechanics.item.shears.damage-if-sprinting", dontRunWithScissors);
+ ignoreScissorsInWater = getBoolean("gameplay-mechanics.item.shears.ignore-in-water", ignoreScissorsInWater);
+ ignoreScissorsInLava = getBoolean("gameplay-mechanics.item.shears.ignore-in-lava", ignoreScissorsInLava);
+ scissorsRunningDamage = getDouble("gameplay-mechanics.item.shears.sprinting-damage", scissorsRunningDamage);
}
public double minecartMaxSpeed = 0.4D;

View File

@@ -1,56 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Fourmisain <8464472+Fourmisain@users.noreply.github.com>
Date: Fri, 5 Mar 2021 17:42:35 -0500
Subject: [PATCH] One Punch Man!
inspired by https://modrinth.com/mod/creative-one-punch
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 4f172f9a0ec61a10b0b1411b9d0eb82d49bd0c57..7a99319d6ac85fd794fef361dd6f8092b847c744 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -1441,6 +1441,24 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.stopSleeping();
}
+ // Purpur start
+ if (source.getEntity() instanceof net.minecraft.world.entity.player.Player player && source.getEntity().level().purpurConfig.creativeOnePunch && !source.is(DamageTypeTags.IS_PROJECTILE)) {
+ if (player.isCreative()) {
+ org.apache.commons.lang3.mutable.MutableDouble attackDamage = new org.apache.commons.lang3.mutable.MutableDouble();
+ player.getMainHandItem().forEachModifier(EquipmentSlot.MAINHAND, (attributeHolder, attributeModifier) -> {
+ if (attributeModifier.operation() == AttributeModifier.Operation.ADD_VALUE) {
+ attackDamage.addAndGet(attributeModifier.amount());
+ }
+ });
+
+ if (attackDamage.doubleValue() == 0.0D) {
+ // One punch!
+ amount = 9999F;
+ }
+ }
+ }
+ // Purpur end
+
this.noActionTime = 0;
float f1 = amount; final float originalAmount = f1; // Paper - revert to vanilla #hurt - OBFHELPER
boolean flag = amount > 0.0F && this.isDamageSourceBlocked(source); // Copied from below
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 1cf04d5acd6a252762f643f5933f22846930c1a0..a963ceb3b9ed41d36239c468ebc901e3d94e4768 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -337,6 +337,7 @@ public class PurpurWorldConfig {
public boolean teleportIfOutsideBorder = false;
public boolean totemOfUndyingWorksInInventory = false;
public boolean playerFixStuckPortal = false;
+ public boolean creativeOnePunch = false;
private void playerSettings() {
if (PurpurConfig.version < 19) {
boolean oldVal = getBoolean("gameplay-mechanics.player.idle-timeout.mods-target", idleTimeoutTargetPlayer);
@@ -353,6 +354,7 @@ public class PurpurWorldConfig {
teleportIfOutsideBorder = getBoolean("gameplay-mechanics.player.teleport-if-outside-border", teleportIfOutsideBorder);
totemOfUndyingWorksInInventory = getBoolean("gameplay-mechanics.player.totem-of-undying-works-in-inventory", totemOfUndyingWorksInInventory);
playerFixStuckPortal = getBoolean("gameplay-mechanics.player.fix-stuck-in-portal", playerFixStuckPortal);
+ creativeOnePunch = getBoolean("gameplay-mechanics.player.one-punch-in-creative", creativeOnePunch);
}
public boolean silkTouchEnabled = false;

View File

@@ -1,70 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Sun, 7 Mar 2021 19:08:16 -0500
Subject: [PATCH] Configurable Ender Pearl cooldown, damage, and Endermite RNG
- Survival and Creative Cooldown speed
- Damage dealt on pearl usage
- Endermite spawn chance
diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
index 1aa5e57a4e6a4be60514d8808a2e6c973d93e798..0d2a18190c46f34277a714570267bcc33507ff10 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
@@ -77,7 +77,7 @@ public class ThrownEnderpearl extends ThrowableItemProjectile {
return;
}
// CraftBukkit end
- if (this.random.nextFloat() < 0.05F && worldserver.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) {
+ if (this.random.nextFloat() < this.level().purpurConfig.enderPearlEndermiteChance && worldserver.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) { // Purpur
Endermite entityendermite = (Endermite) EntityType.ENDERMITE.create(worldserver);
if (entityendermite != null) {
@@ -89,7 +89,7 @@ public class ThrownEnderpearl extends ThrowableItemProjectile {
// entity.changeDimension(new DimensionTransition(worldserver, this.position(), entity.getDeltaMovement(), entity.getYRot(), entity.getXRot(), DimensionTransition.DO_NOTHING)); // CraftBukkit - moved up
entity.resetFallDistance();
entityplayer.resetCurrentImpulseContext();
- entity.hurt(this.damageSources().fall().customEventDamager(this), 5.0F); // CraftBukkit // Paper - fix DamageSource API
+ entity.hurt(this.damageSources().fall().customEventDamager(this), this.level().purpurConfig.enderPearlDamage); // CraftBukkit // Paper - fix DamageSource API // Purpur
this.playSound(worldserver, this.position());
}
} else {
diff --git a/src/main/java/net/minecraft/world/item/EnderpearlItem.java b/src/main/java/net/minecraft/world/item/EnderpearlItem.java
index 20a91d798d31a71b3c05efa2cc5bda55494e26cc..fc62754f93bd11a10c28b8b7b116e9fff70a5c7b 100644
--- a/src/main/java/net/minecraft/world/item/EnderpearlItem.java
+++ b/src/main/java/net/minecraft/world/item/EnderpearlItem.java
@@ -36,7 +36,7 @@ public class EnderpearlItem extends Item {
world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENDER_PEARL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (net.minecraft.world.entity.Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F));
user.awardStat(Stats.ITEM_USED.get(this));
- user.getCooldowns().addCooldown(this, 20);
+ user.getCooldowns().addCooldown(this, user.getAbilities().instabuild ? world.purpurConfig.enderPearlCooldownCreative : world.purpurConfig.enderPearlCooldown); // Purpur
} else {
// Paper end - PlayerLaunchProjectileEvent
if (user instanceof net.minecraft.server.level.ServerPlayer) {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index a963ceb3b9ed41d36239c468ebc901e3d94e4768..70d5b6e46dce5f1e22f7bc365fd01e6da8a7c591 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -194,6 +194,10 @@ public class PurpurWorldConfig {
public boolean ignoreScissorsInWater = false;
public boolean ignoreScissorsInLava = false;
public double scissorsRunningDamage = 1D;
+ public float enderPearlDamage = 5.0F;
+ public int enderPearlCooldown = 20;
+ public int enderPearlCooldownCreative = 20;
+ public float enderPearlEndermiteChance = 0.05F;
private void itemSettings() {
itemImmuneToCactus.clear();
getList("gameplay-mechanics.item.immune.cactus", new ArrayList<>()).forEach(key -> {
@@ -235,6 +239,10 @@ public class PurpurWorldConfig {
ignoreScissorsInWater = getBoolean("gameplay-mechanics.item.shears.ignore-in-water", ignoreScissorsInWater);
ignoreScissorsInLava = getBoolean("gameplay-mechanics.item.shears.ignore-in-lava", ignoreScissorsInLava);
scissorsRunningDamage = getDouble("gameplay-mechanics.item.shears.sprinting-damage", scissorsRunningDamage);
+ enderPearlDamage = (float) getDouble("gameplay-mechanics.item.ender-pearl.damage", enderPearlDamage);
+ enderPearlCooldown = getInt("gameplay-mechanics.item.ender-pearl.cooldown", enderPearlCooldown);
+ enderPearlCooldownCreative = getInt("gameplay-mechanics.item.ender-pearl.creative-cooldown", enderPearlCooldownCreative);
+ enderPearlEndermiteChance = (float) getDouble("gameplay-mechanics.item.ender-pearl.endermite-spawn-chance", enderPearlEndermiteChance);
}
public double minecartMaxSpeed = 0.4D;

View File

@@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Mon, 8 Mar 2021 16:46:54 -0500
Subject: [PATCH] Config to ignore nearby mobs when sleeping
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index d677c1308412e5a12046225ce2449af136b7665f..513ab3d7d3ff4fe0a5c9c609ca752357b2d8055a 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -1529,7 +1529,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
return entitymonster.isPreventingPlayerRest(this);
});
- if (!list.isEmpty()) {
+ if (!this.level().purpurConfig.playerSleepNearMonsters && !list.isEmpty()) { // Purpur
return Either.left(net.minecraft.world.entity.player.Player.BedSleepingProblem.NOT_SAFE);
}
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 70d5b6e46dce5f1e22f7bc365fd01e6da8a7c591..4293d2a343fa9ac2dec503371c2fb62311f8e77f 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -346,6 +346,7 @@ public class PurpurWorldConfig {
public boolean totemOfUndyingWorksInInventory = false;
public boolean playerFixStuckPortal = false;
public boolean creativeOnePunch = false;
+ public boolean playerSleepNearMonsters = false;
private void playerSettings() {
if (PurpurConfig.version < 19) {
boolean oldVal = getBoolean("gameplay-mechanics.player.idle-timeout.mods-target", idleTimeoutTargetPlayer);
@@ -363,6 +364,7 @@ public class PurpurWorldConfig {
totemOfUndyingWorksInInventory = getBoolean("gameplay-mechanics.player.totem-of-undying-works-in-inventory", totemOfUndyingWorksInInventory);
playerFixStuckPortal = getBoolean("gameplay-mechanics.player.fix-stuck-in-portal", playerFixStuckPortal);
creativeOnePunch = getBoolean("gameplay-mechanics.player.one-punch-in-creative", creativeOnePunch);
+ playerSleepNearMonsters = getBoolean("gameplay-mechanics.player.sleep-ignore-nearby-mobs", playerSleepNearMonsters);
}
public boolean silkTouchEnabled = false;

View File

@@ -1,79 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Tue, 9 Mar 2021 16:10:39 -0500
Subject: [PATCH] Add back player spawned endermite API
diff --git a/src/main/java/net/minecraft/world/entity/monster/Endermite.java b/src/main/java/net/minecraft/world/entity/monster/Endermite.java
index dd73278cea317280b88c3290dfcc052866c9ec52..13c41b561683231a369affd309a28509c8ce5c93 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Endermite.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Endermite.java
@@ -32,6 +32,7 @@ public class Endermite extends Monster {
private static final int MAX_LIFE = 2400;
public int life;
+ private boolean isPlayerSpawned; // Purpur
public Endermite(EntityType<? extends Endermite> type, Level world) {
super(type, world);
@@ -66,6 +67,14 @@ public class Endermite extends Monster {
return this.level().purpurConfig.endermiteTakeDamageFromWater;
}
+ public boolean isPlayerSpawned() {
+ return this.isPlayerSpawned;
+ }
+
+ public void setPlayerSpawned(boolean playerSpawned) {
+ this.isPlayerSpawned = playerSpawned;
+ }
+
@Override
protected void registerGoals() {
this.goalSelector.addGoal(1, new FloatGoal(this));
@@ -113,12 +122,14 @@ public class Endermite extends Monster {
public void readAdditionalSaveData(CompoundTag nbt) {
super.readAdditionalSaveData(nbt);
this.life = nbt.getInt("Lifetime");
+ this.isPlayerSpawned = nbt.getBoolean("PlayerSpawned"); // Purpur
}
@Override
public void addAdditionalSaveData(CompoundTag nbt) {
super.addAdditionalSaveData(nbt);
nbt.putInt("Lifetime", this.life);
+ nbt.putBoolean("PlayerSpawned", this.isPlayerSpawned); // Purpur
}
@Override
diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
index 0d2a18190c46f34277a714570267bcc33507ff10..334fa781e94d195c13dd78cdbe8f43b4b126ebd0 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
@@ -81,6 +81,7 @@ public class ThrownEnderpearl extends ThrowableItemProjectile {
Endermite entityendermite = (Endermite) EntityType.ENDERMITE.create(worldserver);
if (entityendermite != null) {
+ entityendermite.setPlayerSpawned(true); // Purpur
entityendermite.moveTo(entity.getX(), entity.getY(), entity.getZ(), entity.getYRot(), entity.getXRot());
worldserver.addFreshEntity(entityendermite, CreatureSpawnEvent.SpawnReason.ENDER_PEARL);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEndermite.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEndermite.java
index d657fd2c507a5b215aeab0a5f3e9c2ee892a27c8..985e9ec21c60a1f47973bd5fc53b96a6f9b7d04a 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEndermite.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEndermite.java
@@ -21,12 +21,12 @@ public class CraftEndermite extends CraftMonster implements Endermite {
@Override
public boolean isPlayerSpawned() {
- return false;
+ return getHandle().isPlayerSpawned(); // Purpur
}
@Override
public void setPlayerSpawned(boolean playerSpawned) {
- // Nop
+ getHandle().setPlayerSpawned(playerSpawned); // Purpur
}
// Paper start
@Override

View File

@@ -1,51 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Tue, 9 Mar 2021 16:10:39 -0500
Subject: [PATCH] Config Enderman aggressiveness towards Endermites
diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
index d4360a62cc2514dafc02749e49674213db65cc85..22583cdb173862b021c9701d26171ca337796557 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
@@ -132,7 +132,7 @@ public class EnderMan extends Monster implements NeutralMob {
this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur
this.targetSelector.addGoal(1, new EnderMan.EndermanLookForPlayerGoal(this, this::isAngryAt));
this.targetSelector.addGoal(2, new HurtByTargetGoal(this, new Class[0]));
- this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Endermite.class, true, false));
+ this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Endermite.class, 10, true, false, (entityliving) -> entityliving.level().purpurConfig.endermanAggroEndermites && entityliving instanceof Endermite endermite && (!entityliving.level().purpurConfig.endermanAggroEndermitesOnlyIfPlayerSpawned || endermite.isPlayerSpawned()))); // Purpur
this.targetSelector.addGoal(4, new ResetUniversalAngerTargetGoal<>(this, false));
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 4293d2a343fa9ac2dec503371c2fb62311f8e77f..9dd087d34438b7685e50d4574e3cb58c09bdf9c5 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1016,6 +1016,8 @@ public class PurpurWorldConfig {
public boolean endermanDespawnEvenWithBlock = false;
public boolean endermanBypassMobGriefing = false;
public boolean endermanTakeDamageFromWater = true;
+ public boolean endermanAggroEndermites = true;
+ public boolean endermanAggroEndermitesOnlyIfPlayerSpawned = false;
private void endermanSettings() {
endermanRidable = getBoolean("mobs.enderman.ridable", endermanRidable);
endermanRidableInWater = getBoolean("mobs.enderman.ridable-in-water", endermanRidableInWater);
@@ -1025,12 +1027,18 @@ public class PurpurWorldConfig {
set("mobs.enderman.attributes.max-health", null);
set("mobs.enderman.attributes.max_health", oldValue);
}
+ if (PurpurConfig.version < 15) {
+ // remove old option
+ set("mobs.enderman.aggressive-towards-spawned-endermites", null);
+ }
endermanMaxHealth = getDouble("mobs.enderman.attributes.max_health", endermanMaxHealth);
endermanScale = Mth.clamp(getDouble("mobs.enderman.attributes.scale", endermanScale), 0.0625D, 16.0D);
endermanAllowGriefing = getBoolean("mobs.enderman.allow-griefing", endermanAllowGriefing);
endermanDespawnEvenWithBlock = getBoolean("mobs.enderman.can-despawn-with-held-block", endermanDespawnEvenWithBlock);
endermanBypassMobGriefing = getBoolean("mobs.enderman.bypass-mob-griefing", endermanBypassMobGriefing);
endermanTakeDamageFromWater = getBoolean("mobs.enderman.takes-damage-from-water", endermanTakeDamageFromWater);
+ endermanAggroEndermites = getBoolean("mobs.enderman.aggressive-towards-endermites", endermanAggroEndermites);
+ endermanAggroEndermitesOnlyIfPlayerSpawned = getBoolean("mobs.enderman.aggressive-towards-endermites-only-spawned-by-player-thrown-ender-pearls", endermanAggroEndermitesOnlyIfPlayerSpawned);
}
public boolean endermiteRidable = false;

View File

@@ -1,43 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Tue, 9 Mar 2021 16:16:01 -0500
Subject: [PATCH] Config to ignore Dragon Head wearers and stare aggro
Prevents Enderman from becoming aggresive towards players that are wearing a Dragon Head.
Adds functionality to a useless item!
diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
index 22583cdb173862b021c9701d26171ca337796557..65c7bf88071dda62034d71b6a83caedd49d0902a 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
@@ -269,7 +269,7 @@ public class EnderMan extends Monster implements NeutralMob {
// Paper end - EndermanAttackPlayerEvent
ItemStack itemstack = (ItemStack) player.getInventory().armor.get(3);
- if (itemstack.is(Blocks.CARVED_PUMPKIN.asItem())) {
+ if (this.level().purpurConfig.endermanDisableStareAggro || itemstack.is(Blocks.CARVED_PUMPKIN.asItem()) || (this.level().purpurConfig.endermanIgnorePlayerDragonHead && itemstack.is(net.minecraft.world.item.Items.DRAGON_HEAD))) { // Purpur
return false;
} else {
Vec3 vec3d = player.getViewVector(1.0F).normalize();
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 9dd087d34438b7685e50d4574e3cb58c09bdf9c5..5902f7c6a74723c07892abbefbf7d2daf5e66271 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1018,6 +1018,8 @@ public class PurpurWorldConfig {
public boolean endermanTakeDamageFromWater = true;
public boolean endermanAggroEndermites = true;
public boolean endermanAggroEndermitesOnlyIfPlayerSpawned = false;
+ public boolean endermanIgnorePlayerDragonHead = false;
+ public boolean endermanDisableStareAggro = false;
private void endermanSettings() {
endermanRidable = getBoolean("mobs.enderman.ridable", endermanRidable);
endermanRidableInWater = getBoolean("mobs.enderman.ridable-in-water", endermanRidableInWater);
@@ -1039,6 +1041,8 @@ public class PurpurWorldConfig {
endermanTakeDamageFromWater = getBoolean("mobs.enderman.takes-damage-from-water", endermanTakeDamageFromWater);
endermanAggroEndermites = getBoolean("mobs.enderman.aggressive-towards-endermites", endermanAggroEndermites);
endermanAggroEndermitesOnlyIfPlayerSpawned = getBoolean("mobs.enderman.aggressive-towards-endermites-only-spawned-by-player-thrown-ender-pearls", endermanAggroEndermitesOnlyIfPlayerSpawned);
+ endermanIgnorePlayerDragonHead = getBoolean("mobs.enderman.ignore-players-wearing-dragon-head", endermanIgnorePlayerDragonHead);
+ endermanDisableStareAggro = getBoolean("mobs.enderman.disable-player-stare-aggression", endermanDisableStareAggro);
}
public boolean endermiteRidable = false;

View File

@@ -1,57 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Mon, 15 Mar 2021 03:52:17 -0500
Subject: [PATCH] Tick fluids config
diff --git a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
index 84623c632d8c2f0fa7ec939c711316d757117d23..1851035b9fdcc076442d0699567a3b020e6425d6 100644
--- a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
@@ -137,7 +137,7 @@ public class LiquidBlock extends Block implements BucketPickup {
@Override
protected void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) {
- if (this.shouldSpreadLiquid(world, pos, state)) {
+ if (world.purpurConfig.tickFluids && this.shouldSpreadLiquid(world, pos, state)) { // Purpur
world.scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper - Configurable speed for water flowing over lava
}
@@ -165,7 +165,7 @@ public class LiquidBlock extends Block implements BucketPickup {
@Override
protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
- if (state.getFluidState().isSource() || neighborState.getFluidState().isSource()) {
+ if (world.getMinecraftWorld().purpurConfig.tickFluids && state.getFluidState().isSource() || neighborState.getFluidState().isSource()) { // Purpur
world.scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay(world));
}
@@ -174,7 +174,7 @@ public class LiquidBlock extends Block implements BucketPickup {
@Override
protected void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) {
- if (this.shouldSpreadLiquid(world, pos, state)) {
+ if (world.purpurConfig.tickFluids && this.shouldSpreadLiquid(world, pos, state)) { // Purpur
world.scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper - Configurable speed for water flowing over lava
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 5902f7c6a74723c07892abbefbf7d2daf5e66271..4e7ea1f1b4413c929ed4066e9dd213a9fc9b4b35 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -132,6 +132,7 @@ public class PurpurWorldConfig {
public boolean noteBlockIgnoreAbove = false;
public boolean persistentDroppableEntityDisplayNames = true;
public boolean projectilesBypassMobGriefing = false;
+ public boolean tickFluids = true;
public double tridentLoyaltyVoidReturnHeight = 0.0D;
public int raidCooldownSeconds = 0;
public int animalBreedingCooldownSeconds = 0;
@@ -151,6 +152,7 @@ public class PurpurWorldConfig {
noteBlockIgnoreAbove = getBoolean("gameplay-mechanics.note-block-ignore-above", noteBlockIgnoreAbove);
persistentDroppableEntityDisplayNames = getBoolean("gameplay-mechanics.persistent-droppable-entity-display-names", persistentDroppableEntityDisplayNames);
projectilesBypassMobGriefing = getBoolean("gameplay-mechanics.projectiles-bypass-mob-griefing", projectilesBypassMobGriefing);
+ tickFluids = getBoolean("gameplay-mechanics.tick-fluids", tickFluids);
tridentLoyaltyVoidReturnHeight = getDouble("gameplay-mechanics.trident-loyalty-void-return-height", tridentLoyaltyVoidReturnHeight);
raidCooldownSeconds = getInt("gameplay-mechanics.raid-cooldown-seconds", raidCooldownSeconds);
animalBreedingCooldownSeconds = getInt("gameplay-mechanics.animal-breeding-cooldown-seconds", animalBreedingCooldownSeconds);

View File

@@ -1,53 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Wed, 17 Mar 2021 10:12:53 -0400
Subject: [PATCH] Config to disable Llama caravans
Disables the mechanic where llamas follow leashed llamas.
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/LlamaFollowCaravanGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/LlamaFollowCaravanGoal.java
index eb0faf58fa1a408f294fc62120b140def97f998d..0f4f546cd0eda4bd82b47446ae23ac32da8a9556 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/LlamaFollowCaravanGoal.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/LlamaFollowCaravanGoal.java
@@ -22,7 +22,7 @@ public class LlamaFollowCaravanGoal extends Goal {
@Override
public boolean canUse() {
- if (!this.llama.shouldJoinCaravan) return false; // Purpur
+ if (!this.llama.level().purpurConfig.llamaJoinCaravans || !this.llama.shouldJoinCaravan) return false; // Purpur
if (!this.llama.isLeashed() && !this.llama.inCaravan()) {
List<Entity> list = this.llama.level().getEntities(this.llama, this.llama.getBoundingBox().inflate(9.0, 4.0, 9.0), entity -> {
EntityType<?> entityType = entity.getType();
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java
index 96f1eba4a356e131a8f3c689bedc9eb8821e1a72..8edfc34a17d8c05cfa2928738306c1abc1743cc5 100644
--- a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java
@@ -477,7 +477,7 @@ public class Llama extends AbstractChestedHorse implements VariantHolder<Llama.V
}
public void joinCaravan(Llama llama) {
- if (!shouldJoinCaravan || !new org.purpurmc.purpur.event.entity.LlamaJoinCaravanEvent((org.bukkit.entity.Llama) getBukkitEntity(), (org.bukkit.entity.Llama) llama.getBukkitEntity()).callEvent()) return; // Purpur
+ if (!this.level().purpurConfig.llamaJoinCaravans || !shouldJoinCaravan || !new org.purpurmc.purpur.event.entity.LlamaJoinCaravanEvent((org.bukkit.entity.Llama) getBukkitEntity(), (org.bukkit.entity.Llama) llama.getBukkitEntity()).callEvent()) return; // Purpur
this.caravanHead = llama;
this.caravanHead.caravanTail = this;
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 4e7ea1f1b4413c929ed4066e9dd213a9fc9b4b35..1a690b72b8d149a3c9338abc83069fcab4ff0ccc 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1375,6 +1375,7 @@ public class PurpurWorldConfig {
public double llamaMovementSpeedMax = 0.175D;
public int llamaBreedingTicks = 6000;
public boolean llamaTakeDamageFromWater = false;
+ public boolean llamaJoinCaravans = true;
private void llamaSettings() {
llamaRidable = getBoolean("mobs.llama.ridable", llamaRidable);
llamaRidableInWater = getBoolean("mobs.llama.ridable-in-water", llamaRidableInWater);
@@ -1394,6 +1395,7 @@ public class PurpurWorldConfig {
llamaMovementSpeedMax = getDouble("mobs.llama.attributes.movement_speed.max", llamaMovementSpeedMax);
llamaBreedingTicks = getInt("mobs.llama.breeding-delay-ticks", llamaBreedingTicks);
llamaTakeDamageFromWater = getBoolean("mobs.llama.takes-damage-from-water", llamaTakeDamageFromWater);
+ llamaJoinCaravans = getBoolean("mobs.llama.join-caravans", llamaJoinCaravans);
}
public boolean magmaCubeRidable = false;

View File

@@ -1,73 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Tue, 16 Mar 2021 19:50:58 -0400
Subject: [PATCH] Config to make Creepers explode on death
Creepers exploded after being killed in the alpha days. This brings that back.
diff --git a/src/main/java/net/minecraft/world/entity/monster/Creeper.java b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
index 1ce1cf48624d8273dccc571ee37a08c06951acad..902191001a7302872ff661564fb6389457abaa9c 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
@@ -66,6 +66,7 @@ public class Creeper extends Monster implements PowerableMob {
private int prevSpacebarCharge = 0;
private int powerToggleDelay = 0;
// Purpur end
+ private boolean exploding = false; // Purpur - Config to make Creepers explode on death
public Creeper(EntityType<? extends Creeper> type, Level world) {
super(type, world);
@@ -271,6 +272,16 @@ public class Creeper extends Monster implements PowerableMob {
return this.level().purpurConfig.creeperTakeDamageFromWater;
}
+ // Purpur start - Config to make Creepers explode on death
+ @Override
+ protected org.bukkit.event.entity.EntityDeathEvent dropAllDeathLoot(ServerLevel world, DamageSource damageSource) {
+ if (!this.exploding && this.level().purpurConfig.creeperExplodeWhenKilled && damageSource.getEntity() instanceof net.minecraft.server.level.ServerPlayer) {
+ this.explodeCreeper();
+ }
+ return super.dropAllDeathLoot(world, damageSource);
+ }
+ // Purpur end - Config to make Creepers explode on death
+
@Override
protected SoundEvent getHurtSound(DamageSource source) {
return SoundEvents.CREEPER_HURT;
@@ -359,6 +370,8 @@ public class Creeper extends Monster implements PowerableMob {
}
public void explodeCreeper() {
+ this.exploding = true; // Purpur - Config to make Creepers explode on death
+
if (!this.level().isClientSide) {
float f = this.isPowered() ? 2.0F : 1.0F;
@@ -379,6 +392,7 @@ public class Creeper extends Monster implements PowerableMob {
// CraftBukkit end
}
+ this.exploding = false; // Purpur - Config to make Creepers explode on death
}
private void spawnLingeringCloud() {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 1a690b72b8d149a3c9338abc83069fcab4ff0ccc..d861652c9495ad58b24124c495b3041e071ad549 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -862,6 +862,7 @@ public class PurpurWorldConfig {
public boolean creeperAllowGriefing = true;
public boolean creeperBypassMobGriefing = false;
public boolean creeperTakeDamageFromWater = false;
+ public boolean creeperExplodeWhenKilled = false;
private void creeperSettings() {
creeperRidable = getBoolean("mobs.creeper.ridable", creeperRidable);
creeperRidableInWater = getBoolean("mobs.creeper.ridable-in-water", creeperRidableInWater);
@@ -877,6 +878,7 @@ public class PurpurWorldConfig {
creeperAllowGriefing = getBoolean("mobs.creeper.allow-griefing", creeperAllowGriefing);
creeperBypassMobGriefing = getBoolean("mobs.creeper.bypass-mob-griefing", creeperBypassMobGriefing);
creeperTakeDamageFromWater = getBoolean("mobs.creeper.takes-damage-from-water", creeperTakeDamageFromWater);
+ creeperExplodeWhenKilled = getBoolean("mobs.creeper.explode-when-killed", creeperExplodeWhenKilled);
}
public boolean dolphinRidable = false;

View File

@@ -1,68 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Wed, 17 Mar 2021 14:54:43 -0500
Subject: [PATCH] Configurable ravager griefable blocks list
diff --git a/src/main/java/net/minecraft/world/entity/monster/Ravager.java b/src/main/java/net/minecraft/world/entity/monster/Ravager.java
index 30aee88ab5fd1e849780903083c2c95dd4e392aa..6c52629a304e48d6f9ea04ac52c8b1cae00df53a 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Ravager.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Ravager.java
@@ -185,7 +185,7 @@ public class Ravager extends Raider {
BlockState iblockdata = this.level().getBlockState(blockposition);
Block block = iblockdata.getBlock();
- if (block instanceof LeavesBlock) {
+ if (this.level().purpurConfig.ravagerGriefableBlocks.contains(block)) { // Purpur
// CraftBukkit start
if (!CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, iblockdata.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state
continue;
diff --git a/src/main/java/net/minecraft/world/level/block/CropBlock.java b/src/main/java/net/minecraft/world/level/block/CropBlock.java
index 2af4c365743b2956939335512f74e0a1d84298f7..a69e7e8da81bd13578d230cc1e3f0f900817cbfd 100644
--- a/src/main/java/net/minecraft/world/level/block/CropBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/CropBlock.java
@@ -179,7 +179,7 @@ public class CropBlock extends BushBlock implements BonemealableBlock {
@Override
protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
- if (entity instanceof Ravager && CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), (!world.purpurConfig.ravagerBypassMobGriefing && !world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)))) { // CraftBukkit // Purpur
+ if (entity instanceof Ravager && world.purpurConfig.ravagerGriefableBlocks.contains(world.getBlockState(pos).getBlock()) && CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), (!world.purpurConfig.ravagerBypassMobGriefing && !world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)))) { // CraftBukkit // Purpur
world.destroyBlock(pos, true, entity);
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index d861652c9495ad58b24124c495b3041e071ad549..7f2a5c5720bd7f5e176a58d2369a4ffbd81ca138 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -1770,6 +1770,7 @@ public class PurpurWorldConfig {
public double ravagerScale = 1.0D;
public boolean ravagerBypassMobGriefing = false;
public boolean ravagerTakeDamageFromWater = false;
+ public List<Block> ravagerGriefableBlocks = new ArrayList<>();
private void ravagerSettings() {
ravagerRidable = getBoolean("mobs.ravager.ridable", ravagerRidable);
ravagerRidableInWater = getBoolean("mobs.ravager.ridable-in-water", ravagerRidableInWater);
@@ -1783,6 +1784,23 @@ public class PurpurWorldConfig {
ravagerScale = Mth.clamp(getDouble("mobs.ravager.attributes.scale", ravagerScale), 0.0625D, 16.0D);
ravagerBypassMobGriefing = getBoolean("mobs.ravager.bypass-mob-griefing", ravagerBypassMobGriefing);
ravagerTakeDamageFromWater = getBoolean("mobs.ravager.takes-damage-from-water", ravagerTakeDamageFromWater);
+ getList("mobs.ravager.griefable-blocks", new ArrayList<String>(){{
+ add("minecraft:oak_leaves");
+ add("minecraft:spruce_leaves");
+ add("minecraft:birch_leaves");
+ add("minecraft:jungle_leaves");
+ add("minecraft:acacia_leaves");
+ add("minecraft:dark_oak_leaves");
+ add("minecraft:beetroots");
+ add("minecraft:carrots");
+ add("minecraft:potatoes");
+ add("minecraft:wheat");
+ }}).forEach(key -> {
+ Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(key.toString()));
+ if (!block.defaultBlockState().isAir()) {
+ ravagerGriefableBlocks.add(block);
+ }
+ });
}
public boolean salmonRidable = false;

View File

@@ -1,104 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Sun, 7 May 2023 22:26:59 -0700
Subject: [PATCH] Sneak to bulk process composter
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
index ee9e4521079137d7b72194e8789810e7a89b8e75..09ab1904ea9c587f365513150dafe434a0b56ccf 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
@@ -577,7 +577,7 @@ public class ServerPlayerGameMode {
ItemStack itemstack1 = stack.copy();
InteractionResult enuminteractionresult;
- if (!flag1) {
+ if (!flag1 || (player.level().purpurConfig.composterBulkProcess && iblockdata.is(Blocks.COMPOSTER))) { // Purpur
ItemInteractionResult iteminteractionresult = iblockdata.useItemOn(player.getItemInHand(hand), world, player, hand, hitResult);
if (iteminteractionresult.consumesAction()) {
diff --git a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java
index d3d12f9114173f4971f95d7ef895a4374705bd3f..f34159f8d6c51af2341bf49db0d6d6f0417919cf 100644
--- a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java
@@ -237,18 +237,27 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder {
int i = (Integer) state.getValue(ComposterBlock.LEVEL);
if (i < 8 && ComposterBlock.COMPOSTABLES.containsKey(stack.getItem())) {
- if (i < 7 && !world.isClientSide) {
- BlockState iblockdata1 = ComposterBlock.addItem(player, state, world, pos, stack);
- // Paper start - handle cancelled events
- if (iblockdata1 == null) {
- return ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION;
- }
- // Paper end
-
- world.levelEvent(1500, pos, state != iblockdata1 ? 1 : 0);
- player.awardStat(Stats.ITEM_USED.get(stack.getItem()));
- stack.consume(1, player);
+ // Purpur start - sneak to bulk process composter
+ BlockState newState = process(i, player, state, world, pos, stack);
+ if (newState == null) {
+ return ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION;
}
+ if (world.purpurConfig.composterBulkProcess && player.isShiftKeyDown() && newState != state) {
+ BlockState oldState;
+ int oldCount, newCount, oldLevel, newLevel;
+ do {
+ oldState = newState;
+ oldCount = stack.getCount();
+ oldLevel = oldState.getValue(ComposterBlock.LEVEL);
+ newState = process(oldLevel, player, oldState, world, pos, stack);
+ if (newState == null) {
+ return ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION;
+ }
+ newCount = stack.getCount();
+ newLevel = newState.getValue(ComposterBlock.LEVEL);
+ } while (newCount > 0 && (newCount != oldCount || newLevel != oldLevel || newState != oldState));
+ }
+ // Purpur end
return ItemInteractionResult.sidedSuccess(world.isClientSide);
} else {
@@ -256,6 +265,25 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder {
}
}
+ // Purpur start - sneak to bulk process composter
+ private static @Nullable BlockState process(int level, Player player, BlockState state, Level world, BlockPos pos, ItemStack stack) {
+ if (level < 7 && !world.isClientSide) {
+ BlockState iblockdata1 = ComposterBlock.addItem(player, state, world, pos, stack);
+ // Paper start - handle cancelled events
+ if (iblockdata1 == null) {
+ return null;
+ }
+ // Paper end
+
+ world.levelEvent(1500, pos, state != iblockdata1 ? 1 : 0);
+ player.awardStat(Stats.ITEM_USED.get(stack.getItem()));
+ stack.consume(1, player);
+ return iblockdata1;
+ }
+ return state;
+ }
+ // Purpur end
+
@Override
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) {
int i = (Integer) state.getValue(ComposterBlock.LEVEL);
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 7f2a5c5720bd7f5e176a58d2369a4ffbd81ca138..b1d81d3877c207ec711f8e796f2b12e6febb8eba 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -439,6 +439,11 @@ public class PurpurWorldConfig {
chestOpenWithBlockOnTop = getBoolean("blocks.chest.open-with-solid-block-on-top", chestOpenWithBlockOnTop);
}
+ public boolean composterBulkProcess = false;
+ private void composterSettings() {
+ composterBulkProcess = getBoolean("blocks.composter.sneak-to-bulk-process", composterBulkProcess);
+ }
+
public boolean dispenserApplyCursedArmor = true;
public boolean dispenserPlaceAnvils = false;
private void dispenserSettings() {

View File

@@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ben Kerllenevich <ben@omega24.dev>
Date: Thu, 18 Mar 2021 06:22:40 -0400
Subject: [PATCH] Config for skipping night
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index e077c6cb1880ee19e696d2430b07d1101e330919..40a5107d37e908d13bd0307fc41d9a6e3faf1217 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -661,7 +661,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
int i = this.getGameRules().getInt(GameRules.RULE_PLAYERS_SLEEPING_PERCENTAGE);
long j;
- if (this.sleepStatus.areEnoughSleeping(i) && this.sleepStatus.areEnoughDeepSleeping(i, this.players)) {
+ if (this.purpurConfig.playersSkipNight && this.sleepStatus.areEnoughSleeping(i) && this.sleepStatus.areEnoughDeepSleeping(i, this.players)) {
// CraftBukkit start
j = this.levelData.getDayTime() + 24000L;
TimeSkipEvent event = new TimeSkipEvent(this.getWorld(), TimeSkipEvent.SkipReason.NIGHT_SKIP, (j - j % 24000L) - this.getDayTime());
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index b1d81d3877c207ec711f8e796f2b12e6febb8eba..dbacc159567dea21653148a4e9d9dbf78c8139f7 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -349,6 +349,7 @@ public class PurpurWorldConfig {
public boolean playerFixStuckPortal = false;
public boolean creativeOnePunch = false;
public boolean playerSleepNearMonsters = false;
+ public boolean playersSkipNight = true;
private void playerSettings() {
if (PurpurConfig.version < 19) {
boolean oldVal = getBoolean("gameplay-mechanics.player.idle-timeout.mods-target", idleTimeoutTargetPlayer);
@@ -367,6 +368,7 @@ public class PurpurWorldConfig {
playerFixStuckPortal = getBoolean("gameplay-mechanics.player.fix-stuck-in-portal", playerFixStuckPortal);
creativeOnePunch = getBoolean("gameplay-mechanics.player.one-punch-in-creative", creativeOnePunch);
playerSleepNearMonsters = getBoolean("gameplay-mechanics.player.sleep-ignore-nearby-mobs", playerSleepNearMonsters);
+ playersSkipNight = getBoolean("gameplay-mechanics.player.can-skip-night", playersSkipNight);
}
public boolean silkTouchEnabled = false;

View File

@@ -1,69 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ben Kerllenevich <ben@omega24.dev>
Date: Thu, 18 Mar 2021 07:23:27 -0400
Subject: [PATCH] Add config for villager trading
diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java
index a717443f894d1e30efed61944f45e991902d1fa4..671d1dafbfe2f8ba24096f78e2661014d00a5e09 100644
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
@@ -376,6 +376,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
}
if (level().purpurConfig.villagerRidable && itemstack.isEmpty()) return tryRide(player, hand); // Purpur
+ if (this.level().purpurConfig.villagerAllowTrading) // Purpur
this.startTrading(player);
}
diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java
index 05c63eb6cf8a7067105c58d244c7cc27d6bf1125..7c2d5d28f8c2aba2cd8255a4aef22247fe04d0e0 100644
--- a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java
+++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java
@@ -155,8 +155,10 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill
return tryRide(player, hand, InteractionResult.CONSUME); // Purpur
}
if (level().purpurConfig.wanderingTraderRidable && itemstack.isEmpty()) return tryRide(player, hand); // Purpur
+ if (this.level().purpurConfig.wanderingTraderAllowTrading) { // Purpur
this.setTradingPlayer(player);
this.openTradingScreen(player, this.getDisplayName(), 1);
+ } // Purpur
}
return InteractionResult.sidedSuccess(this.level().isClientSide);
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index dbacc159567dea21653148a4e9d9dbf78c8139f7..4430a61f8c923e92ea889897c17ab4535fa47b4d 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -2224,6 +2224,7 @@ public class PurpurWorldConfig {
public boolean villagerClericFarmersThrowWarts = true;
public boolean villagerBypassMobGriefing = false;
public boolean villagerTakeDamageFromWater = false;
+ public boolean villagerAllowTrading = true;
private void villagerSettings() {
villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable);
villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater);
@@ -2243,6 +2244,7 @@ public class PurpurWorldConfig {
villagerClericFarmersThrowWarts = getBoolean("mobs.villager.cleric-wart-farmers-throw-warts-at-villagers", villagerClericFarmersThrowWarts);
villagerBypassMobGriefing = getBoolean("mobs.villager.bypass-mob-griefing", villagerBypassMobGriefing);
villagerTakeDamageFromWater = getBoolean("mobs.villager.takes-damage-from-water", villagerTakeDamageFromWater);
+ villagerAllowTrading = getBoolean("mobs.villager.allow-trading", villagerAllowTrading);
}
public boolean vindicatorRidable = false;
@@ -2275,6 +2277,7 @@ public class PurpurWorldConfig {
public boolean wanderingTraderFollowEmeraldBlock = false;
public boolean wanderingTraderCanBeLeashed = false;
public boolean wanderingTraderTakeDamageFromWater = false;
+ public boolean wanderingTraderAllowTrading = true;
private void wanderingTraderSettings() {
wanderingTraderRidable = getBoolean("mobs.wandering_trader.ridable", wanderingTraderRidable);
wanderingTraderRidableInWater = getBoolean("mobs.wandering_trader.ridable-in-water", wanderingTraderRidableInWater);
@@ -2289,6 +2292,7 @@ public class PurpurWorldConfig {
wanderingTraderFollowEmeraldBlock = getBoolean("mobs.wandering_trader.follow-emerald-blocks", wanderingTraderFollowEmeraldBlock);
wanderingTraderCanBeLeashed = getBoolean("mobs.wandering_trader.can-be-leashed", wanderingTraderCanBeLeashed);
wanderingTraderTakeDamageFromWater = getBoolean("mobs.wandering_trader.takes-damage-from-water", wanderingTraderTakeDamageFromWater);
+ wanderingTraderAllowTrading = getBoolean("mobs.wandering_trader.allow-trading", wanderingTraderAllowTrading);
}
public boolean wardenRidable = false;

View File

@@ -1,61 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ben Kerllenevich <ben@omega24.dev>
Date: Sun, 21 Mar 2021 15:26:52 -0400
Subject: [PATCH] Drowning Settings
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 901080dd8431b83b20aa5604e931519dcba82b22..657980c6c82b6a50ee9874f4aeb483b40dc24247 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -3493,7 +3493,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
public int getMaxAirSupply() {
- return this.maxAirTicks; // CraftBukkit - SPIGOT-6907: re-implement LivingEntity#setMaximumAir()
+ return this.level == null? this.maxAirTicks : this.level().purpurConfig.drowningAirTicks; // CraftBukkit - SPIGOT-6907: re-implement LivingEntity#setMaximumAir() // Purpur
}
public int getAirSupply() {
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 7a99319d6ac85fd794fef361dd6f8092b847c744..d4ba4752b04ad3d1a8133c56144800af756f4aa6 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -473,7 +473,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
if (flag1) {
this.setAirSupply(this.decreaseAirSupply(this.getAirSupply()));
- if (this.getAirSupply() == -20) {
+ if (this.getAirSupply() == -this.level().purpurConfig.drowningDamageInterval) { // Purpur
this.setAirSupply(0);
Vec3 vec3d = this.getDeltaMovement();
@@ -485,7 +485,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.level().addParticle(ParticleTypes.BUBBLE, this.getX() + d2, this.getY() + d3, this.getZ() + d4, vec3d.x, vec3d.y, vec3d.z);
}
- this.hurt(this.damageSources().drown(), 2.0F);
+ this.hurt(this.damageSources().drown(), (float) this.level().purpurConfig.damageFromDrowning); // Purpur
}
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 4430a61f8c923e92ea889897c17ab4535fa47b4d..1859d0003a0c1860dd9db434b113dcfec284e025 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -165,6 +165,15 @@ public class PurpurWorldConfig {
nighttimeTicks = getInt("gameplay-mechanics.daylight-cycle-ticks.nighttime", nighttimeTicks);
}
+ public int drowningAirTicks = 300;
+ public int drowningDamageInterval = 20;
+ public double damageFromDrowning = 2.0F;
+ private void drowningSettings() {
+ drowningAirTicks = getInt("gameplay-mechanics.drowning.air-ticks", drowningAirTicks);
+ drowningDamageInterval = getInt("gameplay-mechanics.drowning.ticks-per-damage", drowningDamageInterval);
+ damageFromDrowning = getDouble("gameplay-mechanics.drowning.damage-from-drowning", damageFromDrowning);
+ }
+
public int elytraDamagePerSecond = 1;
public double elytraDamageMultiplyBySpeed = 0;
public int elytraDamagePerFireworkBoost = 0;

View File

@@ -1,64 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Tue, 23 Mar 2021 19:38:53 -0500
Subject: [PATCH] Break individual slabs when sneaking
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
index 09ab1904ea9c587f365513150dafe434a0b56ccf..d3c49951c0bd7db4352326d3113f0ca9da393fab 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
@@ -405,6 +405,7 @@ public class ServerPlayerGameMode {
} else {capturedBlockEntity = true;} // Paper - Send block entities after destroy prediction
return false;
}
+ if (this.player.level().purpurConfig.slabHalfBreak && this.player.isShiftKeyDown() && iblockdata.getBlock() instanceof net.minecraft.world.level.block.SlabBlock && ((net.minecraft.world.level.block.SlabBlock) iblockdata.getBlock()).halfBreak(iblockdata, pos, this.player)) return true; // Purpur
}
// CraftBukkit end
diff --git a/src/main/java/net/minecraft/world/level/block/SlabBlock.java b/src/main/java/net/minecraft/world/level/block/SlabBlock.java
index fa29eb15934b3dad171d27c21d99b2451cfe553b..ba4aa69425d796d306791ea193f9c6b21a065f0b 100644
--- a/src/main/java/net/minecraft/world/level/block/SlabBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/SlabBlock.java
@@ -138,4 +138,25 @@ public class SlabBlock extends Block implements SimpleWaterloggedBlock {
return false;
}
}
+
+ // Purpur start
+ public boolean halfBreak(BlockState state, BlockPos pos, net.minecraft.server.level.ServerPlayer player) {
+ if (state.getValue(SlabBlock.TYPE) != SlabType.DOUBLE) {
+ return false;
+ }
+ net.minecraft.world.phys.HitResult result = player.getRayTrace(16, net.minecraft.world.level.ClipContext.Fluid.NONE);
+ if (result.getType() != net.minecraft.world.phys.HitResult.Type.BLOCK) {
+ return false;
+ }
+ double hitY = result.getLocation().y();
+ int blockY = org.bukkit.util.NumberConversions.floor(hitY);
+ player.level().setBlock(pos, state.setValue(SlabBlock.TYPE, (hitY - blockY > 0.5 || blockY - pos.getY() == 1) ? SlabType.BOTTOM : SlabType.TOP), 3);
+ if (!player.getAbilities().instabuild) {
+ net.minecraft.world.entity.item.ItemEntity item = new net.minecraft.world.entity.item.ItemEntity(player.level(), pos.getX(), pos.getY(), pos.getZ(), new ItemStack(asItem()));
+ item.setDefaultPickUpDelay();
+ player.level().addFreshEntity(item);
+ }
+ return true;
+ }
+ // Purpur end
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 1859d0003a0c1860dd9db434b113dcfec284e025..c9bff81954385a2f4113a4fd51d3b85b2f7048c2 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -560,6 +560,11 @@ public class PurpurWorldConfig {
}
}
+ public boolean slabHalfBreak = false;
+ private void slabSettings() {
+ slabHalfBreak = getBoolean("blocks.slab.break-individual-slabs-when-sneaking", slabHalfBreak);
+ }
+
public boolean spawnerDeactivateByRedstone = false;
private void spawnerSettings() {
spawnerDeactivateByRedstone = getBoolean("blocks.spawner.deactivate-by-redstone", spawnerDeactivateByRedstone);

View File

@@ -1,43 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Tue, 23 Mar 2021 15:40:45 -0400
Subject: [PATCH] Config to disable hostile mob spawn on ice
diff --git a/src/main/java/net/minecraft/world/entity/monster/Monster.java b/src/main/java/net/minecraft/world/entity/monster/Monster.java
index e7bfce0534c7ef3a1480a1082ae8514caf78778b..6511b8c737a57fbc72122dd04e2b544987a49b92 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Monster.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Monster.java
@@ -87,6 +87,14 @@ public abstract class Monster extends PathfinderMob implements Enemy {
}
public static boolean isDarkEnoughToSpawn(ServerLevelAccessor world, BlockPos pos, RandomSource random) {
+ // Purpur start
+ if (!world.getMinecraftWorld().purpurConfig.mobsSpawnOnPackedIce || !world.getMinecraftWorld().purpurConfig.mobsSpawnOnBlueIce) {
+ net.minecraft.world.level.block.state.BlockState spawnBlock = world.getBlockState(pos.below());
+ if ((!world.getMinecraftWorld().purpurConfig.mobsSpawnOnPackedIce && spawnBlock.is(net.minecraft.world.level.block.Blocks.PACKED_ICE)) || (!world.getMinecraftWorld().purpurConfig.mobsSpawnOnBlueIce && spawnBlock.is(net.minecraft.world.level.block.Blocks.BLUE_ICE))) {
+ return false;
+ }
+ }
+ // Purpur end
if (world.getBrightness(LightLayer.SKY, pos) > random.nextInt(32)) {
return false;
} else {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index c9bff81954385a2f4113a4fd51d3b85b2f7048c2..4e6824fa7adf8dfbafeff2bd6f6426ddb03c5a15 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -525,6 +525,13 @@ public class PurpurWorldConfig {
furnaceUseLavaFromUnderneath = getBoolean("blocks.furnace.use-lava-from-underneath", furnaceUseLavaFromUnderneath);
}
+ public boolean mobsSpawnOnPackedIce = true;
+ public boolean mobsSpawnOnBlueIce = true;
+ private void iceSettings() {
+ mobsSpawnOnPackedIce = getBoolean("blocks.packed_ice.allow-mob-spawns", mobsSpawnOnPackedIce);
+ mobsSpawnOnBlueIce = getBoolean("blocks.blue_ice.allow-mob-spawns", mobsSpawnOnBlueIce);
+ }
+
public int lavaInfiniteRequiredSources = 2;
public int lavaSpeedNether = 10;
public int lavaSpeedNotNether = 30;

View File

@@ -1,38 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Tue, 23 Mar 2021 22:42:20 -0400
Subject: [PATCH] Config to show Armor Stand arms on spawn
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
index 7180d65afee6216a0bc6ff2dc7888f64b9b6c22d..c0383771b08e1d89dfa4996b979248da1de8aca1 100644
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
@@ -116,6 +116,7 @@ public class ArmorStand extends LivingEntity {
this.rightArmPose = ArmorStand.DEFAULT_RIGHT_ARM_POSE;
this.leftLegPose = ArmorStand.DEFAULT_LEFT_LEG_POSE;
this.rightLegPose = ArmorStand.DEFAULT_RIGHT_LEG_POSE;
+ this.setShowArms(world != null && world.purpurConfig.armorstandPlaceWithArms); // Purpur
}
public ArmorStand(Level world, double x, double y, double z) {
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 4e6824fa7adf8dfbafeff2bd6f6426ddb03c5a15..678130678e1f0b018fc77c608ed092c94e2f52a0 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -103,6 +103,7 @@ public class PurpurWorldConfig {
public boolean armorstandMovement = true;
public boolean armorstandWaterMovement = true;
public boolean armorstandWaterFence = true;
+ public boolean armorstandPlaceWithArms = false;
private void armorstandSettings() {
armorstandStepHeight = (float) getDouble("gameplay-mechanics.armorstand.step-height", armorstandStepHeight);
armorstandSetNameVisible = getBoolean("gameplay-mechanics.armorstand.set-name-visible-when-placing-with-custom-name", armorstandSetNameVisible);
@@ -110,6 +111,7 @@ public class PurpurWorldConfig {
armorstandMovement = getBoolean("gameplay-mechanics.armorstand.can-movement-tick", armorstandMovement);
armorstandWaterMovement = getBoolean("gameplay-mechanics.armorstand.can-move-in-water", armorstandWaterMovement);
armorstandWaterFence = getBoolean("gameplay-mechanics.armorstand.can-move-in-water-over-fence", armorstandWaterFence);
+ armorstandPlaceWithArms = getBoolean("gameplay-mechanics.armorstand.place-with-arms-visible", armorstandPlaceWithArms);
}
public boolean arrowMovementResetsDespawnCounter = true;

View File

@@ -1,104 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Wed, 24 Mar 2021 04:40:11 -0500
Subject: [PATCH] Option to make doors require redstone
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java b/src/main/java/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java
index 3513b15f6622bfc134ecfcd9129f81a8acc2c601..6e70579a58a1bf906b176b81713e55318199cef6 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java
@@ -57,7 +57,7 @@ public class InteractWithDoor {
if (iblockdata.is(BlockTags.MOB_INTERACTABLE_DOORS, (blockbase_blockdata) -> {
return blockbase_blockdata.getBlock() instanceof DoorBlock;
- })) {
+ }) && !DoorBlock.requiresRedstone(entityliving.level(), iblockdata, blockposition)) { // Purpur
DoorBlock blockdoor = (DoorBlock) iblockdata.getBlock();
if (!blockdoor.isOpen(iblockdata)) {
@@ -79,7 +79,7 @@ public class InteractWithDoor {
if (iblockdata1.is(BlockTags.MOB_INTERACTABLE_DOORS, (blockbase_blockdata) -> {
return blockbase_blockdata.getBlock() instanceof DoorBlock;
- })) {
+ }) && !DoorBlock.requiresRedstone(entityliving.level(), iblockdata, blockposition1)) { // Purpur
DoorBlock blockdoor1 = (DoorBlock) iblockdata1.getBlock();
if (!blockdoor1.isOpen(iblockdata1)) {
@@ -122,7 +122,7 @@ public class InteractWithDoor {
if (!iblockdata.is(BlockTags.MOB_INTERACTABLE_DOORS, (blockbase_blockdata) -> {
return blockbase_blockdata.getBlock() instanceof DoorBlock;
- })) {
+ }) || DoorBlock.requiresRedstone(entity.level(), iblockdata, blockposition)) { // Purpur
iterator.remove();
} else {
DoorBlock blockdoor = (DoorBlock) iblockdata.getBlock();
diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java
index 7c2d5d28f8c2aba2cd8255a4aef22247fe04d0e0..6250bc28db4bbac0f101cdc93c90ec4d7ec6b2ba 100644
--- a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java
+++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java
@@ -156,8 +156,8 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill
}
if (level().purpurConfig.wanderingTraderRidable && itemstack.isEmpty()) return tryRide(player, hand); // Purpur
if (this.level().purpurConfig.wanderingTraderAllowTrading) { // Purpur
- this.setTradingPlayer(player);
- this.openTradingScreen(player, this.getDisplayName(), 1);
+ this.setTradingPlayer(player);
+ this.openTradingScreen(player, this.getDisplayName(), 1);
} // Purpur
}
diff --git a/src/main/java/net/minecraft/world/level/block/DoorBlock.java b/src/main/java/net/minecraft/world/level/block/DoorBlock.java
index 6dd75bc722f9c20b4869e6353115c3b02dd79f99..dfaf82f5b0180cf08c4125347867d37a2557fd24 100644
--- a/src/main/java/net/minecraft/world/level/block/DoorBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/DoorBlock.java
@@ -198,6 +198,7 @@ public class DoorBlock extends Block {
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) {
if (!this.type.canOpenByHand()) {
return InteractionResult.PASS;
+ } else if (requiresRedstone(world, state, pos)) { return InteractionResult.CONSUME; // Purpur
} else {
state = (BlockState) state.cycle(DoorBlock.OPEN);
world.setBlock(pos, state, 10);
@@ -299,4 +300,18 @@ public class DoorBlock extends Block {
flag = false;
return flag;
}
+
+ // Purpur start
+ public static boolean requiresRedstone(Level level, BlockState state, BlockPos pos) {
+ if (level.purpurConfig.doorRequiresRedstone.contains(state.getBlock())) {
+ // force update client
+ BlockPos otherPos = pos.relative(state.getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER ? Direction.UP : Direction.DOWN);
+ BlockState otherState = level.getBlockState(otherPos);
+ level.sendBlockUpdated(pos, state, state, 3);
+ level.sendBlockUpdated(otherPos, otherState, otherState, 3);
+ return true;
+ }
+ return false;
+ }
+ // Purpur end
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 678130678e1f0b018fc77c608ed092c94e2f52a0..58726907eb4dcb4f386873c4092df2b314736f2d 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -464,6 +464,16 @@ public class PurpurWorldConfig {
dispenserPlaceAnvils = getBoolean("blocks.dispenser.place-anvils", dispenserPlaceAnvils);
}
+ public List<Block> doorRequiresRedstone = new ArrayList<>();
+ private void doorSettings() {
+ getList("blocks.door.requires-redstone", new ArrayList<String>()).forEach(key -> {
+ Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(key.toString()));
+ if (!block.defaultBlockState().isAir()) {
+ doorRequiresRedstone.add(block);
+ }
+ });
+ }
+
public boolean baselessEndCrystalExplode = true;
public double baselessEndCrystalExplosionPower = 6.0D;
public boolean baselessEndCrystalExplosionFire = false;

View File

@@ -1,137 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Wed, 24 Mar 2021 17:59:54 -0400
Subject: [PATCH] Config to allow unsafe enchants
diff --git a/src/main/java/net/minecraft/server/commands/EnchantCommand.java b/src/main/java/net/minecraft/server/commands/EnchantCommand.java
index 99695e38b6a10c3cffda6e453f9f0619c7406cc0..2283f69607cb769545c85bcae940ac956779e80b 100644
--- a/src/main/java/net/minecraft/server/commands/EnchantCommand.java
+++ b/src/main/java/net/minecraft/server/commands/EnchantCommand.java
@@ -70,7 +70,7 @@ public class EnchantCommand {
private static int enchant(CommandSourceStack source, Collection<? extends Entity> targets, Holder<Enchantment> enchantment, int level) throws CommandSyntaxException {
Enchantment enchantment2 = enchantment.value();
- if (level > enchantment2.getMaxLevel()) {
+ if (!org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && level > enchantment2.getMaxLevel()) { // Purpur - Config to allow unsafe enchants
throw ERROR_LEVEL_TOO_HIGH.create(level, enchantment2.getMaxLevel());
} else {
int i = 0;
@@ -81,7 +81,7 @@ public class EnchantCommand {
ItemStack itemStack = livingEntity.getMainHandItem();
if (!itemStack.isEmpty()) {
if (enchantment2.canEnchant(itemStack)
- && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(itemStack).keySet(), enchantment)) {
+ && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(itemStack).keySet(), enchantment) || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && !itemStack.hasEnchantment(enchantment))) { // Purpur - Config to allow unsafe enchants
itemStack.enchant(enchantment, level);
i++;
} else if (targets.size() == 1) {
diff --git a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
index 58135a3292bcdfea17726f17d86192ced96eea9a..29e54876c22739f45565cd91bcbd76612e8bfad1 100644
--- a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
+++ b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
@@ -232,7 +232,10 @@ public class AnvilMenu extends ItemCombinerMenu {
i2 = l1 == i2 ? i2 + 1 : Math.max(i2, l1);
Enchantment enchantment = (Enchantment) holder.value();
- boolean flag3 = enchantment.canEnchant(itemstack);
+ // Purpur start - Config to allow unsafe enchants
+ boolean flag3 = this.canDoUnsafeEnchants || org.purpurmc.purpur.PurpurConfig.allowInapplicableEnchants || enchantment.canEnchant(itemstack); // whether the enchantment can be applied on specific item type
+ boolean flag4 = true; // whether two incompatible enchantments can be applied on a single item
+ // Purpur end - Config to allow unsafe enchants
if (this.player.getAbilities().instabuild || itemstack.is(Items.ENCHANTED_BOOK)) {
flag3 = true;
@@ -244,16 +247,22 @@ public class AnvilMenu extends ItemCombinerMenu {
Holder<Enchantment> holder1 = (Holder) iterator1.next();
if (!holder1.equals(holder) && !Enchantment.areCompatible(holder, holder1)) {
- flag3 = this.canDoUnsafeEnchants; // Purpur - Anvil API
+ flag4 = this.canDoUnsafeEnchants || org.purpurmc.purpur.PurpurConfig.allowIncompatibleEnchants; // Purpur - Anvil API // Purpur - flag3 -> flag4 - Config to allow unsafe enchants
+ // Purpur start - Config to allow unsafe enchants
+ if (!flag4 && org.purpurmc.purpur.PurpurConfig.replaceIncompatibleEnchants) {
+ iterator1.remove(); // replace current enchant with the incompatible one trying to be applied
+ flag4 = true;
+ }
+ // Purpur end - Config to allow unsafe enchants
++i;
}
}
- if (!flag3) {
+ if (!flag3 || !flag4) { // Purpur - Config to allow unsafe enchants
flag2 = true;
} else {
flag1 = true;
- if (i2 > enchantment.getMaxLevel() && !this.bypassEnchantmentLevelRestriction) { // Paper - bypass anvil level restrictions
+ if (!org.purpurmc.purpur.PurpurConfig.allowHigherEnchantsLevels && i2 > enchantment.getMaxLevel() && !this.bypassEnchantmentLevelRestriction) { // Paper - bypass anvil level restrictions // Purpur - Config to allow unsafe enchants
i2 = enchantment.getMaxLevel();
}
@@ -379,7 +388,7 @@ public class AnvilMenu extends ItemCombinerMenu {
this.broadcastChanges();
// Purpur start - Anvil API
- if (this.canDoUnsafeEnchants && itemstack1 != ItemStack.EMPTY) {
+ if ((this.canDoUnsafeEnchants || org.purpurmc.purpur.PurpurConfig.allowInapplicableEnchants || org.purpurmc.purpur.PurpurConfig.allowIncompatibleEnchants) && itemstack1 != ItemStack.EMPTY) { // Purpur - Config to allow unsafe enchants
((ServerPlayer) this.player).connection.send(new ClientboundContainerSetSlotPacket(this.containerId, this.incrementStateId(), 2, itemstack1));
((ServerPlayer) this.player).connection.send(new ClientboundContainerSetDataPacket(this.containerId, 0, this.cost.get()));
}
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
index 5f57f3494705ca1664dbca395c1af3280a50cad8..8c14f8c9f61baf1842e42b62bcd73717e82a29e1 100644
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
@@ -1255,6 +1255,12 @@ public final class ItemStack implements DataComponentHolder {
return !((ItemEnchantments) this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY)).isEmpty();
}
+ // Purpur start - Config to allow unsafe enchants
+ public boolean hasEnchantment(Holder<Enchantment> enchantment) {
+ return this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY).getLevel(enchantment) > 0;
+ }
+ // Purpur end - Config to allow unsafe enchants
+
public ItemEnchantments getEnchantments() {
return (ItemEnchantments) this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY);
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index 6fcb2db92a38e862da288518ce34d16aa4b856e0..b37daca2ca99d79210ec5e8e9d589e27702a57e5 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -285,6 +285,36 @@ public class PurpurConfig {
cryingObsidianValidForPortalFrame = getBoolean("settings.blocks.crying_obsidian.valid-for-portal-frame", cryingObsidianValidForPortalFrame);
}
+ public static boolean allowInapplicableEnchants = false;
+ public static boolean allowIncompatibleEnchants = false;
+ public static boolean allowHigherEnchantsLevels = false;
+ public static boolean allowUnsafeEnchantCommand = false;
+ public static boolean replaceIncompatibleEnchants = false;
+ private static void enchantmentSettings() {
+ if (version < 30) {
+ boolean oldValue = getBoolean("settings.enchantment.allow-unsafe-enchants", false);
+ set("settings.enchantment.anvil.allow-unsafe-enchants", oldValue);
+ set("settings.enchantment.anvil.allow-inapplicable-enchants", true);
+ set("settings.enchantment.anvil.allow-incompatible-enchants", true);
+ set("settings.enchantment.anvil.allow-higher-enchants-levels", true);
+ set("settings.enchantment.allow-unsafe-enchants", null);
+ }
+ if (version < 37) {
+ boolean allowUnsafeEnchants = getBoolean("settings.enchantment.anvil.allow-unsafe-enchants", false);
+ if (!allowUnsafeEnchants) {
+ set("settings.enchantment.anvil.allow-inapplicable-enchants", false);
+ set("settings.enchantment.anvil.allow-incompatible-enchants", false);
+ set("settings.enchantment.anvil.allow-higher-enchants-levels", false);
+ }
+ set("settings.enchantment.anvil.allow-unsafe-enchants", null);
+ }
+ allowInapplicableEnchants = getBoolean("settings.enchantment.anvil.allow-inapplicable-enchants", allowInapplicableEnchants);
+ allowIncompatibleEnchants = getBoolean("settings.enchantment.anvil.allow-incompatible-enchants", allowIncompatibleEnchants);
+ allowHigherEnchantsLevels = getBoolean("settings.enchantment.anvil.allow-higher-enchants-levels", allowHigherEnchantsLevels);
+ allowUnsafeEnchantCommand = getBoolean("settings.enchantment.allow-unsafe-enchant-command", allowUnsafeEnchantCommand);
+ replaceIncompatibleEnchants = getBoolean("settings.enchantment.anvil.replace-incompatible-enchants", replaceIncompatibleEnchants);
+ }
+
public static boolean endermanShortHeight = false;
private static void entitySettings() {
endermanShortHeight = getBoolean("settings.entity.enderman.short-height", endermanShortHeight);

View File

@@ -1,40 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Wed, 24 Mar 2021 20:30:37 -0400
Subject: [PATCH] Configurable sponge absorption
Allows the total area and radius of water blocks the sponge can absorb to be changed.
Co-authored by: granny <granny@purpurmc.org>
diff --git a/src/main/java/net/minecraft/world/level/block/SpongeBlock.java b/src/main/java/net/minecraft/world/level/block/SpongeBlock.java
index 902825ec9ea05f4418b45f56a008d73f217bd178..a676ccfa6b02e8986df6f6a2e04cbb06b3edd0ff 100644
--- a/src/main/java/net/minecraft/world/level/block/SpongeBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/SpongeBlock.java
@@ -58,7 +58,7 @@ public class SpongeBlock extends Block {
private boolean removeWaterBreadthFirstSearch(Level world, BlockPos pos) {
BlockStateListPopulator blockList = new BlockStateListPopulator(world); // CraftBukkit - Use BlockStateListPopulator
- BlockPos.breadthFirstTraversal(pos, 6, 65, (blockposition1, consumer) -> {
+ BlockPos.breadthFirstTraversal(pos, world.purpurConfig.spongeAbsorptionRadius, world.purpurConfig.spongeAbsorptionArea, (blockposition1, consumer) -> { // Purpur
Direction[] aenumdirection = SpongeBlock.ALL_DIRECTIONS;
int i = aenumdirection.length;
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 58726907eb4dcb4f386873c4092df2b314736f2d..a4c0ed4e5b6145cb8e33f6bd38af678cae4d79d7 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -589,6 +589,13 @@ public class PurpurWorldConfig {
spawnerDeactivateByRedstone = getBoolean("blocks.spawner.deactivate-by-redstone", spawnerDeactivateByRedstone);
}
+ public int spongeAbsorptionArea = 65;
+ public int spongeAbsorptionRadius = 6;
+ private void spongeSettings() {
+ spongeAbsorptionArea = getInt("blocks.sponge.absorption.area", spongeAbsorptionArea);
+ spongeAbsorptionRadius = getInt("blocks.sponge.absorption.radius", spongeAbsorptionRadius);
+ }
+
public boolean turtleEggsBreakFromExpOrbs = false;
public boolean turtleEggsBreakFromItems = false;
public boolean turtleEggsBreakFromMinecarts = false;

View File

@@ -1,125 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: YouHaveTrouble <garrenpolska@gmail.com>
Date: Thu, 25 Mar 2021 01:56:38 +0100
Subject: [PATCH] Projectile offset config
diff --git a/src/main/java/net/minecraft/world/item/BowItem.java b/src/main/java/net/minecraft/world/item/BowItem.java
index 4db2032178471860baddc6b669c9a4f8cffd084b..fc534b1f214663eb8e4fe479fed12b1dd069105c 100644
--- a/src/main/java/net/minecraft/world/item/BowItem.java
+++ b/src/main/java/net/minecraft/world/item/BowItem.java
@@ -37,7 +37,7 @@ public class BowItem extends ProjectileWeaponItem {
if (!((double)f < 0.1)) {
List<ItemStack> list = draw(stack, itemStack, player);
if (world instanceof ServerLevel serverLevel && !list.isEmpty()) {
- this.shoot(serverLevel, player, player.getUsedItemHand(), stack, list, f * 3.0F, 1.0F, f == 1.0F, null);
+ this.shoot(serverLevel, player, player.getUsedItemHand(), stack, list, f * 3.0F, (float) world.purpurConfig.bowProjectileOffset, f == 1.0F, null); // Purpur
}
world.playSound(
diff --git a/src/main/java/net/minecraft/world/item/CrossbowItem.java b/src/main/java/net/minecraft/world/item/CrossbowItem.java
index 1467e6f2df302e0b7992dcb6c136cb626ade3d2b..4e60c2102e3e838c68e4b9db41c8bca365d22923 100644
--- a/src/main/java/net/minecraft/world/item/CrossbowItem.java
+++ b/src/main/java/net/minecraft/world/item/CrossbowItem.java
@@ -69,7 +69,7 @@ public class CrossbowItem extends ProjectileWeaponItem {
ItemStack itemStack = user.getItemInHand(hand);
ChargedProjectiles chargedProjectiles = itemStack.get(DataComponents.CHARGED_PROJECTILES);
if (chargedProjectiles != null && !chargedProjectiles.isEmpty()) {
- this.performShooting(world, user, hand, itemStack, getShootingPower(chargedProjectiles), 1.0F, null);
+ this.performShooting(world, user, hand, itemStack, getShootingPower(chargedProjectiles), (float) world.purpurConfig.crossbowProjectileOffset, null); // Purpur
return InteractionResultHolder.consume(itemStack);
} else if (!user.getProjectile(itemStack).isEmpty()) {
this.startSoundPlayed = false;
diff --git a/src/main/java/net/minecraft/world/item/EggItem.java b/src/main/java/net/minecraft/world/item/EggItem.java
index 4ebd634cff286b10868e26eeb3ecf34abdcab22e..7dc811335caa46870d1d895899a1e6c21980382d 100644
--- a/src/main/java/net/minecraft/world/item/EggItem.java
+++ b/src/main/java/net/minecraft/world/item/EggItem.java
@@ -27,7 +27,7 @@ public class EggItem extends Item implements ProjectileItem {
ThrownEgg entityegg = new ThrownEgg(world, user);
entityegg.setItem(itemstack);
- entityegg.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, 1.0F);
+ entityegg.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, (float) world.purpurConfig.eggProjectileOffset); // Purpur
// Paper start - PlayerLaunchProjectileEvent
com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entityegg.getBukkitEntity());
if (event.callEvent() && world.addFreshEntity(entityegg)) {
diff --git a/src/main/java/net/minecraft/world/item/EnderpearlItem.java b/src/main/java/net/minecraft/world/item/EnderpearlItem.java
index fc62754f93bd11a10c28b8b7b116e9fff70a5c7b..11b04455f09d8bfdf44499bb8359dc715c2daffd 100644
--- a/src/main/java/net/minecraft/world/item/EnderpearlItem.java
+++ b/src/main/java/net/minecraft/world/item/EnderpearlItem.java
@@ -24,7 +24,7 @@ public class EnderpearlItem extends Item {
ThrownEnderpearl entityenderpearl = new ThrownEnderpearl(world, user);
entityenderpearl.setItem(itemstack);
- entityenderpearl.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, 1.0F);
+ entityenderpearl.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, (float) world.purpurConfig.enderPearlProjectileOffset); // Purpur
// Paper start - PlayerLaunchProjectileEvent
com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entityenderpearl.getBukkitEntity());
if (event.callEvent() && world.addFreshEntity(entityenderpearl)) {
diff --git a/src/main/java/net/minecraft/world/item/SnowballItem.java b/src/main/java/net/minecraft/world/item/SnowballItem.java
index 32b170551a2f5bdc88d29f4d03750bfe3974e71b..a41fb0dd26af367fc2470a7913a84d864bc505f7 100644
--- a/src/main/java/net/minecraft/world/item/SnowballItem.java
+++ b/src/main/java/net/minecraft/world/item/SnowballItem.java
@@ -28,7 +28,7 @@ public class SnowballItem extends Item implements ProjectileItem {
Snowball entitysnowball = new Snowball(world, user);
entitysnowball.setItem(itemstack);
- entitysnowball.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, 1.0F);
+ entitysnowball.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, (float) world.purpurConfig.snowballProjectileOffset); // Purpur
// Paper start - PlayerLaunchProjectileEvent
com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entitysnowball.getBukkitEntity());
if (event.callEvent() && world.addFreshEntity(entitysnowball)) {
diff --git a/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java b/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java
index 369955746f4b51f69fa01103e3771dd74fc6c8f0..e6edd3a0fa2578900cdbe8bd588219dc3fd3af5f 100644
--- a/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java
+++ b/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java
@@ -21,7 +21,7 @@ public class ThrowablePotionItem extends PotionItem implements ProjectileItem {
if (!world.isClientSide) {
ThrownPotion thrownPotion = new ThrownPotion(world, user);
thrownPotion.setItem(itemStack);
- thrownPotion.shootFromRotation(user, user.getXRot(), user.getYRot(), -20.0F, 0.5F, 1.0F);
+ thrownPotion.shootFromRotation(user, user.getXRot(), user.getYRot(), -20.0F, 0.5F, (float) world.purpurConfig.throwablePotionProjectileOffset); // Purpur
// Paper start - PlayerLaunchProjectileEvent
com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) thrownPotion.getBukkitEntity());
if (event.callEvent() && world.addFreshEntity(thrownPotion)) {
diff --git a/src/main/java/net/minecraft/world/item/TridentItem.java b/src/main/java/net/minecraft/world/item/TridentItem.java
index 4934bae61114b49a9f8d0ed044fbb881210df32a..1be074074283f12543ac771ac9201580e7736289 100644
--- a/src/main/java/net/minecraft/world/item/TridentItem.java
+++ b/src/main/java/net/minecraft/world/item/TridentItem.java
@@ -81,7 +81,7 @@ public class TridentItem extends Item implements ProjectileItem {
if (f == 0.0F) {
ThrownTrident entitythrowntrident = new ThrownTrident(world, entityhuman, stack);
- entitythrowntrident.shootFromRotation(entityhuman, entityhuman.getXRot(), entityhuman.getYRot(), 0.0F, 2.5F, 1.0F);
+ entitythrowntrident.shootFromRotation(entityhuman, entityhuman.getXRot(), entityhuman.getYRot(), 0.0F, 2.5F, (float) world.purpurConfig.tridentProjectileOffset); // Purpur
if (entityhuman.hasInfiniteMaterials()) {
entitythrowntrident.pickup = AbstractArrow.Pickup.CREATIVE_ONLY;
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index a4c0ed4e5b6145cb8e33f6bd38af678cae4d79d7..c4233c138edf6c685cbcb487c79c02e84adaf65e 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -414,6 +414,23 @@ public class PurpurWorldConfig {
});
}
+ public double bowProjectileOffset = 1.0D;
+ public double crossbowProjectileOffset = 1.0D;
+ public double eggProjectileOffset = 1.0D;
+ public double enderPearlProjectileOffset = 1.0D;
+ public double throwablePotionProjectileOffset = 1.0D;
+ public double tridentProjectileOffset = 1.0D;
+ public double snowballProjectileOffset = 1.0D;
+ private void projectileOffsetSettings() {
+ bowProjectileOffset = getDouble("gameplay-mechanics.projectile-offset.bow", bowProjectileOffset);
+ crossbowProjectileOffset = getDouble("gameplay-mechanics.projectile-offset.crossbow", crossbowProjectileOffset);
+ eggProjectileOffset = getDouble("gameplay-mechanics.projectile-offset.egg", eggProjectileOffset);
+ enderPearlProjectileOffset = getDouble("gameplay-mechanics.projectile-offset.ender-pearl", enderPearlProjectileOffset);
+ throwablePotionProjectileOffset = getDouble("gameplay-mechanics.projectile-offset.throwable-potion", throwablePotionProjectileOffset);
+ tridentProjectileOffset = getDouble("gameplay-mechanics.projectile-offset.trident", tridentProjectileOffset);
+ snowballProjectileOffset = getDouble("gameplay-mechanics.projectile-offset.snowball", snowballProjectileOffset);
+ }
+
public int snowballDamage = -1;
private void snowballSettings() {
snowballDamage = getInt("gameplay-mechanics.projectile-damage.snowball", snowballDamage);

View File

@@ -1,35 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Encode42 <me@encode42.dev>
Date: Thu, 25 Mar 2021 18:10:03 -0400
Subject: [PATCH] Config for powered rail activation distance
diff --git a/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java b/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java
index 9603d8c84ff483030dc08e82d3579b89e5c1f6e9..8fc65c32a3c6e6842a76b36f45e1b1c23abbc480 100644
--- a/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java
@@ -30,7 +30,7 @@ public class PoweredRailBlock extends BaseRailBlock {
}
protected boolean findPoweredRailSignal(Level world, BlockPos pos, BlockState state, boolean flag, int distance) {
- if (distance >= 8) {
+ if (distance >= world.purpurConfig.railActivationRange) { // Purpur
return false;
} else {
int j = pos.getX();
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index c4233c138edf6c685cbcb487c79c02e84adaf65e..22de19aeb28795484525ddb22df96b89f915eceb 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -575,6 +575,11 @@ public class PurpurWorldConfig {
powderSnowBypassMobGriefing = getBoolean("blocks.powder_snow.bypass-mob-griefing", powderSnowBypassMobGriefing);
}
+ public int railActivationRange = 8;
+ private void railSettings() {
+ railActivationRange = getInt("blocks.powered-rail.activation-range", railActivationRange);
+ }
+
public boolean respawnAnchorExplode = true;
public double respawnAnchorExplosionPower = 5.0D;
public boolean respawnAnchorExplosionFire = true;