Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions paper-api/src/main/java/org/bukkit/entity/AbstractArrow.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,29 @@
*/
public interface AbstractArrow extends Projectile {

/**
* Enables Minecraft 1.7-style flight for this arrow only. Disabled by default.
* This selects the nearest ray intersection against a constant 0.3-block
* entity margin, permits owner collision from the fifth airborne tick, and
* applies water drag after movement. Native collision, damage, visibility,
* protection and knockback events remain authoritative.
* <p>
* Launch position, initial velocity and combat balance remain the caller's
* responsibility. The setting survives chunk unloads; airborne owner-immunity
* age resets on load, as in the legacy implementation.
* Apply before insertion into the world for a complete flight.
*
* @param legacyFlight whether to use legacy flight
*/
void setLegacyFlight(boolean legacyFlight);

/**
* Returns whether this arrow uses legacy flight.
*
* @return legacy flight enabled
*/
boolean hasLegacyFlight();

/**
* Gets the knockback strength for an arrow, which is the
* {@link org.bukkit.enchantments.Enchantment#KNOCKBACK KnockBack} level
Expand Down
11 changes: 11 additions & 0 deletions paper-api/src/main/java/org/bukkit/entity/FishHook.java
Original file line number Diff line number Diff line change
Expand Up @@ -383,4 +383,15 @@ public enum HookState {
* {@link org.bukkit.inventory.ItemType#FISHING_ROD} in the specified equipment slot.
*/
int retrieve(@NotNull EquipmentSlot slot);
/**
* Enables opt-in legacy PvP flight, impact acceptance and reel equations.
* Native fishing loot, bite timers, water buoyancy and protection events remain active.
*
* @param legacyFlight whether the profile is enabled (disabled by default)
*/
void setLegacyFlight(boolean legacyFlight);

/** @return whether opt-in legacy PvP flight is enabled */
boolean hasLegacyFlight();

}
40 changes: 40 additions & 0 deletions paper-api/src/main/java/org/bukkit/entity/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,46 @@
@NullMarked
public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginMessageRecipient, net.kyori.adventure.identity.Identified, net.kyori.adventure.bossbar.BossBarViewer, com.destroystokyo.paper.network.NetworkClient, ObjectContentsLike { // Paper

/**
* Selects 1.7.10-style combat physics for this player. Disabled by default.
* Classic explosion damage uses the legacy integer curve. Small velocity
* components use the legacy cutoff and jumps replace vertical velocity. Base knockback
* halves all velocity axes even in the air, attack bonuses
* add an impulse, and melee velocity is delivered by the native tracker.
* Spear, mace-smash and shield-block impulses retain native physics.
* Native damage acceptance, resistance attributes and knockback/velocity
* events remain authoritative. This runtime setting is not persisted.
*
* @param legacyCombat whether to use legacy combat physics
*/
void setLegacyCombat(boolean legacyCombat);

/**
* Gets whether this player uses legacy combat physics.
*
* @return legacy combat physics enabled
*/
boolean hasLegacyCombat();

/**
* Controls off-hand equipment eligibility, player-inventory menu placement
* and automatic merging into stored off-hand items. Enabled by default.
* Disabling this runtime setting does not
* remove stored items or prevent their pickup. Other inventory mutations,
* hand-swap and creative actions remain governed by their native events.
* The setting is copied when this player respawns and is not persisted.
*
* @param enabled whether off-hand equipment is enabled
*/
void setOffHandEnabled(boolean enabled);

/**
* Gets whether off-hand equipment is enabled for this player.
*
* @return whether off-hand placement is enabled
*/
boolean isOffHandEnabled();

// Paper start
@Override
default net.kyori.adventure.identity.Identity identity() {
Expand Down
11 changes: 11 additions & 0 deletions paper-api/src/main/java/org/bukkit/entity/Projectile.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@
*/
public interface Projectile extends Entity {

/**
* Changes the initial position of an projectile before its native spawn attempt.
* Does not insert, teleport, replace or respawn the entity, and leaves the
* cancellable native launch/spawn transaction in control.
*
* @param position finite coordinates in this projectile's world
* @throws IllegalArgumentException if the position is invalid or in another world
* @throws IllegalStateException if the projectile has already been inserted or ticked
*/
void setPositionBeforeSpawn(@org.jetbrains.annotations.NotNull org.bukkit.Location position);

/**
* Retrieve the shooter of this projectile.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,15 @@ public interface ThrowableProjectile extends Projectile {
* @param item ItemStack set to be displayed
*/
void setItem(ItemStack item);
/**
* Enables opt-in legacy flight order, gravity, owner grace and entity intersections.
* Native impact callbacks and protection events remain active.
*
* @param legacyFlight whether the profile is enabled (disabled by default)
*/
void setLegacyFlight(boolean legacyFlight);

/** @return whether opt-in legacy flight is enabled */
boolean hasLegacyFlight();

}
Original file line number Diff line number Diff line change
Expand Up @@ -27387,7 +27387,7 @@ index 229035e15113419080187263c7fa5e004a12c3f3..550b915d4ed457231605247c3e21844f
}
}
diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java
index f11c5ea1ee9381e7bf65305b959bd7da67423ece..26822e1211194b411dd8ea75ce523133e5389e47 100644
index eb4b85405e2a0d86a26a617133720c3949ed1acd..ae76db3d2fdc806f6c64a01d364ea261420850c1 100644
--- a/net/minecraft/server/level/ServerEntity.java
+++ b/net/minecraft/server/level/ServerEntity.java
@@ -90,6 +90,11 @@ public class ServerEntity {
Expand Down Expand Up @@ -28191,7 +28191,7 @@ index 473feb1aa6ccf0f03ce0bc895de367b3e554e1bc..4fce291cb7cd6eb2f4e47237fe247a5d
"Server weather",
() -> String.format(
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index b569df775fcc9885b7cfee1b8280b68f33f4cd71..220409fd6335e17445e1acdbfac8d83ae36a99b4 100644
index f32b702bad5f5b26c484cb468218a0aa0ab1ba2c..a03d2e889b516ee6f9ace96ae1d29f18f6aebe69 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -206,7 +206,7 @@ import net.minecraft.world.scores.criteria.ObjectiveCriteria;
Expand Down Expand Up @@ -29298,7 +29298,7 @@ index 09b6da207530987b483444cebeadc2f1c9a15247..3666c3efd188508153b6482db425648e
+ // Paper end - block counting
}
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index ec8b47eebc30a73adb3195aa91fd5b82518cac2d..4b74c91b47318d048abc53952ebeae7615f50524 100644
index 80d57f833a4b5d26e5302708f8b7f41e40d71085..97f28bbdaab46357db6de27d17abb285d6745c9f 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -164,7 +164,7 @@ public abstract class Entity
Expand Down Expand Up @@ -31374,7 +31374,7 @@ index 254a967292938a9ed6a0291bbc9cf6e971eeaf01..416646f15ceea04fbbb5a5b0044c2a49

@Nullable ChunkAccess getChunkIfLoadedImmediately(int x, int z); // Paper - ifLoaded api (we need this since current impl blocks if the chunk is loading)
diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java
index def5a92046a663e53b29f9863c541ddc30ee9d3a..91bb2ac15b9e9350552f4eeb9573c2f564854ce4 100644
index d664956c4b74a84a8858939706a5b52b0765bd11..da0d74e6d5efff433b517c82bcb13c098ce54c0f 100644
--- a/net/minecraft/world/level/ServerExplosion.java
+++ b/net/minecraft/world/level/ServerExplosion.java
@@ -54,6 +54,249 @@ public class ServerExplosion implements Explosion {
Expand Down Expand Up @@ -31777,7 +31777,7 @@ index def5a92046a663e53b29f9863c541ddc30ee9d3a..91bb2ac15b9e9350552f4eeb9573c2f5
}

private void hurtEntities() {
@@ -341,6 +623,14 @@ public class ServerExplosion implements Explosion {
@@ -343,6 +625,14 @@ public class ServerExplosion implements Explosion {
}

public int explode() {
Expand All @@ -31792,7 +31792,7 @@ index def5a92046a663e53b29f9863c541ddc30ee9d3a..91bb2ac15b9e9350552f4eeb9573c2f5
this.level.gameEvent(this.source, GameEvent.EXPLODE, this.center);
List<BlockPos> toBlow = this.calculateExplodedPositions();
this.hurtEntities();
@@ -355,6 +645,13 @@ public class ServerExplosion implements Explosion {
@@ -357,6 +647,13 @@ public class ServerExplosion implements Explosion {
this.createFire(toBlow);
}

Expand All @@ -31806,7 +31806,7 @@ index def5a92046a663e53b29f9863c541ddc30ee9d3a..91bb2ac15b9e9350552f4eeb9573c2f5
return toBlow.size();
}

@@ -437,12 +734,12 @@ public class ServerExplosion implements Explosion {
@@ -439,12 +736,12 @@ public class ServerExplosion implements Explosion {
// Paper start - Optimize explosions
private float getBlockDensity(Vec3 vec3d, Entity entity) {
if (!this.level.paperConfig().environment.optimizeExplosions) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ index 0000000000000000000000000000000000000000..829f7685904fd741e00403647ae76d32
+ }
+}
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index e5328f08d6a323aa1307ed791a88916b4588939c..1afbe7a877f8055702809bc33b110bdf2933f999 100644
index 4fce291cb7cd6eb2f4e47237fe247a5d666da0ad..6cf92a7ae011fe4fa55cd744dce8d5f8fb49b1ec 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -880,6 +880,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
Expand Down Expand Up @@ -463,7 +463,7 @@ index 271ed1128959287f6c1b6ca59ded377b88f5afff..f03fa06c0ba56f7f5e1e45bc1568a490
public void tick() {
super.tick();
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index a5792bc27fdc85ecf388ab44c0b1b3055fc41d21..4a18f74c7513f0ac6a3415163165d9239ee5b567 100644
index 97f28bbdaab46357db6de27d17abb285d6745c9f..4929cc856531c07b3c7e37dc22e7de0ea44bc156 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -383,6 +383,15 @@ public abstract class Entity
Expand Down Expand Up @@ -522,10 +522,10 @@ index a5792bc27fdc85ecf388ab44c0b1b3055fc41d21..4a18f74c7513f0ac6a3415163165d923
delta = this.maybeBackOffFromEdge(delta, moverType);
Vec3 movement = this.collide(delta);
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
index 2837e630ae414bd37c4afc72c83a78e4d38a945a..3a4da514c163e7565fc241835db52c464a5c4734 100644
index 416f920e3e7e46cb5ef423373112e1ffe9fb49a1..380663766e48a9d04db732f994600f50fa304226 100644
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -3385,6 +3385,14 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
@@ -3449,6 +3449,14 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
protected void playAttackSound() {
}

Expand All @@ -541,7 +541,7 @@ index 2837e630ae414bd37c4afc72c83a78e4d38a945a..3a4da514c163e7565fc241835db52c46
public void tick() {
super.tick();
diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java
index fd17e62b99fd59130739b4c8c6c0c49122aec094..c2dd2da4bfb7d65ad2730ba1ce771e2b488beda4 100644
index a87c1343e28114f513c9f52dcc4fe7ddd04bc5bb..1b89e5909d810d9da528c3e6cc312ef93d1c9d84 100644
--- a/net/minecraft/world/entity/Mob.java
+++ b/net/minecraft/world/entity/Mob.java
@@ -215,6 +215,20 @@ public abstract class Mob extends LivingEntity implements Targeting, EquipmentUs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ index 3a6410f4b061c7431ad09b23be9691160c36ef6c..29e02b01ba7eeb7767e8dad6b3be909f
} else {
this.removePlayer(player);
diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java
index 26822e1211194b411dd8ea75ce523133e5389e47..60af82925d2f7e605bf7340cf01f1a5668f4d725 100644
index ae76db3d2fdc806f6c64a01d364ea261420850c1..8c7ee0e3122baddfde140357adf89201fa6c1a4e 100644
--- a/net/minecraft/server/level/ServerEntity.java
+++ b/net/minecraft/server/level/ServerEntity.java
@@ -89,6 +89,13 @@ public class ServerEntity {
Expand Down Expand Up @@ -95,7 +95,7 @@ index 26822e1211194b411dd8ea75ce523133e5389e47..60af82925d2f7e605bf7340cf01f1a56
|| deltaTooBig
|| this.teleportDelay > 400
|| this.wasRiding
@@ -238,6 +245,7 @@ public class ServerEntity {
@@ -239,6 +246,7 @@ public class ServerEntity {
}

this.entity.needsSync = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,17 @@
Packet<ClientGamePacketListener> packet = null;
boolean pos = positionChanged || this.tickCount % 60 == 0;
boolean sentPosition = false;
@@ -223,6 +_,25 @@
@@ -174,7 +_,8 @@
sentRotation = true;
}

- if (this.entity.needsSync || this.trackDelta || this.entity instanceof LivingEntity livingEntity && livingEntity.isFallFlying()) {
+ if (!(this.entity.hurtMarked && this.entity instanceof ServerPlayer player && player.legacyCombat)
+ && (this.entity.needsSync || this.trackDelta || this.entity instanceof LivingEntity livingEntity && livingEntity.isFallFlying())) {
Vec3 movement = this.entity.getDeltaMovement();
double diff = movement.distanceToSqr(this.lastSentMovement);
if (diff > 1.0E-7 || diff > 0.0 && movement.lengthSqr() == 0.0) {
@@ -223,6 +_,26 @@

this.tickCount++;
if (this.entity.hurtMarked) {
Expand All @@ -81,6 +91,7 @@
+ }
+
+ if (cancelled) {
+ if (this.entity instanceof ServerPlayer player && player.legacyCombat) this.entity.hurtMarked = false;
+ return;
+ }
+ // CraftBukkit end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1187,7 +1187,14 @@
}

@Override
@@ -1602,18 +_,18 @@
@@ -1596,24 +_,25 @@
}

public void restoreFrom(final ServerPlayer oldPlayer, final boolean restoreAll) {
+ this.offHandEnabled = oldPlayer.offHandEnabled; // Preserve runtime inventory capability across respawn.
this.wardenSpawnTracker = oldPlayer.wardenSpawnTracker;
this.chatSession = oldPlayer.chatSession;
this.gameMode.setGameModeForPlayer(oldPlayer.gameMode.getGameModeForPlayer(), oldPlayer.gameMode.getPreviousGameModeForPlayer());
this.onUpdateAbilities();
this.getAttributes().assignBaseValues(oldPlayer.getAttributes());
if (restoreAll) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1261,6 +1261,15 @@
}

protected boolean canAddPassenger(final Entity passenger) {
@@ -2585,7 +_,7 @@
if (!(this instanceof Player player)) {
return Vec3.ZERO;
} else {
- boolean itemOnlyInOffhand = player.getOffhandItem().is(item) && !player.getMainHandItem().is(item);
+ boolean itemOnlyInOffhand = player.canUseSlot(EquipmentSlot.OFFHAND) && player.getOffhandItem().is(item) && !player.getMainHandItem().is(item); // Paper - configurable off-hand eligibility
HumanoidArm itemArm = itemOnlyInOffhand ? player.getMainArm().getOpposite() : player.getMainArm();
return this.calculateViewVector(0.0F, this.getYRot() + (itemArm == HumanoidArm.RIGHT ? 80 : -80)).scale(0.5);
}
@@ -2704,7 +_,7 @@
}

Expand Down
Loading