-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Fixes and updates to bed events #13203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev/snapshot
Are you sure you want to change the base?
Changes from all commits
c4fbf88
a689cad
c6c5564
7d4fc6d
09a9e9d
d27c1b7
d9d97ce
9863e90
59cfe93
67954bc
ae6c1e2
6207fb1
03a043f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| package io.papermc.paper.block.bed; | ||
|
|
||
| import net.kyori.adventure.text.Component; | ||
| import org.jetbrains.annotations.ApiStatus; | ||
| import org.jspecify.annotations.Nullable; | ||
|
|
||
| /** | ||
| * An action type that represents the action that will happen after | ||
| * {@link org.bukkit.event.player.PlayerBedEnterEvent} and that is | ||
| * happening during {@link io.papermc.paper.event.player.PlayerBedFailEnterEvent} | ||
| */ | ||
| @ApiStatus.NonExtendable | ||
| @ApiStatus.Experimental | ||
| public interface BedEnterAction { | ||
|
|
||
| /** | ||
| * Gets if the player is allowed to sleep in the bed. | ||
| * This can be {@link BedRuleResult#ALLOWED} at the same time as {@link #canSetSpawn()} | ||
| * <p> | ||
| * It is advised to check for {@link BedEnterProblem}s first, as if it returns anything but {@code null} | ||
| * the bed interaction is prevented | ||
| * | ||
| * @return whether the player is allowed to sleep | ||
| */ | ||
| BedRuleResult canSleep(); | ||
|
|
||
| /** | ||
| * Gets if the player is allowed to save its spawn point in the bed. | ||
| * This can be {@link BedRuleResult#ALLOWED} at the same time as {@link #canSleep()} | ||
| * <p> | ||
| * It is advised to check for {@link BedEnterProblem}s first, as if it returns anything but {@code null} | ||
| * the bed interaction is prevented | ||
| * | ||
| * @return whether the player is allowed to save its spawn point | ||
| */ | ||
| BedRuleResult canSetSpawn(); | ||
|
|
||
| /** | ||
| * A problem is an issue that prevents the player from sleeping and from saving its spawn point. | ||
| * No problem being found doesn't mean the player successfully slept or set its spawn point, | ||
| * see {@link #canSleep()} and {@link #canSetSpawn()} for individual successes | ||
| * | ||
| * @return any of {@link BedEnterProblem}s if one is found, otherwise {@code null} | ||
| */ | ||
| @Nullable | ||
| BedEnterProblem problem(); | ||
|
|
||
| /** | ||
| * Returns the default error message to be shown as an actionbar message to the player | ||
| * | ||
| * @return the error message | ||
| */ | ||
| @Nullable | ||
| Component errorMessage(); | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| package io.papermc.paper.block.bed; | ||
|
|
||
| import java.util.Optional; | ||
| import java.util.ServiceLoader; | ||
| import org.jetbrains.annotations.ApiStatus; | ||
|
|
||
| /** | ||
| * @hidden | ||
| */ | ||
| @ApiStatus.Internal | ||
| public interface BedEnterActionBridge { | ||
|
|
||
| static BedEnterActionBridge instance() { | ||
| final class Holder { | ||
| static final Optional<BedEnterActionBridge> INSTANCE = ServiceLoader.load(BedEnterActionBridge.class, BedEnterActionBridge.class.getClassLoader()).findFirst(); | ||
| } | ||
| return Holder.INSTANCE.orElseThrow(); | ||
| } | ||
|
|
||
| BedEnterProblem createTooFarAwayProblem(); | ||
|
|
||
| BedEnterProblem createObstructedProblem(); | ||
|
|
||
| BedEnterProblem createNotSafeProblem(); | ||
|
|
||
| BedEnterProblem createExplosionProblem(); | ||
|
|
||
| BedEnterProblem createOtherProblem(); | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| package io.papermc.paper.block.bed; | ||
|
|
||
| import net.kyori.adventure.text.Component; | ||
| import org.jetbrains.annotations.ApiStatus; | ||
| import org.jspecify.annotations.Nullable; | ||
|
|
||
| /** | ||
| * Represents a problem that prevents a player from continuing | ||
| * the sleeping process, preventing it from sleeping and from setting | ||
| * its spawn point | ||
| */ | ||
| @ApiStatus.NonExtendable | ||
| @ApiStatus.Experimental | ||
| public interface BedEnterProblem { | ||
|
|
||
| /** | ||
| * Happens when the bed is too far away from the player. | ||
| * Makes no explosion and has an error message | ||
| * | ||
| * @see #errorMessage() | ||
| */ | ||
| BedEnterProblem TOO_FAR_AWAY = BedEnterActionBridge.instance().createTooFarAwayProblem(); | ||
|
|
||
| /** | ||
| * Happens when the bed has blocks one block above it. | ||
| * Makes no explosion and has an error message | ||
| * | ||
| * @see #errorMessage() | ||
| */ | ||
| BedEnterProblem OBSTRUCTED = BedEnterActionBridge.instance().createObstructedProblem(); | ||
|
|
||
| /** | ||
| * Happens when there are monsters in a 16x10x16 box centered on the bed's head | ||
| * and the player is not in creative mode. Makes no explosion and has an error message | ||
| * | ||
| * @see #errorMessage() | ||
| */ | ||
| BedEnterProblem NOT_SAFE = BedEnterActionBridge.instance().createNotSafeProblem(); | ||
|
|
||
| /** | ||
| * Happens when the bed is set to explode. This is defined in the environment attributes of the world. | ||
| * This doesn't have a fixed error message, see {@link BedEnterAction#errorMessage()} | ||
| */ | ||
| BedEnterProblem EXPLOSION = BedEnterActionBridge.instance().createExplosionProblem(); | ||
|
|
||
| /** | ||
| * Happens when a player tries to sleep when an invalid state, for example when a player tries | ||
| * to sleep but is already sleeping or is dead. | ||
| * This doesn't have an error message at all, the interaction is simply discarded | ||
| */ | ||
| BedEnterProblem OTHER = BedEnterActionBridge.instance().createOtherProblem(); | ||
|
|
||
| /** | ||
| * Returns the error message associated with this problem, if any. | ||
| * This component is sent to the client as an actionbar message | ||
| * when this problem occur | ||
| * | ||
| * @return the error message | ||
| */ | ||
| @Nullable | ||
| Component errorMessage(); | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| package io.papermc.paper.block.bed; | ||
|
|
||
| import org.jetbrains.annotations.ApiStatus; | ||
|
|
||
| /** | ||
| * Represents the result of a bed rule during {@link org.bukkit.event.player.PlayerBedEnterEvent} | ||
| * and {@link io.papermc.paper.event.player.PlayerBedFailEnterEvent}. Bed rules are responsible | ||
| * for allowing players to sleep and to set their spawn point | ||
| */ | ||
| @ApiStatus.Experimental | ||
| public sealed interface BedRuleResult permits BedRuleResultImpl { | ||
|
|
||
| /** | ||
| * Used when the bed rule is allowed | ||
| */ | ||
| BedRuleResult ALLOWED = new BedRuleResultImpl(true); | ||
|
|
||
| /** | ||
| * Used when the bed rule is denied due to there | ||
| * being too much light. This is the case during | ||
| * daytime without thunderstorms | ||
| */ | ||
| BedRuleResult TOO_MUCH_LIGHT = new BedRuleResultImpl(false); | ||
|
|
||
| /** | ||
| * Used when the bed rule is set to always be denied | ||
| */ | ||
| BedRuleResult NEVER = new BedRuleResultImpl(false); | ||
|
|
||
| /** | ||
| * Returns {@code true} if this result is a success | ||
| * | ||
| * @return whether this result is a success | ||
| */ | ||
| boolean success(); | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package io.papermc.paper.block.bed; | ||
|
|
||
| import org.jetbrains.annotations.ApiStatus; | ||
|
|
||
| /** | ||
| * @hidden | ||
| */ | ||
| @ApiStatus.Internal | ||
| record BedRuleResultImpl( | ||
| boolean success | ||
| ) implements BedRuleResult { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| @NullMarked | ||
| package io.papermc.paper.block.bed; | ||
|
|
||
| import org.jspecify.annotations.NullMarked; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| package io.papermc.paper.event.player; | ||
|
|
||
| import io.papermc.paper.block.bed.BedEnterAction; | ||
| import net.kyori.adventure.text.Component; | ||
| import org.bukkit.block.Block; | ||
| import org.bukkit.entity.Player; | ||
|
|
@@ -15,26 +16,43 @@ public class PlayerBedFailEnterEvent extends PlayerEvent implements Cancellable | |
|
|
||
| private static final HandlerList HANDLER_LIST = new HandlerList(); | ||
|
|
||
| private final FailReason failReason; | ||
| private final @Deprecated(since = "1.21.11") FailReason failReason; | ||
| private final Block bed; | ||
| private final BedEnterAction enterAction; | ||
| private boolean willExplode; | ||
| private @Nullable Component message; | ||
|
|
||
| private boolean cancelled; | ||
|
|
||
| @ApiStatus.Internal | ||
| public PlayerBedFailEnterEvent(final Player player, final FailReason failReason, final Block bed, final boolean willExplode, final @Nullable Component message) { | ||
| public PlayerBedFailEnterEvent(final Player player, final FailReason failReason, final Block bed, final boolean willExplode, final @Nullable Component message, BedEnterAction enterAction) { | ||
| super(player); | ||
| this.failReason = failReason; | ||
| this.bed = bed; | ||
| this.enterAction = enterAction; | ||
| this.willExplode = willExplode; | ||
| this.message = message; | ||
| } | ||
|
|
||
| /** | ||
| * @deprecated This enum has been replaced with a system that better | ||
| * represents how beds work. See {@link #enterAction} | ||
| */ | ||
| @Deprecated(since = "1.21.11") | ||
| public FailReason getFailReason() { | ||
| return this.failReason; | ||
| } | ||
|
|
||
| /** | ||
| * This describes the default outcome of this event. | ||
| * | ||
| * @return the action representing the default outcome of this event | ||
| */ | ||
| @ApiStatus.Experimental | ||
| public BedEnterAction enterAction() { | ||
| return this.enterAction; | ||
| } | ||
|
|
||
| public Block getBed() { | ||
| return this.bed; | ||
| } | ||
|
|
@@ -80,14 +98,17 @@ public static HandlerList getHandlerList() { | |
| return HANDLER_LIST; | ||
| } | ||
|
|
||
| /** | ||
| * @deprecated Enums no longer represents reliably how beds work and fail. This has been | ||
| * replaced with {@link BedEnterAction} that better fits the new beds | ||
| */ | ||
| @Deprecated(since = "1.21.11") | ||
| public enum FailReason { | ||
| /** | ||
| * The world doesn't allow sleeping (ex. Nether or The End). Entering | ||
| * the bed is prevented and the bed explodes. | ||
| * | ||
| * @deprecated TODO - snapshot - no longer exists in vanilla | ||
| * the bed is prevented but the bed doesn't explode. When the bed | ||
| * explodes, {@link #EXPLOSION} is used instead. | ||
| */ | ||
| @Deprecated(since = "1.21.11") | ||
| NOT_POSSIBLE_HERE, | ||
| /** | ||
| * Entering the bed is prevented due to it not being night nor | ||
|
|
@@ -96,10 +117,7 @@ public enum FailReason { | |
| * If the event is forcefully allowed during daytime, the player will | ||
| * enter the bed (and set its bed location), but might get immediately | ||
| * thrown out again. | ||
| * | ||
| * @deprecated TODO - snapshot - no longer exists in vanilla | ||
| */ | ||
| @Deprecated(since = "1.21.11") | ||
| NOT_POSSIBLE_NOW, | ||
| /** | ||
| * Entering the bed is prevented due to the player being too far away. | ||
|
|
@@ -116,6 +134,10 @@ public enum FailReason { | |
| /** | ||
| * Entering the bed is prevented due to there being monsters nearby. | ||
| */ | ||
| NOT_SAFE | ||
| NOT_SAFE, | ||
| /** | ||
| * Entering the bed is prevented and the bed explodes. | ||
| */ | ||
| EXPLOSION | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it still worth to add new values to deprecated things anyway?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't think so but since It was added before the API rework I left it there. I'm conflicted between "it's done so we may let it be" and "there's a rework so no need to modify deprecated things". I'm fine with both on this one honestly, whatever fits the needs best for the team |
||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.