145 lines
11 KiB
Diff
145 lines
11 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
|
Date: Sun, 8 Mar 2026 23:56:06 +0800
|
|
Subject: [PATCH] Leaves: Creative fly no clip
|
|
|
|
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
|
As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/da12a58e8d3bd3cd13b52a60676d5a1e03acd30a/leaves-server/minecraft-patches/features/0049-Creative-fly-no-clip.patch)
|
|
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
|
|
|
diff --git a/net/minecraft/world/entity/ExperienceOrb.java b/net/minecraft/world/entity/ExperienceOrb.java
|
|
index 700c9c0d40dee1df6c97f7c63ad731f16bc5f3e7..b95c56e0699fbe16e65efcf010cd514f0ac0962f 100644
|
|
--- a/net/minecraft/world/entity/ExperienceOrb.java
|
|
+++ b/net/minecraft/world/entity/ExperienceOrb.java
|
|
@@ -204,7 +204,7 @@ public class ExperienceOrb extends Entity {
|
|
Player prevTarget = this.followingPlayer; // CraftBukkit - store old target
|
|
if (this.followingPlayer == null || this.followingPlayer.isSpectator() || this.followingPlayer.distanceToSqr(this) > 64.0) {
|
|
Player nearestPlayer = this.level().getNearestPlayer(this, 8.0);
|
|
- if (nearestPlayer != null && !nearestPlayer.isSpectator() && !nearestPlayer.isDeadOrDying()) {
|
|
+ if (nearestPlayer != null && !nearestPlayer.isCreativeFlyOrSpectator() && !nearestPlayer.isDeadOrDying()) { // Leaves - creative no clip
|
|
this.followingPlayer = nearestPlayer;
|
|
} else {
|
|
this.followingPlayer = null;
|
|
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
|
|
index f063e9b7601480d0e66da22ea8e5bec2e8619fee..d46abbea2153cac2d939416fafeac7f905fe0e02 100644
|
|
--- a/net/minecraft/world/entity/player/Player.java
|
|
+++ b/net/minecraft/world/entity/player/Player.java
|
|
@@ -284,8 +284,8 @@ public abstract class Player extends Avatar implements ContainerUser {
|
|
if (this.cullTask != null) this.cullTask.requestCullSignal(); // Luminol - Ray tracing entity tracker
|
|
// Luminol end
|
|
|
|
- this.noPhysics = this.isSpectator();
|
|
- if (this.isSpectator() || this.isPassenger()) {
|
|
+ this.noPhysics = this.isCreativeFlyOrSpectator(); // Leaves - creative no clip
|
|
+ if (this.isCreativeFlyOrSpectator() || this.isPassenger()) { // Leaves - creative no clip
|
|
this.setOnGround(false);
|
|
}
|
|
|
|
@@ -411,7 +411,7 @@ public abstract class Player extends Avatar implements ContainerUser {
|
|
if (this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.SWIMMING)) {
|
|
Pose desiredPose = this.getDesiredPose();
|
|
Pose actualPose;
|
|
- if (this.isSpectator() || this.isPassenger() || this.canPlayerFitWithinBlocksAndEntitiesWhen(desiredPose)) {
|
|
+ if (this.isCreativeFlyOrSpectator() || this.isPassenger() || this.canPlayerFitWithinBlocksAndEntitiesWhen(desiredPose)) { // Leaves - creative no clip
|
|
actualPose = desiredPose;
|
|
} else if (this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.CROUCHING)) {
|
|
actualPose = Pose.CROUCHING;
|
|
@@ -540,7 +540,7 @@ public abstract class Player extends Avatar implements ContainerUser {
|
|
this.updateSwingTime();
|
|
this.yHeadRot = this.getYRot();
|
|
this.setSpeed((float)this.getAttributeValue(Attributes.MOVEMENT_SPEED));
|
|
- if (this.getHealth() > 0.0F && !this.isSpectator()) {
|
|
+ if (this.getHealth() > 0.0F && !this.isCreativeFlyOrSpectator()) { // Leaves - creative no clip
|
|
AABB pickupArea;
|
|
if (this.isPassenger() && !this.getVehicle().isRemoved()) {
|
|
pickupArea = this.getBoundingBox().minmax(this.getVehicle().getBoundingBox()).inflate(1.0, 0.0, 1.0);
|
|
@@ -1872,6 +1872,26 @@ public abstract class Player extends Avatar implements ContainerUser {
|
|
return this.gameMode() == GameType.SPECTATOR;
|
|
}
|
|
|
|
+ // Leaves start - creative no clip
|
|
+ public boolean isCreativeFlyOrSpectator() {
|
|
+ return isSpectator() || (fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.creativeNoClip && isCreative() && getAbilities().flying);
|
|
+ }
|
|
+
|
|
+ public boolean canSpectatingPlace(final net.minecraft.world.level.LevelReader world, final BlockState state, final BlockPos pos, final net.minecraft.world.phys.shapes.CollisionContext context) {
|
|
+ if (this.isCreativeFlyOrSpectator()) {
|
|
+ net.minecraft.world.phys.shapes.VoxelShape voxelShape = state.getCollisionShape(world, pos, context);
|
|
+ return voxelShape.isEmpty() || world.isUnobstructed(this, voxelShape.move(pos.getX(), pos.getY(), pos.getZ()));
|
|
+ } else {
|
|
+ return world.isUnobstructed(state, pos, context);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isCollidable(final boolean ignoreClimbing) {
|
|
+ return !isCreativeFlyOrSpectator() && super.isCollidable(ignoreClimbing);
|
|
+ }
|
|
+ // Leaves end - creative no clip
|
|
+
|
|
@Override
|
|
public boolean isPickable() {
|
|
return !this.isSpectator() && super.isPickable();
|
|
diff --git a/net/minecraft/world/item/BlockItem.java b/net/minecraft/world/item/BlockItem.java
|
|
index f4b68c02c2beea4438cb4cd212ad70c78cfc68d3..4e31e25df5d57086027413bb5e6aa0e4f39452c7 100644
|
|
--- a/net/minecraft/world/item/BlockItem.java
|
|
+++ b/net/minecraft/world/item/BlockItem.java
|
|
@@ -160,8 +160,9 @@ public class BlockItem extends Item {
|
|
Player player = context.getPlayer();
|
|
// CraftBukkit start
|
|
Level world = context.getLevel(); // Paper - Cancel hit for vanished players
|
|
+ CollisionContext collisionContext = player == null ? CollisionContext.empty() : CollisionContext.placementContext(player); // Leaves - creative no clip
|
|
boolean canBuild = (!this.mustSurvive() || stateForPlacement.canSurvive(world, context.getClickedPos()))
|
|
- && world.checkEntityCollision(stateForPlacement, player, CollisionContext.placementContext(player), context.getClickedPos(), true); // Paper - Cancel hit for vanished players
|
|
+ && ((fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.creativeNoClip && context.getPlayer() != null) ? context.getPlayer().canSpectatingPlace(world, stateForPlacement, context.getClickedPos(), collisionContext) : world.checkEntityCollision(stateForPlacement, player, collisionContext, context.getClickedPos(), true)); // Paper - Cancel hit for vanished players // Leaves - creative no clip
|
|
org.bukkit.entity.Player bukkitPlayer = (context.getPlayer() instanceof ServerPlayer) ? (org.bukkit.entity.Player) context.getPlayer().getBukkitEntity() : null;
|
|
|
|
org.bukkit.event.block.BlockCanBuildEvent event = new org.bukkit.event.block.BlockCanBuildEvent(
|
|
diff --git a/net/minecraft/world/item/StandingAndWallBlockItem.java b/net/minecraft/world/item/StandingAndWallBlockItem.java
|
|
index 1f17f966882320b3a2ced50b3f73925cd0dfa14c..5a75df997c9026bcc740823d7039c8e426ea345a 100644
|
|
--- a/net/minecraft/world/item/StandingAndWallBlockItem.java
|
|
+++ b/net/minecraft/world/item/StandingAndWallBlockItem.java
|
|
@@ -44,7 +44,7 @@ public class StandingAndWallBlockItem extends BlockItem {
|
|
// return stateForPlacement != null && level.isUnobstructed(stateForPlacement, pos, CollisionContext.empty()) ? stateForPlacement : null;
|
|
// CraftBukkit start
|
|
if (stateForPlacement != null) {
|
|
- boolean defaultReturn = level.isUnobstructed(stateForPlacement, pos, CollisionContext.empty());
|
|
+ boolean defaultReturn = (fun.bm.lophine.carpet.config.modules.GeneralCompatConfig.creativeNoClip && context.getPlayer() != null) ? context.getPlayer().canSpectatingPlace(level, stateForPlacement, pos, CollisionContext.empty()) : level.isUnobstructed(stateForPlacement, pos, CollisionContext.empty()); // Leaves - creative no clip
|
|
org.bukkit.entity.Player player = (context.getPlayer() instanceof net.minecraft.server.level.ServerPlayer serverPlayer) ? serverPlayer.getBukkitEntity() : null;
|
|
|
|
org.bukkit.event.block.BlockCanBuildEvent event = new org.bukkit.event.block.BlockCanBuildEvent(org.bukkit.craftbukkit.block.CraftBlock.at(context.getLevel(), pos), player, stateForPlacement.asBlockData(), defaultReturn, org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(context.getHand())); // Paper - Expose hand in BlockCanBuildEvent
|
|
diff --git a/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java b/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java
|
|
index 8025fec49e6b9550d6154d6e735c6a39a2352f24..2c27de099c203b51b0fb317a8160402b3189e41c 100644
|
|
--- a/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java
|
|
+++ b/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java
|
|
@@ -153,7 +153,7 @@ public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity impl
|
|
List<Entity> entities = level.getEntities(null, aabb);
|
|
if (!entities.isEmpty()) {
|
|
for (Entity entity : entities) {
|
|
- if (entity.getPistonPushReaction() != PushReaction.IGNORE) {
|
|
+ if (entity.getPistonPushReaction() != PushReaction.IGNORE && !(entity instanceof net.minecraft.world.entity.player.Player player && player.isCreativeFlyOrSpectator())) { // Leaves - creative no clip
|
|
entity.move(
|
|
MoverType.SHULKER_BOX,
|
|
new Vec3(
|
|
diff --git a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
|
index 15605dacaec3860e476a70dbdd3743e4197f67a6..199f23547fded9b7d311b9cf21484d863748fd1c 100644
|
|
--- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
|
+++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
|
@@ -168,7 +168,7 @@ public class PistonMovingBlockEntity extends BlockEntity {
|
|
dz = movement.getStepZ();
|
|
}
|
|
|
|
- entity.setDeltaMovement(dx, dy, dz);
|
|
+ if (!(entity instanceof net.minecraft.world.entity.player.Player player) || !player.isCreativeFlyOrSpectator()) entity.setDeltaMovement(dx, dy, dz); // Leaves - creative no clip
|
|
// Paper - EAR items stuck in slime pushed by a piston
|
|
entity.activatedTick = Math.max(entity.activatedTick, io.papermc.paper.threadedregions.RegionizedServer.getCurrentTick() + 10); // Folia - region threading
|
|
entity.activatedImmunityTick = Math.max(entity.activatedImmunityTick, io.papermc.paper.threadedregions.RegionizedServer.getCurrentTick() + 10); // Folia - region threading
|
|
@@ -204,6 +204,7 @@ public class PistonMovingBlockEntity extends BlockEntity {
|
|
}
|
|
|
|
private static void moveEntityByPiston(final Direction pistonDirection, final Entity entity, final double delta, final Direction movement) {
|
|
+ if (entity instanceof net.minecraft.world.entity.player.Player player && player.isCreativeFlyOrSpectator()) return; // Leaves - creative no clip
|
|
NOCLIP.set(pistonDirection);
|
|
Vec3 previousPos = entity.position();
|
|
entity.move(MoverType.PISTON, new Vec3(delta * movement.getStepX(), delta * movement.getStepY(), delta * movement.getStepZ()));
|