Skip to content

Commit 8c18ca3

Browse files
authored
Migrate WorldBorder API to use ticks (#13223)
1 parent 19ed6da commit 8c18ca3

File tree

4 files changed

+118
-50
lines changed

4 files changed

+118
-50
lines changed

paper-api/src/main/java/io/papermc/paper/event/world/border/WorldBorderBoundsChangeEvent.java

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package io.papermc.paper.event.world.border;
22

3+
import io.papermc.paper.util.Tick;
34
import org.bukkit.World;
45
import org.bukkit.WorldBorder;
56
import org.bukkit.event.Cancellable;
67
import org.bukkit.event.HandlerList;
78
import org.jetbrains.annotations.ApiStatus;
9+
import org.jetbrains.annotations.Range;
810
import org.jspecify.annotations.NullMarked;
11+
import java.time.Duration;
912

1013
/**
1114
* Called when a world border changes its bounds, either over time, or instantly.
@@ -66,27 +69,49 @@ public void setNewSize(final double newSize) {
6669
this.newSize = Math.min(this.worldBorder.getMaxSize(), Math.max(1.0D, newSize));
6770
}
6871

72+
/**
73+
* Gets the time in ticks for the change. Will be 0 if instant.
74+
*
75+
* @return the time in ticks for the change
76+
*/
77+
public long getDurationTicks() {
78+
return this.duration;
79+
}
80+
6981
/**
7082
* Gets the time in milliseconds for the change. Will be 0 if instant.
7183
*
7284
* @return the time in milliseconds for the change
85+
* @deprecated in favor of {@link #getDurationTicks()}
7386
*/
87+
@Deprecated(forRemoval = true, since = "1.21.11")
7488
public long getDuration() {
75-
return this.duration;
89+
return Tick.of(this.duration).toMillis();
90+
}
91+
92+
/**
93+
* Sets the time in ticks for the change. Will change {@link #getType()} to return
94+
* {@link Type#STARTED_MOVE}.
95+
*
96+
* @param duration the time in ticks for the change
97+
*/
98+
public void setDurationTicks(@Range(from = 0, to = Integer.MAX_VALUE) final long duration) {
99+
this.duration = Math.clamp(duration, 0L, Integer.MAX_VALUE);
100+
if (this.type == Type.INSTANT_MOVE) {
101+
this.type = Type.STARTED_MOVE;
102+
}
76103
}
77104

78105
/**
79106
* Sets the time in milliseconds for the change. Will change {@link #getType()} to return
80107
* {@link Type#STARTED_MOVE}.
81108
*
82109
* @param duration the time in milliseconds for the change
110+
* @deprecated in favor of {@link #setDurationTicks(long)}
83111
*/
112+
@Deprecated(forRemoval = true, since = "1.21.11")
84113
public void setDuration(final long duration) {
85-
// PAIL: TODO: Magic Values
86-
this.duration = Math.min(9223372036854775L, Math.max(0L, duration));
87-
if (duration >= 0 && this.type == Type.INSTANT_MOVE) {
88-
this.type = Type.STARTED_MOVE;
89-
}
114+
this.setDurationTicks(Tick.tick().fromDuration(Duration.ofMillis(Math.clamp(duration, 0L, Integer.MAX_VALUE))));
90115
}
91116

92117
@Override
Lines changed: 69 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package org.bukkit;
22

3+
import java.time.Duration;
34
import java.util.concurrent.TimeUnit;
5+
import com.google.common.base.Preconditions;
6+
import io.papermc.paper.util.Tick;
47
import org.jetbrains.annotations.NotNull;
58
import org.jetbrains.annotations.Nullable;
69

@@ -12,20 +15,19 @@ public interface WorldBorder {
1215
* @return the associated world, or null if this world border is not associated
1316
* with any specific world, such as those created via {@link Server#createWorldBorder()}
1417
*/
15-
@Nullable
16-
public World getWorld();
18+
@Nullable World getWorld();
1719

1820
/**
1921
* Resets the border to default values.
2022
*/
21-
public void reset();
23+
void reset();
2224

2325
/**
2426
* Gets the current side length of the border.
2527
*
2628
* @return The current side length of the border.
2729
*/
28-
public double getSize();
30+
double getSize();
2931

3032
/**
3133
* Sets the border to a square region with the specified side length in blocks.
@@ -34,7 +36,7 @@ public interface WorldBorder {
3436
*
3537
* @throws IllegalArgumentException if newSize is less than 1.0D or greater than {@link #getMaxSize()}
3638
*/
37-
public void setSize(double newSize);
39+
void setSize(double newSize);
3840

3941
/**
4042
* Sets the border to a square region with the specified side length in blocks.
@@ -43,8 +45,24 @@ public interface WorldBorder {
4345
* @param seconds The time in seconds in which the border grows or shrinks from the previous size to that being set.
4446
*
4547
* @throws IllegalArgumentException if newSize is less than 1.0D or greater than {@link #getMaxSize()}
48+
* @see #setSize(double, TimeUnit, long)
49+
* @deprecated Use {@link #changeSize(double, long)} instead
4650
*/
47-
public void setSize(double newSize, long seconds);
51+
@Deprecated(since = "1.21.11", forRemoval = true)
52+
default void setSize(double newSize, long seconds) {
53+
this.setSize(Math.min(this.getMaxSize(), Math.max(1.0D, newSize)), TimeUnit.SECONDS, Math.clamp(seconds, 0L, Integer.MAX_VALUE));
54+
}
55+
56+
/**
57+
* Sets the border to a square region with the specified side length in blocks.
58+
*
59+
* @param newSize The new side length of the border.
60+
* @param ticks The time in ticks in which the border grows or shrinks from the previous size to that being set.
61+
*
62+
* @throws IllegalArgumentException if newSize is less than 1.0D or greater than {@link #getMaxSize()}
63+
* @throws IllegalArgumentException if ticks are less than 0
64+
*/
65+
void changeSize(double newSize, long ticks);
4866

4967
/**
5068
* Sets the border to a square region with the specified side length in blocks.
@@ -54,16 +72,22 @@ public interface WorldBorder {
5472
* @param time The time in which the border grows or shrinks from the previous size to that being set.
5573
*
5674
* @throws IllegalArgumentException if unit is <code>null</code> or newSize is less than 1.0D or greater than {@link #getMaxSize()}
75+
*
76+
* @see Tick
77+
* @deprecated Use {@link #changeSize(double, long)} instead
5778
*/
58-
public void setSize(double newSize, @NotNull TimeUnit unit, long time);
79+
@Deprecated(since = "1.21.11", forRemoval = true)
80+
default void setSize(double newSize, @NotNull TimeUnit unit, long time) {
81+
Preconditions.checkArgument(unit != null, "TimeUnit cannot be null.");
82+
this.changeSize(newSize, Tick.tick().fromDuration(Duration.of(time, unit.toChronoUnit())));
83+
}
5984

6085
/**
6186
* Gets the current border center.
6287
*
6388
* @return The current border center.
6489
*/
65-
@NotNull
66-
public Location getCenter();
90+
@NotNull Location getCenter();
6791

6892
/**
6993
* Sets the new border center.
@@ -73,7 +97,7 @@ public interface WorldBorder {
7397
*
7498
* @throws IllegalArgumentException if the absolute value of x or z is higher than {@link #getMaxCenterCoordinate()}
7599
*/
76-
public void setCenter(double x, double z);
100+
void setCenter(double x, double z);
77101

78102
/**
79103
* Sets the new border center.
@@ -82,84 +106,106 @@ public interface WorldBorder {
82106
*
83107
* @throws IllegalArgumentException if location is <code>null</code> or the absolute value of {@link Location#getX()} or {@link Location#getZ()} is higher than {@link #getMaxCenterCoordinate()}
84108
*/
85-
public void setCenter(@NotNull Location location);
109+
void setCenter(@NotNull Location location);
86110

87111
/**
88112
* Gets the current border damage buffer.
89113
*
90114
* @return The current border damage buffer.
91115
*/
92-
public double getDamageBuffer();
116+
double getDamageBuffer();
93117

94118
/**
95119
* Sets the amount of blocks a player may safely be outside the border before taking damage.
96120
*
97121
* @param blocks The amount of blocks. (The default is 5 blocks.)
98122
*/
99-
public void setDamageBuffer(double blocks);
123+
void setDamageBuffer(double blocks);
100124

101125
/**
102126
* Gets the current border damage amount.
103127
*
104128
* @return The current border damage amount.
105129
*/
106-
public double getDamageAmount();
130+
double getDamageAmount();
107131

108132
/**
109133
* Sets the amount of damage a player takes when outside the border plus the border buffer.
110134
*
111135
* @param damage The amount of damage. (The default is 0.2 damage per second per block.)
112136
*/
113-
public void setDamageAmount(double damage);
137+
void setDamageAmount(double damage);
114138

115139
/**
116140
* Gets the current border warning time in seconds.
117141
*
118142
* @return The current border warning time in seconds.
143+
* @deprecated Use {@link #getWarningTimeTicks()} instead
144+
*/
145+
@Deprecated(since = "1.21.11", forRemoval = true)
146+
default int getWarningTime() {
147+
return (int) Tick.of(this.getWarningTimeTicks()).toSeconds();
148+
}
149+
150+
/**
151+
* Gets the current border warning time in ticks.
152+
*
153+
* @return The current border warning time in ticks.
154+
*/
155+
int getWarningTimeTicks();
156+
157+
/**
158+
* Sets the warning time that causes the screen to be tinted red when a contracting border will reach the player within the specified time.
159+
*
160+
* @param seconds The amount of time in seconds.
161+
* @deprecated Use {@link #setWarningTimeTicks(int)} instead
119162
*/
120-
public int getWarningTime();
163+
@Deprecated(since = "1.21.11", forRemoval = true)
164+
default void setWarningTime(int seconds) {
165+
this.setWarningTimeTicks(Tick.tick().fromDuration(Duration.ofSeconds(seconds)));
166+
}
121167

122168
/**
123169
* Sets the warning time that causes the screen to be tinted red when a contracting border will reach the player within the specified time.
124170
*
125-
* @param seconds The amount of time in seconds. (The default is 15 seconds.)
171+
* @param ticks The number of ticks.
126172
*/
127-
public void setWarningTime(int seconds);
173+
void setWarningTimeTicks(int ticks);
128174

129175
/**
130176
* Gets the current border warning distance.
131177
*
132178
* @return The current border warning distance.
133179
*/
134-
public int getWarningDistance();
180+
int getWarningDistance();
135181

136182
/**
137183
* Sets the warning distance that causes the screen to be tinted red when the player is within the specified number of blocks from the border.
138184
*
139185
* @param distance The distance in blocks. (The default is 5 blocks.)
140186
*/
141-
public void setWarningDistance(int distance);
187+
void setWarningDistance(int distance);
142188

143189
/**
144190
* Check if the specified location is inside this border.
145191
*
146192
* @param location the location to check
147193
* @return if this location is inside the border or not
148194
*/
149-
public boolean isInside(@NotNull Location location);
195+
boolean isInside(@NotNull Location location);
150196

151197
/**
152198
* Gets the maximum possible size of a WorldBorder.
153199
*
154200
* @return The maximum size the WorldBorder
155201
*/
156-
public double getMaxSize();
202+
double getMaxSize();
157203

158204
/**
159205
* Gets the absolute value of the maximum x/z center coordinate of a
160206
* WorldBorder.
161207
*
162208
* @return The absolute maximum center coordinate of the WorldBorder
163209
*/
164-
public double getMaxCenterCoordinate();
210+
double getMaxCenterCoordinate();
165211
}

paper-server/patches/sources/net/minecraft/world/level/border/WorldBorder.java.patch

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
double centerZ;
55
int absoluteMaxSize = 29999984;
66
WorldBorder.BorderExtent extent = new WorldBorder.StaticBorderExtent(5.999997E7F);
7-
+ public net.minecraft.server.level.ServerLevel world; // CraftBukkit
7+
+ public net.minecraft.server.level.@org.jspecify.annotations.Nullable ServerLevel world; // CraftBukkit
88

99
public WorldBorder() {
1010
this(WorldBorder.Settings.DEFAULT);
@@ -52,8 +52,8 @@
5252
+ if (this.world != null) {
5353
+ io.papermc.paper.event.world.border.WorldBorderBoundsChangeEvent event = new io.papermc.paper.event.world.border.WorldBorderBoundsChangeEvent(world.getWorld(), world.getWorld().getWorldBorder(), io.papermc.paper.event.world.border.WorldBorderBoundsChangeEvent.Type.INSTANT_MOVE, getSize(), size, 0);
5454
+ if (!event.callEvent()) return;
55-
+ if (event.getType() == io.papermc.paper.event.world.border.WorldBorderBoundsChangeEvent.Type.STARTED_MOVE && event.getDuration() > 0) { // If changed to a timed transition
56-
+ lerpSizeBetween(event.getOldSize(), event.getNewSize(), event.getDuration(), this.world.getGameTime());
55+
+ if (event.getType() == io.papermc.paper.event.world.border.WorldBorderBoundsChangeEvent.Type.STARTED_MOVE && event.getDurationTicks() > 0) { // If changed to a timed transition
56+
+ lerpSizeBetween(event.getOldSize(), event.getNewSize(), event.getDurationTicks(), this.world.getGameTime());
5757
+ return;
5858
+ }
5959
+ size = event.getNewSize();
@@ -77,7 +77,7 @@
7777
+ io.papermc.paper.event.world.border.WorldBorderBoundsChangeEvent event = new io.papermc.paper.event.world.border.WorldBorderBoundsChangeEvent(world.getWorld(), world.getWorld().getWorldBorder(), type, oldSize, newSize, time);
7878
+ if (!event.callEvent()) return;
7979
+ newSize = event.getNewSize();
80-
+ time = event.getDuration();
80+
+ time = event.getDurationTicks();
8181
+ }
8282
+ // Paper end - Add worldborder events
8383
this.extent = (WorldBorder.BorderExtent)(oldSize == newSize
@@ -91,7 +91,7 @@
9191
this.listeners.add(listener);
9292
}
9393

94-
@@ -298,6 +_,21 @@
94+
@@ -298,6 +_,22 @@
9595
}
9696
}
9797

@@ -103,7 +103,8 @@
103103
+ this.setWarningBlocks(settings.warningBlocks());
104104
+ this.setWarningTime(settings.warningTime());
105105
+ if (settings.lerpTime() > 0L) {
106-
+ this.lerpSizeBetween(settings.size(), settings.lerpTarget(), settings.lerpTime(), this.world.getGameTime());
106+
+ final long startTime = (this.world != null) ? this.world.getGameTime() : 0; // Virtual Borders don't have a World
107+
+ this.lerpSizeBetween(settings.size(), settings.lerpTarget(), settings.lerpTime(), startTime);
107108
+ } else {
108109
+ this.setSize(settings.size());
109110
+ }

paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorldBorder.java

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package org.bukkit.craftbukkit;
22

33
import com.google.common.base.Preconditions;
4-
import java.util.concurrent.TimeUnit;
54
import net.minecraft.core.BlockPos;
65
import org.bukkit.Location;
76
import org.bukkit.World;
@@ -39,22 +38,17 @@ public double getSize() {
3938

4039
@Override
4140
public void setSize(double newSize) {
42-
this.setSize(newSize, 0L);
41+
this.changeSize(newSize, 0);
4342
}
4443

4544
@Override
46-
public void setSize(double newSize, long time) {
47-
this.setSize(Math.min(this.getMaxSize(), Math.max(1.0D, newSize)), TimeUnit.SECONDS, Math.min(9223372036854775L, Math.max(0L, time)));
48-
}
49-
50-
@Override
51-
public void setSize(double newSize, TimeUnit unit, long time) {
52-
Preconditions.checkArgument(unit != null, "TimeUnit cannot be null.");
53-
Preconditions.checkArgument(time >= 0, "time cannot be lower than 0");
45+
public void changeSize(double newSize, long ticks) {
46+
Preconditions.checkArgument(ticks >= 0, "ticks cannot be lower than 0");
5447
Preconditions.checkArgument(newSize >= 1.0D && newSize <= this.getMaxSize(), "newSize must be between 1.0D and %s", this.getMaxSize());
5548

56-
if (time > 0L) {
57-
this.handle.lerpSizeBetween(this.handle.getSize(), newSize, unit.toMillis(time), this.getWorld().getGameTime());
49+
if (ticks > 0L) {
50+
final long startTime = (this.getWorld() != null) ? this.getWorld().getGameTime() : 0; // Virtual Borders don't have a World
51+
this.handle.lerpSizeBetween(this.handle.getSize(), newSize, ticks, startTime);
5852
} else {
5953
this.handle.setSize(newSize);
6054
}
@@ -102,13 +96,15 @@ public void setDamageAmount(double damage) {
10296
}
10397

10498
@Override
105-
public int getWarningTime() {
99+
public int getWarningTimeTicks() {
106100
return this.handle.getWarningTime();
107101
}
108102

109103
@Override
110-
public void setWarningTime(int time) {
111-
this.handle.setWarningTime(time);
104+
public void setWarningTimeTicks(final int ticks) {
105+
Preconditions.checkArgument(ticks >= 0, "ticks cannot be lower than 0");
106+
107+
this.handle.setWarningTime(ticks);
112108
}
113109

114110
@Override

0 commit comments

Comments
 (0)