make it compile \o/

This commit is contained in:
granny
2026-03-24 01:25:42 -07:00
parent 465f4d86be
commit 57a0650b8f
40 changed files with 78 additions and 147 deletions

View File

@@ -1,7 +1,6 @@
# This file is auto generated, any changes may be overridden!
# See CONTRIBUTING.md on how to add access transformers.
protected net.minecraft.world.entity.Entity dimensions
public net.minecraft.world.entity.Entity updateInWaterStateAndDoWaterCurrentPushing()V
public net.minecraft.world.entity.LivingEntity canGlide()Z
public net.minecraft.world.entity.monster.Shulker MAX_SCALE
public net.minecraft.world.entity.player.Player canGlide()Z

View File

@@ -14,7 +14,7 @@
if (!item.isEmpty()) {
if (enchantment.canEnchant(item)
- && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(item).keySet(), enchantmentHolder)) {
+ && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(item).keySet(), enchantmentHolder) || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && !mainHandItem.hasEnchantment(enchantment))) { // Purpur - Config to allow unsafe enchants
+ && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(item).keySet(), enchantmentHolder) || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && !item.hasEnchantment(enchantmentHolder))) { // Purpur - Config to allow unsafe enchants
item.enchant(enchantmentHolder, level);
success++;
} else if (targets.size() == 1) {

View File

@@ -30,7 +30,7 @@
+ this.customSpawners.add(new net.minecraft.world.entity.ai.village.VillageSiege());
+ }
+ if (purpurConfig.villagerTraderSpawning) {
+ this.customSpawners.add(new net.minecraft.world.entity.npc.wanderingtrader.WanderingTraderSpawner(levelData));
+ this.customSpawners.add(new net.minecraft.world.entity.npc.wanderingtrader.WanderingTraderSpawner(savedDataStorage));
+ }
+ // Purpur end - Allow toggling special MobSpawners per world
ChunkGenerator generator = levelStem.generator();
@@ -40,7 +40,7 @@
this.environmentAttributes = EnvironmentAttributeSystem.builder().addDefaultLayers(this).build();
this.updateSkyBrightness();
this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit
+ this.preciseTime = this.serverLevelData.getDayTime(); // Purpur - Configurable daylight cycle
+ this.preciseTime = this.serverLevelData.getGameTime(); // Purpur - Configurable daylight cycle
}
// Paper start
@@ -81,10 +81,10 @@
+ boolean canSnow = true;
+ // Ensure snow doesn't get more than N layers taller than its neighbors
+ // We only need to check blocks that are taller than the minimum step height
+ if (org.purpurmc.purpur.PurpurConfig.smoothSnowAccumulationStep > 0 && layersValue >= org.purpurmc.purpur.PurpurConfig.smoothSnowAccumulationStep) {
+ int layersValueMin = layersValue - org.purpurmc.purpur.PurpurConfig.smoothSnowAccumulationStep;
+ if (org.purpurmc.purpur.PurpurConfig.smoothSnowAccumulationStep > 0 && currentLayers >= org.purpurmc.purpur.PurpurConfig.smoothSnowAccumulationStep) {
+ int layersValueMin = currentLayers - org.purpurmc.purpur.PurpurConfig.smoothSnowAccumulationStep;
+ for (Direction direction : Direction.Plane.HORIZONTAL) {
+ BlockPos blockPosNeighbor = heightmapPos.relative(direction);
+ BlockPos blockPosNeighbor = topPos.relative(direction);
+ BlockState blockStateNeighbor = this.getBlockState(blockPosNeighbor);
+ if (blockStateNeighbor.is(Blocks.SNOW)) {
+ // Special check for snow layers, if neighbors are too short, don't accumulate
@@ -139,7 +139,7 @@
+ if (!org.purpurmc.purpur.PurpurConfig.sleepingPlayersPercent.equalsIgnoreCase("default")) {
+ message = io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.sleepingPlayersPercent,
+ net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.parsed("count", Integer.toString(this.sleepStatus.amountSleeping())),
+ net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.parsed("total", Integer.toString(this.sleepStatus.sleepersNeeded(i)))));
+ net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.parsed("total", Integer.toString(this.sleepStatus.sleepersNeeded(percentage)))));
+ } else
+ // Purpur end - Customizable sleeping actionbar messages
message = Component.translatable("sleep.players_sleeping", this.sleepStatus.amountSleeping(), this.sleepStatus.sleepersNeeded(percentage));

View File

@@ -4,7 +4,7 @@
}
return false;
}
+ if (this.player.level().purpurConfig.slabHalfBreak && this.player.isShiftKeyDown() && blockState.getBlock() instanceof net.minecraft.world.level.block.SlabBlock && ((net.minecraft.world.level.block.SlabBlock) blockState.getBlock()).halfBreak(blockState, pos, this.player)) return true; // Purpur - Break individual slabs when sneaking
+ if (this.player.level().purpurConfig.slabHalfBreak && this.player.isShiftKeyDown() && state.getBlock() instanceof net.minecraft.world.level.block.SlabBlock && ((net.minecraft.world.level.block.SlabBlock) state.getBlock()).halfBreak(state, pos, this.player)) return true; // Purpur - Break individual slabs when sneaking
}
// CraftBukkit end

View File

@@ -161,7 +161,7 @@
if (event.getLogWarning())
// Paper end
- LOGGER.warn("{} moved wrongly!", this.player.getPlainTextName());
+ LOGGER.warn("{} moved wrongly!, ({})", this.player.getPlainTextName(), verticalDelta); // Purpur - AFK API
+ LOGGER.warn("{} moved wrongly!, ({})", this.player.getPlainTextName(), oyDist); // Purpur - AFK API
} // Paper
}

View File

@@ -6,7 +6,7 @@
if (!event.isCancelled()) {
- player.getFoodData().eat(event.getFoodLevel() - oldFoodLevel, 1.0F);
+ if (player.level().purpurConfig.playerBurpWhenFull && event.getFoodLevel() == 20 && oldFoodLevel < 20) player.burpDelay = player.level().purpurConfig.playerBurpDelay; // Purpur - Burp delay
+ player.getFoodData().eat(event.getFoodLevel() - oldFoodLevel, entity.level().purpurConfig.humanSaturationRegenAmount); // Purpur - Config MobEffect by world
+ player.getFoodData().eat(event.getFoodLevel() - oldFoodLevel, mob.level().purpurConfig.humanSaturationRegenAmount); // Purpur - Config MobEffect by world
}
((org.bukkit.craftbukkit.entity.CraftPlayer) player.getBukkitEntity()).sendHealthUpdate();

View File

@@ -19,7 +19,7 @@
public int tickCount;
private int remainingFireTicks;
private final EntityFluidInteraction fluidInteraction = new EntityFluidInteraction(Set.of(FluidTags.WATER, FluidTags.LAVA));
@@ -374,13 +_,13 @@
@@ -374,8 +_,8 @@
public @Nullable PortalProcessor portalProcess;
public int portalCooldown;
private boolean invulnerable;
@@ -30,12 +30,6 @@
private boolean hasGlowingTag;
private final Set<String> tags = new io.papermc.paper.util.SizeLimitedSet<>(new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>(), MAX_ENTITY_TAG_COUNT); // Paper - fully limit tag size - replace set impl
private final double[] pistonDeltas = new double[]{0.0, 0.0, 0.0};
private long pistonDeltasGameTime;
- protected EntityDimensions dimensions;
+ private EntityDimensions dimensions;
private float eyeHeight;
public boolean isInPowderSnow;
public boolean wasInPowderSnow;
@@ -426,6 +_,7 @@
private final int despawnTime; // Paper - entity despawn time limit
public int totalEntityAge; // Paper - age-like counter for all entities

View File

@@ -1,14 +1,5 @@
--- a/net/minecraft/world/entity/EntityType.java
+++ b/net/minecraft/world/entity/EntityType.java
@@ -1221,7 +_,7 @@
private final String descriptionId;
private @Nullable Component description;
private final Optional<ResourceKey<LootTable>> lootTable;
- public EntityDimensions dimensions;
+ private final EntityDimensions dimensions;
private final float spawnDimensionsScale;
private final FeatureFlagSet requiredFeatures;
private final boolean allowedInPeaceful;
@@ -1238,6 +_,16 @@
return register(vanillaEntityId(vanillaId), builder);
}

View File

@@ -66,7 +66,7 @@
+ if (entityliving.hasEffect(MobEffects.BLINDNESS)) {
+ int amplifier = entityliving.getEffect(MobEffects.BLINDNESS).getAmplifier();
+ for (int i = 0; i < amplifier; i++) {
+ d *= this.level().purpurConfig.mobsBlindnessMultiplier;
+ amplifier *= this.level().purpurConfig.mobsBlindnessMultiplier;
+ }
+ }
+ }
@@ -87,7 +87,7 @@
}
+ // Purpur start - One Punch Man!
+ if (damageSource.getEntity() instanceof net.minecraft.world.entity.player.Player player && damageSource.getEntity().level().purpurConfig.creativeOnePunch && !damageSource.is(DamageTypeTags.IS_PROJECTILE)) {
+ 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) -> {
@@ -98,7 +98,7 @@
+
+ if (attackDamage.doubleValue() == 0.0D) {
+ // One punch!
+ amount = 9999F;
+ damage = 9999F;
+ }
+ }
+ }
@@ -163,15 +163,6 @@
this.hurt(this.damageSources().flyIntoWall(), dmg);
}
}
@@ -3860,7 +_,7 @@
}
}
- public boolean canGlide() {
+ protected boolean canGlide() {
if (!this.onGround() && !this.isPassenger() && !this.hasEffect(MobEffects.LEVITATION)) {
for (EquipmentSlot slot : EquipmentSlot.VALUES) {
if (canGlideUsing(this.getItemBySlot(slot), slot)) {
@@ -4748,6 +_,12 @@
? slot == EquipmentSlot.MAINHAND && this.canUseSlot(EquipmentSlot.MAINHAND)
: slot == equippable.slot() && this.canUseSlot(equippable.slot()) && equippable.canBeEquippedBy(this.typeHolder());

View File

@@ -5,7 +5,7 @@
BlockPos fromPos = fromNode.asBlockPos();
BlockState fromState = level.getBlockState(fromPos);
- if (fromState.is(BlockTags.MOB_INTERACTABLE_DOORS, s -> s.getBlock() instanceof DoorBlock)) {
+ if (fromState.is(BlockTags.MOB_INTERACTABLE_DOORS, s -> s.getBlock() instanceof DoorBlock)&& !DoorBlock.requiresRedstone(entity.level(), blockState, blockPos)) { // Purpur - Option to make doors require redstone
+ if (fromState.is(BlockTags.MOB_INTERACTABLE_DOORS, s -> s.getBlock() instanceof DoorBlock)&& !DoorBlock.requiresRedstone(body.level(), fromState, fromPos)) { // Purpur - Option to make doors require redstone
DoorBlock fromBlock = (DoorBlock)fromState.getBlock();
if (!fromBlock.isOpen(fromState)) {
// CraftBukkit start - entities opening doors
@@ -14,7 +14,7 @@
BlockPos toPos = toNode.asBlockPos();
BlockState toState = level.getBlockState(toPos);
- if (toState.is(BlockTags.MOB_INTERACTABLE_DOORS, s -> s.getBlock() instanceof DoorBlock)) {
+ if (toState.is(BlockTags.MOB_INTERACTABLE_DOORS, s -> s.getBlock() instanceof DoorBlock) && !DoorBlock.requiresRedstone(entity.level(), blockState1, blockPos1)) { // Purpur - Option to make doors require redstone
+ if (toState.is(BlockTags.MOB_INTERACTABLE_DOORS, s -> s.getBlock() instanceof DoorBlock) && !DoorBlock.requiresRedstone(body.level(), toState, toPos)) { // Purpur - Option to make doors require redstone
DoorBlock door = (DoorBlock)toState.getBlock();
if (!door.isOpen(toState)) {
// CraftBukkit start - entities opening doors
@@ -23,7 +23,7 @@
} else {
BlockState state = level.getBlockState(doorPos);
- if (!state.is(BlockTags.MOB_INTERACTABLE_DOORS, s -> s.getBlock() instanceof DoorBlock)) {
+ if (!state.is(BlockTags.MOB_INTERACTABLE_DOORS, s -> s.getBlock() instanceof DoorBlock) || DoorBlock.requiresRedstone(entity.level(), blockState, blockPos)) { // Purpur - Option to make doors require redstone
+ if (!state.is(BlockTags.MOB_INTERACTABLE_DOORS, s -> s.getBlock() instanceof DoorBlock) || DoorBlock.requiresRedstone(body.level(), state, doorPos)) { // Purpur - Option to make doors require redstone
iterator.remove();
} else {
DoorBlock block = (DoorBlock)state.getBlock();

View File

@@ -27,7 +27,7 @@
private boolean isWantedBlock(final PathfinderMob mob, final BlockState block) {
- return isPickingUpItems(mob) ? this.sourceBlockType.test(block) : this.destinationBlockType.test(block);
+ return isPickingUpItems(mob) ? this.sourceBlockType.test(block) : (mob.level().purpurConfig.copperGolemCanOpenBarrel && state.is(net.minecraft.world.level.block.Blocks.BARREL)) || (mob.level().purpurConfig.copperGolemCanOpenShulker && state.is(net.minecraft.tags.BlockTags.SHULKER_BOXES)) || this.destinationBlockType.test(block); // Purpur - copper golem can place items in barrels or shulkers option
+ return isPickingUpItems(mob) ? this.sourceBlockType.test(block) : (mob.level().purpurConfig.copperGolemCanOpenBarrel && block.is(net.minecraft.world.level.block.Blocks.BARREL)) || (mob.level().purpurConfig.copperGolemCanOpenShulker && block.is(net.minecraft.tags.BlockTags.SHULKER_BOXES)) || this.destinationBlockType.test(block); // Purpur - copper golem can place items in barrels or shulkers option
}
private static double getInteractionRange(final PathfinderMob body) {

View File

@@ -14,8 +14,8 @@
player.setItemInHand(hand, bucketOrMilkBucket);
return InteractionResult.SUCCESS;
+ // Purpur start - Cows eat mushrooms - feed mushroom to change to mooshroom
+ } else if (level().purpurConfig.cowFeedMushrooms > 0 && this.getType() != EntityType.MOOSHROOM && isMushroom(itemInHand)) {
+ return this.feedMushroom(player, itemInHand);
+ } else if (level().purpurConfig.cowFeedMushrooms > 0 && this.getType() != EntityType.MOOSHROOM && isMushroom(itemStack)) {
+ return this.feedMushroom(player, itemStack);
+ // Purpur end - Cows eat mushrooms
} else {
return super.mobInteract(player, hand);

View File

@@ -49,10 +49,10 @@
return InteractionResult.SUCCESS;
+ // Purpur start - Snowman drop and put back pumpkin
+ } else if (level().purpurConfig.snowGolemPutPumpkinBack && !hasPumpkin() && itemInHand.getItem() == Blocks.CARVED_PUMPKIN.asItem()) {
+ } else if (level().purpurConfig.snowGolemPutPumpkinBack && !hasPumpkin() && itemStack.getItem() == Blocks.CARVED_PUMPKIN.asItem()) {
+ setPumpkin(true);
+ if (!player.getAbilities().instabuild) {
+ itemInHand.shrink(1);
+ itemStack.shrink(1);
+ }
+ return InteractionResult.SUCCESS;
+ // Purpur end - Snowman drop and put back pumpkin

View File

@@ -30,7 +30,7 @@
@Override
public boolean isFood(final ItemStack itemStack) {
- return false;
+ return this.level().purpurConfig.parrotBreedable && stack.is(ItemTags.PARROT_FOOD); // Purpur - Breedable parrots
+ return this.level().purpurConfig.parrotBreedable && itemStack.is(ItemTags.PARROT_FOOD); // Purpur - Breedable parrots
}
public static boolean checkParrotSpawnRules(
@@ -39,7 +39,7 @@
@Override
public boolean canMate(final Animal partner) {
- return false;
+ return super.canMate(otherAnimal); // Purpur - Breedable parrots
+ return super.canMate(partner); // Purpur - Breedable parrots
}
@Override

View File

@@ -142,7 +142,7 @@
this.tryToTame(player);
return InteractionResult.SUCCESS_SERVER;
+ // Purpur start - Configurable chance for wolves to spawn rabid
+ } else if (this.level().purpurConfig.wolfMilkCuresRabies && itemInHand.getItem() == Items.MILK_BUCKET && this.isRabid()) {
+ } else if (this.level().purpurConfig.wolfMilkCuresRabies && itemStack.getItem() == Items.MILK_BUCKET && this.isRabid()) {
+ if (!player.isCreative()) {
+ player.setItemInHand(hand, new ItemStack(Items.BUCKET));
+ }

View File

@@ -22,17 +22,18 @@
if (!this.canTick) {
if (this.noTickEquipmentDirty) {
this.noTickEquipmentDirty = false;
@@ -809,4 +_,18 @@
@@ -809,4 +_,19 @@
}
}
// Paper end
+
+ // Purpur start - Movement options for armor stands
+ @Override
+ public void updateInWaterStateAndDoWaterCurrentPushing() {
+ protected boolean updateFluidInteraction() {
+ if (this.level().purpurConfig.armorstandWaterMovement &&
+ (this.level().purpurConfig.armorstandWaterFence || !(level().getBlockState(blockPosition().below()).getBlock() instanceof net.minecraft.world.level.block.FenceBlock)))
+ super.updateInWaterStateAndDoWaterCurrentPushing();
+ return super.updateFluidInteraction();
+ return false;
+ }
+
+ @Override

View File

@@ -7,14 +7,14 @@
+
+ // Purpur start - Shears can defuse TNT
+ @Override
+ public net.minecraft.world.InteractionResult interact(net.minecraft.world.entity.player.Player player, net.minecraft.world.InteractionHand hand) {
+ public net.minecraft.world.InteractionResult interact(final net.minecraft.world.entity.player.Player player, final net.minecraft.world.InteractionHand hand, final net.minecraft.world.phys.Vec3 location) {
+ Level world = this.level();
+
+ if (world instanceof ServerLevel serverWorld && level().purpurConfig.shearsCanDefuseTnt) {
+ final net.minecraft.world.item.ItemStack inHand = player.getItemInHand(hand);
+
+ if (!inHand.is(net.minecraft.world.item.Items.SHEARS) || !player.getBukkitEntity().hasPermission("purpur.tnt.defuse") ||
+ serverWorld.random.nextFloat() > serverWorld.purpurConfig.shearsCanDefuseTntChance) return net.minecraft.world.InteractionResult.PASS;
+ serverWorld.getRandom().nextFloat() > serverWorld.purpurConfig.shearsCanDefuseTntChance) return net.minecraft.world.InteractionResult.PASS;
+
+ net.minecraft.world.entity.item.ItemEntity tntItem = new net.minecraft.world.entity.item.ItemEntity(serverWorld, getX(), getY(), getZ(),
+ new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.TNT));
@@ -29,7 +29,7 @@
+ return net.minecraft.world.InteractionResult.SUCCESS;
+ }
+
+ return super.interact(player, hand);
+ return super.interact(player, hand, location);
+ }
+ // Purpur end - Shears can defuse TNT
}

View File

@@ -22,7 +22,7 @@
public boolean hurtServer(final ServerLevel level, final DamageSource source, final float damage) {
if (this.isInvulnerableTo(level, source)) {
return false;
+ } else if (org.purpurmc.purpur.PurpurConfig.endermanShortHeight && damageSource.is(net.minecraft.world.damagesource.DamageTypes.IN_WALL)) { return false; // Purpur - no suffocation damage if short height - Short enderman height
+ } else if (org.purpurmc.purpur.PurpurConfig.endermanShortHeight && source.is(net.minecraft.world.damagesource.DamageTypes.IN_WALL)) { return false; // Purpur - no suffocation damage if short height - Short enderman height
} else {
AbstractThrownPotion thrownPotion = source.getDirectEntity() instanceof AbstractThrownPotion potion ? potion : null;
if (!source.is(DamageTypeTags.IS_PROJECTILE) && thrownPotion == null) { // Paper - EndermanEscapeEvent - diff on change - below logic relies on this path covering non-projectile damage.
@@ -30,7 +30,7 @@
} else {
boolean hurtWithCleanWater = thrownPotion != null && this.hurtWithCleanWater(level, source, thrownPotion, damage);
+ if (!flag && level.purpurConfig.endermanIgnoreProjectiles) return super.hurtServer(level, damageSource, amount); // Purpur - Config to disable Enderman teleport on projectile hit
+ if (!hurtWithCleanWater && level.purpurConfig.endermanIgnoreProjectiles) return super.hurtServer(level, source, damage); // Purpur - Config to disable Enderman teleport on projectile hit
if (this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.INDIRECT)) { // Paper - EndermanEscapeEvent
for (int i = 0; i < 64; i++) {
if (this.teleport()) {

View File

@@ -1,15 +1,6 @@
--- a/net/minecraft/world/entity/monster/Shulker.java
+++ b/net/minecraft/world/entity/monster/Shulker.java
@@ -81,7 +_,7 @@
Vec3i forwardNormal = Direction.SOUTH.getUnitVec3i();
return new Vector3f(forwardNormal.getX(), forwardNormal.getY(), forwardNormal.getZ());
});
- public static final float MAX_SCALE = 3.0F;
+ private static final float MAX_SCALE = 3.0F;
private float currentPeekAmountO;
private float currentPeekAmount;
private @Nullable BlockPos clientOldAttachPosition;
@@ -94,6 +_,21 @@
@@ -94,6 +_,22 @@
this.lookControl = new Shulker.ShulkerLookControl(this);
}
@@ -17,8 +8,9 @@
+ @Override
+ protected net.minecraft.world.InteractionResult mobInteract(Player player, net.minecraft.world.InteractionHand hand) {
+ net.minecraft.world.item.ItemStack itemstack = player.getItemInHand(hand);
+ if (player.level().purpurConfig.shulkerChangeColorWithDye && itemstack.getItem() instanceof net.minecraft.world.item.DyeItem dye && dye.getDyeColor() != this.getColor()) {
+ this.setVariant(Optional.of(dye.getDyeColor()));
+ DyeColor dyeColor = itemstack.get(DataComponents.DYE);
+ if (player.level().purpurConfig.shulkerChangeColorWithDye && dyeColor != null && dyeColor != this.getColor()) {
+ this.setVariant(Optional.of(dyeColor));
+ if (!player.getAbilities().instabuild) {
+ itemstack.shrink(1);
+ }
@@ -62,7 +54,7 @@
public Optional<DyeColor> getVariant() {
- return Optional.ofNullable(this.getColor());
+ return Optional.ofNullable(this.level().purpurConfig.shulkerSpawnFromBulletRandomColor ? DyeColor.random(this.level().random) : this.getColor()); // Purpur - Shulker spawn from bullet options
+ return Optional.ofNullable(this.level().purpurConfig.shulkerSpawnFromBulletRandomColor ? DyeColor.random(this.level().getRandom()) : this.getColor()); // Purpur - Shulker spawn from bullet options
}
public @Nullable DyeColor getColor() {

View File

@@ -5,7 +5,7 @@
public InteractionResult mobInteract(final Player player, final InteractionHand hand) {
boolean hasFood = this.isFood(player.getItemInHand(hand));
+ // Purpur start
+ if (level().purpurConfig.striderGiveSaddleBack && player.isSecondaryUseActive() && !isFood && isSaddled() && !isVehicle()) {
+ if (level().purpurConfig.striderGiveSaddleBack && player.isSecondaryUseActive() && !hasFood && isSaddled() && !isVehicle()) {
+ this.setItemSlot(EquipmentSlot.SADDLE, ItemStack.EMPTY);
+ if (!player.getAbilities().instabuild) {
+ ItemStack saddle = new ItemStack(Items.SADDLE);

View File

@@ -1,7 +1,11 @@
--- a/net/minecraft/world/entity/monster/warden/WardenAi.java
+++ b/net/minecraft/world/entity/monster/warden/WardenAi.java
@@ -139,15 +_,16 @@
return ActivityData.create(
@@ -136,18 +_,19 @@
}
private static ActivityData<Warden> initFightActivity(final Warden body) {
- return ActivityData.create(
+ return ActivityData.<Warden>create( // Purpur - compiler fix - configurable warden sonic boom
Activity.FIGHT,
10,
- ImmutableList.of(
@@ -13,7 +17,7 @@
SetEntityLookTarget.create(entity -> isTarget(body, entity), (float)body.getAttributeValue(Attributes.FOLLOW_RANGE)),
SetWalkTargetFromAttackTargetIfTargetOutOfReach.create(1.2F),
- new SonicBoom(),
+ warden.level().purpurConfig.wardenCanUseSonicBoom ? new SonicBoom() : null, // Purpur - configurable warden sonic boom
+ body.level().purpurConfig.wardenCanUseSonicBoom ? new SonicBoom() : null, // Purpur - configurable warden sonic boom
MeleeAttack.create(18)
+ ).filter(java.util.Objects::nonNull).toList() // Purpur - configurable warden sonic boom
),

View File

@@ -30,7 +30,7 @@
+ }
+ if (this.level().getGameTime() % interval == 0) {
+ // offset Y for short blocks like dirt_path/farmland
+ this.isLobotomized = !(shouldCheckForTradeLocked && this.getVillagerXp() == 0) && !canTravelFrom(BlockPos.containing(this.position().x, this.getBoundingBox().minY + 0.0625D, this.position().z));
+ this.isLobotomized = !(shouldCheckForTradeLocked && this.getVillagerXp() == 0) && !canTravelFrom(net.minecraft.core.BlockPos.containing(this.position().x, this.getBoundingBox().minY + 0.0625D, this.position().z));
+
+ if (this.isLobotomized) {
+ this.notLobotomizedCount = 0;
@@ -41,11 +41,11 @@
+ return this.isLobotomized;
+ }
+
+ private boolean canTravelFrom(BlockPos pos) {
+ private boolean canTravelFrom(net.minecraft.core.BlockPos pos) {
+ return canTravelTo(pos.east()) || canTravelTo(pos.west()) || canTravelTo(pos.north()) || canTravelTo(pos.south());
+ }
+
+ private boolean canTravelTo(BlockPos pos) {
+ private boolean canTravelTo(net.minecraft.core.BlockPos pos) {
+ net.minecraft.world.level.block.state.BlockState state = this.level().getBlockStateIfLoaded(pos);
+ if (state == null) {
+ // chunk not loaded

View File

@@ -27,7 +27,7 @@
public void tick() {
+ // Purpur start - Burp delay
+ if (this.burpDelay > 0 && --this.burpDelay == 0) {
+ this.level().playSound(null, getX(), getY(), getZ(), SoundEvents.PLAYER_BURP, SoundSource.PLAYERS, 1.0F, this.level().random.nextFloat() * 0.1F + 0.9F);
+ this.level().playSound(null, getX(), getY(), getZ(), SoundEvents.PLAYER_BURP, SoundSource.PLAYERS, 1.0F, this.level().getRandom().nextFloat() * 0.1F + 0.9F);
+ }
+ // Purpur end - Burp delay
+
@@ -70,15 +70,6 @@
}
float totalDamage = baseDamage + magicBoost;
@@ -1518,7 +_,7 @@
}
@Override
- public boolean canGlide() {
+ protected boolean canGlide() {
return !this.abilities.flying && super.canGlide();
}
@@ -1746,7 +_,23 @@
@Override

View File

@@ -36,7 +36,7 @@
player.removeEffect(net.minecraft.world.effect.MobEffects.RAID_OMEN);
return null;
- }
+ }if (level.purpurConfig.raidCooldownSeconds != 0) playerCooldowns.put(player.getUUID(), serverLevel.purpurConfig.raidCooldownSeconds); // Purpur - Raid cooldown setting
+ }if (level.purpurConfig.raidCooldownSeconds != 0) playerCooldowns.put(player.getUUID(), level.purpurConfig.raidCooldownSeconds); // Purpur - Raid cooldown setting
if (!raid.isStarted() && !this.raidMap.containsValue(raid)) {
this.raidMap.put(this.getUniqueId(), raid);

View File

@@ -6,8 +6,8 @@
if (!this.moveItemStackTo(stack, 0, 1, false)) {
- return ItemStack.EMPTY;
+ // Purpur start - Added the ability to add combustible items
+ if (this.isFuel(item)) {
+ if (!this.moveItemStackTo(item, 1, 2, false)) {
+ if (this.isFuel(stack)) {
+ if (!this.moveItemStackTo(stack, 1, 2, false)) {
+ return ItemStack.EMPTY;
+ }
+ }

View File

@@ -91,7 +91,7 @@
price++;
}
}
+ mutable.removeIf(removedEnchantments::contains); // Purpur - Config to allow unsafe enchants
+ enchantments.removeIf(removedEnchantments::contains); // Purpur - Config to allow unsafe enchants
- if (!compatible) {
+ if (!compatible || !canEnchant1) { // Purpur - Config to allow unsafe enchants
@@ -177,8 +177,8 @@
this.broadcastChanges();
+
+ // Purpur start - Anvil API
+ if ((this.canDoUnsafeEnchants || org.purpurmc.purpur.PurpurConfig.allowInapplicableEnchants || org.purpurmc.purpur.PurpurConfig.allowIncompatibleEnchants) && itemStack != ItemStack.EMPTY) { // Purpur - Config to allow unsafe enchants
+ ((ServerPlayer) this.player).connection.send(new ClientboundContainerSetSlotPacket(this.containerId, this.incrementStateId(), 2, itemStack));
+ if ((this.canDoUnsafeEnchants || org.purpurmc.purpur.PurpurConfig.allowInapplicableEnchants || org.purpurmc.purpur.PurpurConfig.allowIncompatibleEnchants) && result != ItemStack.EMPTY) { // Purpur - Config to allow unsafe enchants
+ ((ServerPlayer) this.player).connection.send(new ClientboundContainerSetSlotPacket(this.containerId, this.incrementStateId(), 2, result));
+ ((ServerPlayer) this.player).connection.send(new ClientboundContainerSetDataPacket(this.containerId, 0, this.cost.get()));
+ }
+ // Purpur end - Anvil API

View File

@@ -4,7 +4,7 @@
@Override
public void onTake(final Player player, final ItemStack carried) {
access.execute((level, pos) -> {
+ ItemStack itemstack = activeQuickItem == null ? stack : activeQuickItem; // Purpur - Grindstone API
+ ItemStack itemstack = activeQuickItem == null ? carried : activeQuickItem; // Purpur - Grindstone API
if (level instanceof ServerLevel) {
// Paper start - Fire BlockExpEvent on grindstone use
org.bukkit.event.block.BlockExpEvent event = new org.bukkit.event.block.BlockExpEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), this.getExperienceAmount(level));
@@ -20,7 +20,7 @@
Holder<Enchantment> enchant = entry.getKey();
int lvl = entry.getIntValue();
- if (!enchant.is(EnchantmentTags.CURSE)) {
+ if (!org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(holder.value())) { // Purpur - Config for grindstones
+ if (!org.purpurmc.purpur.PurpurConfig.grindstoneIgnoredEnchants.contains(enchant.value())) { // Purpur - Config for grindstones
amount += enchant.value().getMinCost(lvl);
}
}
@@ -130,7 +130,7 @@
return ItemStack.EMPTY;
}
+ this.activeQuickItem = itemStack; // Purpur - Grindstone API
+ this.activeQuickItem = clicked; // Purpur - Grindstone API
slot.onTake(player, item);
+ this.activeQuickItem = null; // Purpur - Grindstone API
}

View File

@@ -27,7 +27,7 @@
+ // Purpur start - Tool actionable options
+ level.setBlock(pos, state, Block.UPDATE_ALL_IMMEDIATE);
+ actionable.drops().forEach((drop, chance) -> {
+ if (level.random.nextDouble() < chance) {
+ if (level.getRandom().nextDouble() < chance) {
+ Block.popResourceFromFace(level, pos, context.getClickedFace(), new ItemStack(drop));
+ }
+ });

View File

@@ -10,7 +10,7 @@
+ if (level.purpurConfig.persistentTileEntityLore) {
+ BlockEntity blockEntity1 = level.getBlockEntity(pos);
+ if (blockEntity1 != null) {
+ blockEntity1.setPersistentLore(stack.getOrDefault(DataComponents.LORE, net.minecraft.world.item.component.ItemLore.EMPTY));
+ blockEntity1.setPersistentLore(itemStack.getOrDefault(DataComponents.LORE, net.minecraft.world.item.component.ItemLore.EMPTY));
+ }
+ }
+ return handled;

View File

@@ -13,7 +13,7 @@
0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F)
);
player.awardStat(Stats.ITEM_USED.get(this));
+ player.getCooldowns().addCooldown(itemInHand, player.getAbilities().instabuild ? level.purpurConfig.enderPearlCooldownCreative : level.purpurConfig.enderPearlCooldown); // Purpur - Configurable Ender Pearl cooldown
+ player.getCooldowns().addCooldown(itemStack, player.getAbilities().instabuild ? level.purpurConfig.enderPearlCooldownCreative : level.purpurConfig.enderPearlCooldown); // Purpur - Configurable Ender Pearl cooldown
} else {
if (player instanceof net.minecraft.server.level.ServerPlayer serverPlayer) {
serverPlayer.deregisterEnderPearl(thrownEnderpearl.projectile());

View File

@@ -18,7 +18,7 @@
+ Consumer<UseOnContext> action = (ctx) -> {
+ level.setBlock(pos, tillable.into().defaultBlockState(), 11);
+ tillable.drops().forEach((drop, chance) -> {
+ if (level.random.nextDouble() < chance) {
+ if (level.getRandom().nextDouble() < chance) {
+ Block.popResourceFromFace(level, pos, ctx.getClickedFace(), new ItemStack(drop));
+ }
+ });

View File

@@ -1,11 +0,0 @@
--- a/net/minecraft/world/level/block/ShulkerBoxBlock.java
+++ b/net/minecraft/world/level/block/ShulkerBoxBlock.java
@@ -85,7 +_,7 @@
return InteractionResult.SUCCESS;
}
- public static boolean canOpen(final BlockState state, final Level level, final BlockPos pos, final ShulkerBoxBlockEntity blockEntity) {
+ private static boolean canOpen(final BlockState state, final Level level, final BlockPos pos, final ShulkerBoxBlockEntity blockEntity) {
if (blockEntity.getAnimationStatus() != ShulkerBoxBlockEntity.AnimationStatus.CLOSED) {
return true;
} else {

View File

@@ -6,7 +6,7 @@
ItemStack fuel = entity.items.get(1);
+ // Purpur start - Furnace uses lava from underneath
+ boolean usedLavaFromUnderneath = false;
+ if (level.purpurConfig.furnaceUseLavaFromUnderneath && !entity.isLit() && fuel.isEmpty() && !entity.items.get(0).isEmpty() && level.getGameTime() % 20 == 0) {
+ if (level.purpurConfig.furnaceUseLavaFromUnderneath && !isLit && fuel.isEmpty() && !entity.items.get(0).isEmpty() && level.getGameTime() % 20 == 0) {
+ BlockPos below = entity.getBlockPos().below();
+ BlockState belowState = level.getBlockStateIfLoaded(below);
+ if (belowState != null && belowState.is(net.minecraft.world.level.block.Blocks.LAVA)) {
@@ -27,7 +27,7 @@
setChanged(level, pos, state);
}
+
+ if (usedLavaFromUnderneath) furnace.items.set(1, ItemStack.EMPTY); // Purpur - Furnace uses lava from underneath
+ if (usedLavaFromUnderneath) entity.items.set(1, ItemStack.EMPTY); // Purpur - Furnace uses lava from underneath
}
private static void consumeFuel(final NonNullList<ItemStack> items, final ItemStack fuel) {

View File

@@ -30,9 +30,9 @@
}
} else {
- if (lastBeamSection == null || state.getLightDampening() >= 15 && !state.is(Blocks.BEDROCK)) {
+ if (level.purpurConfig.beaconAllowEffectsWithTintedGlass && blockState.getBlock().equals(Blocks.TINTED_GLASS)) {isTintedGlass = true;} // Purpur - allow beacon effects when covered by tinted glass
+ if (level.purpurConfig.beaconAllowEffectsWithTintedGlass && state.getBlock().equals(Blocks.TINTED_GLASS)) {isTintedGlass = true;} // Purpur - allow beacon effects when covered by tinted glass
+ // Purpur start - fix effects being applied when tinted glass is covered
+ if (lastBeamSection == null || state.getLightDampening() >= 15 && !state.is(Blocks.BEDROCK) && !(blockState.getBlock().equals(Blocks.TINTED_GLASS) && level.purpurConfig.beaconAllowEffectsWithTintedGlass)) {
+ if (lastBeamSection == null || state.getLightDampening() >= 15 && !state.is(Blocks.BEDROCK) && !(state.getBlock().equals(Blocks.TINTED_GLASS) && level.purpurConfig.beaconAllowEffectsWithTintedGlass)) {
entity.checkingBeamSections.clear();
entity.lastCheckY = lastSetBlock;
+ isTintedGlass = false;

View File

@@ -1,11 +0,0 @@
--- a/net/minecraft/world/level/block/entity/FuelValues.java
+++ b/net/minecraft/world/level/block/entity/FuelValues.java
@@ -17,7 +_,7 @@
import net.minecraft.world.level.block.Blocks;
public class FuelValues {
- public final Object2IntSortedMap<Item> values;
+ private final Object2IntSortedMap<Item> values;
private FuelValues(final Object2IntSortedMap<Item> values) {
this.values = values;

View File

@@ -1,11 +0,0 @@
--- a/net/minecraft/world/level/block/state/BlockBehaviour.java
+++ b/net/minecraft/world/level/block/state/BlockBehaviour.java
@@ -87,7 +_,7 @@
Direction.WEST, Direction.EAST, Direction.NORTH, Direction.SOUTH, Direction.DOWN, Direction.UP
};
public final boolean hasCollision;
- public float explosionResistance;
+ protected final float explosionResistance;
protected final boolean isRandomlyTicking;
protected final SoundType soundType;
protected final float friction;

View File

@@ -5,7 +5,7 @@
private static final int MIN_HEIGHT = 3;
public static final int MAX_HEIGHT = 21;
- public static final BlockBehaviour.StatePredicate FRAME = (state, level, pos) -> state.is(Blocks.OBSIDIAN);
+ private static final BlockBehaviour.StatePredicate FRAME = (state, level, pos) -> state.is(Blocks.OBSIDIAN) || (org.purpurmc.purpur.PurpurConfig.cryingObsidianValidForPortalFrame && state.is(Blocks.CRYING_OBSIDIAN)); // Purpur - Crying obsidian valid for portal frames
+ public static final BlockBehaviour.StatePredicate FRAME = (state, level, pos) -> state.is(Blocks.OBSIDIAN) || (org.purpurmc.purpur.PurpurConfig.cryingObsidianValidForPortalFrame && state.is(Blocks.CRYING_OBSIDIAN)); // Purpur - Crying obsidian valid for portal frames
private static final float SAFE_TRAVEL_MAX_ENTITY_XY = 4.0F;
private static final double SAFE_TRAVEL_MAX_VERTICAL_DELTA = 1.0;
private final Direction.Axis axis;

View File

@@ -6,7 +6,7 @@
int level = EnchantmentHelper.getEnchantmentLevel(this.enchantment, entity);
+ // Purpur start - Add an option to fix MC-3304 projectile looting
+ if (org.purpurmc.purpur.PurpurConfig.fixProjectileLootingTransfer && context.getOptionalParameter(LootContextParams.DIRECT_ATTACKING_ENTITY) instanceof net.minecraft.world.entity.projectile.arrow.AbstractArrow arrow) {
+ enchantmentLevel = arrow.actualEnchantments.getLevel(this.enchantment);
+ level = arrow.actualEnchantments.getLevel(this.enchantment);
+ }
+ // Purpur end - Add an option to fix MC-3304 projectile looting
if (level == 0) {

View File

@@ -4,11 +4,12 @@
return new AABB(this.minX, this.minY, this.minZ, this.maxX, this.maxY, this.maxZ);
}
}
- }
+
+ // Purpur start - Stop squids floating on top of water - tuinity added method
+ public final AABB offsetY(double dy) {
+ return new AABB(this.minX, this.minY + dy, this.minZ, this.maxX, this.maxY + dy, this.maxZ);
+ }
+ // Purpur end - Stop squids floating on top of water
}
+ }
+ // Purpur start - Stop squids floating on top of water - tuinity added method
+ public final AABB offsetY(double dy) {
+ return new AABB(this.minX, this.minY + dy, this.minZ, this.maxX, this.maxY + dy, this.maxZ);
+ }
+ // Purpur end - Stop squids floating on top of water
}

View File

@@ -30,7 +30,7 @@ public class SpawnerItem extends BlockItem {
CompoundTag customData = stack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag();
Optional<String> mobTypeStringOptional = customData.getString("Purpur.mob_type");
if (mobTypeStringOptional.isPresent()) {
EntityType.byString(mobTypeStringOptional.get()).ifPresent(type -> spawner.getSpawner().setEntityId(type, level, level.random, pos));
EntityType.byString(mobTypeStringOptional.get()).ifPresent(type -> spawner.getSpawner().setEntityId(type, level, level.getRandom(), pos));
} else if (customData.contains("Purpur.SpawnData")) {
customData.getCompound("Purpur.SpawnData")
.flatMap(spawnerData -> spawnerData.read("SpawnData", net.minecraft.world.level.SpawnData.CODEC))