mirror of
https://github.com/PaperMC/Paper.git
synced 2026-11-04 17:00:09 -05:00
Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f1fad8687 | ||
|
|
431b4245ea | ||
|
|
8f5f29305d | ||
|
|
4e8df4a990 | ||
|
|
3612df6d9c |
No files matched your search
@@ -654,6 +654,7 @@ public net.minecraft.world.level.storage.SavedDataStorage cache
|
||||
public net.minecraft.world.level.storage.TagValueInput input
|
||||
public net.minecraft.world.level.storage.loot.providers.number.ints.ResolvableInt$Reference getProvider(Lnet/minecraft/world/level/storage/loot/LootContext;)Ljava/util/Optional;
|
||||
public net.minecraft.world.scores.criteria.ObjectiveCriteria CRITERIA_CACHE
|
||||
public net.minecraft.world.timeline.Timeline tracks
|
||||
public-f net.minecraft.server.MinecraftServer storageSource
|
||||
public-f net.minecraft.server.ServerAdvancementManager advancements
|
||||
public-f net.minecraft.server.dedicated.DedicatedServer serverLinks
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package io.papermc.paper.registry.keys;
|
||||
|
||||
import static net.kyori.adventure.key.Key.key;
|
||||
|
||||
import io.papermc.paper.annotation.GeneratedClass;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.registry.TypedKey;
|
||||
import io.papermc.paper.world.Timeline;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
/**
|
||||
* Vanilla keys for {@link RegistryKey#TIMELINE}.
|
||||
*
|
||||
* @apiNote The fields provided here are a direct representation of
|
||||
* what is available from the vanilla game source. They may be
|
||||
* changed (including removals) on any Minecraft version
|
||||
* bump, so cross-version compatibility is not provided on the
|
||||
* same level as it is on most of the other API.
|
||||
*/
|
||||
@SuppressWarnings({
|
||||
"unused",
|
||||
"SpellCheckingInspection"
|
||||
})
|
||||
@NullMarked
|
||||
@GeneratedClass
|
||||
public final class TimelineKeys {
|
||||
/**
|
||||
* {@code minecraft:day}
|
||||
*
|
||||
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||
*/
|
||||
public static final TypedKey<Timeline> DAY = create(key("day"));
|
||||
|
||||
/**
|
||||
* {@code minecraft:early_game}
|
||||
*
|
||||
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||
*/
|
||||
public static final TypedKey<Timeline> EARLY_GAME = create(key("early_game"));
|
||||
|
||||
/**
|
||||
* {@code minecraft:moon}
|
||||
*
|
||||
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||
*/
|
||||
public static final TypedKey<Timeline> MOON = create(key("moon"));
|
||||
|
||||
/**
|
||||
* {@code minecraft:villager_schedule}
|
||||
*
|
||||
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||
*/
|
||||
public static final TypedKey<Timeline> VILLAGER_SCHEDULE = create(key("villager_schedule"));
|
||||
|
||||
private TimelineKeys() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a typed key for {@link Timeline} in the registry {@code minecraft:timeline}.
|
||||
*
|
||||
* @param key the value's key in the registry
|
||||
* @return a new typed key
|
||||
*/
|
||||
public static TypedKey<Timeline> create(final Key key) {
|
||||
return TypedKey.create(RegistryKey.TIMELINE, key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package io.papermc.paper.registry.keys;
|
||||
|
||||
import static net.kyori.adventure.key.Key.key;
|
||||
|
||||
import io.papermc.paper.annotation.GeneratedClass;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.registry.TypedKey;
|
||||
import io.papermc.paper.world.WorldClock;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
/**
|
||||
* Vanilla keys for {@link RegistryKey#WORLD_CLOCK}.
|
||||
*
|
||||
* @apiNote The fields provided here are a direct representation of
|
||||
* what is available from the vanilla game source. They may be
|
||||
* changed (including removals) on any Minecraft version
|
||||
* bump, so cross-version compatibility is not provided on the
|
||||
* same level as it is on most of the other API.
|
||||
*/
|
||||
@SuppressWarnings({
|
||||
"unused",
|
||||
"SpellCheckingInspection"
|
||||
})
|
||||
@NullMarked
|
||||
@GeneratedClass
|
||||
public final class WorldClockKeys {
|
||||
/**
|
||||
* {@code minecraft:overworld}
|
||||
*
|
||||
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||
*/
|
||||
public static final TypedKey<WorldClock> OVERWORLD = create(key("overworld"));
|
||||
|
||||
/**
|
||||
* {@code minecraft:the_end}
|
||||
*
|
||||
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||
*/
|
||||
public static final TypedKey<WorldClock> THE_END = create(key("the_end"));
|
||||
|
||||
private WorldClockKeys() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a typed key for {@link WorldClock} in the registry {@code minecraft:world_clock}.
|
||||
*
|
||||
* @param key the value's key in the registry
|
||||
* @return a new typed key
|
||||
*/
|
||||
public static TypedKey<WorldClock> create(final Key key) {
|
||||
return TypedKey.create(RegistryKey.WORLD_CLOCK, key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package io.papermc.paper.registry.keys.tags;
|
||||
|
||||
import static net.kyori.adventure.key.Key.key;
|
||||
|
||||
import io.papermc.paper.annotation.GeneratedClass;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.registry.tag.TagKey;
|
||||
import io.papermc.paper.world.Timeline;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
/**
|
||||
* Vanilla tag keys for {@link RegistryKey#TIMELINE}.
|
||||
*
|
||||
* @apiNote The fields provided here are a direct representation of
|
||||
* what is available from the vanilla game source. They may be
|
||||
* changed (including removals) on any Minecraft version
|
||||
* bump, so cross-version compatibility is not provided on the
|
||||
* same level as it is on most of the other API.
|
||||
*/
|
||||
@SuppressWarnings({
|
||||
"unused",
|
||||
"SpellCheckingInspection"
|
||||
})
|
||||
@NullMarked
|
||||
@GeneratedClass
|
||||
public final class TimelineTagKeys {
|
||||
/**
|
||||
* {@code #minecraft:in_end}
|
||||
*
|
||||
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||
*/
|
||||
public static final TagKey<Timeline> IN_END = create(key("in_end"));
|
||||
|
||||
/**
|
||||
* {@code #minecraft:in_nether}
|
||||
*
|
||||
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||
*/
|
||||
public static final TagKey<Timeline> IN_NETHER = create(key("in_nether"));
|
||||
|
||||
/**
|
||||
* {@code #minecraft:in_overworld}
|
||||
*
|
||||
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||
*/
|
||||
public static final TagKey<Timeline> IN_OVERWORLD = create(key("in_overworld"));
|
||||
|
||||
/**
|
||||
* {@code #minecraft:universal}
|
||||
*
|
||||
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||
*/
|
||||
public static final TagKey<Timeline> UNIVERSAL = create(key("universal"));
|
||||
|
||||
private TimelineTagKeys() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a tag key for {@link Timeline} in the registry {@code minecraft:timeline}.
|
||||
*
|
||||
* @param key the tag key's key
|
||||
* @return a new tag key
|
||||
*/
|
||||
public static TagKey<Timeline> create(final Key key) {
|
||||
return TagKey.create(RegistryKey.TIMELINE, key);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,8 @@ import io.papermc.paper.datacomponent.DataComponentType;
|
||||
import io.papermc.paper.dialog.Dialog;
|
||||
import io.papermc.paper.entity.poi.PoiType;
|
||||
import io.papermc.paper.registry.tag.TagKey;
|
||||
import io.papermc.paper.world.Timeline;
|
||||
import io.papermc.paper.world.WorldClock;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.key.KeyPattern;
|
||||
import net.kyori.adventure.key.Keyed;
|
||||
@@ -42,6 +44,7 @@ import org.bukkit.inventory.meta.trim.TrimPattern;
|
||||
import org.bukkit.map.MapCursor;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.potion.PotionType;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
import static io.papermc.paper.registry.RegistryKeyImpl.create;
|
||||
@@ -269,6 +272,16 @@ public sealed interface RegistryKey<T> extends Keyed permits RegistryKeyImpl {
|
||||
* @see io.papermc.paper.registry.keys.DialogKeys
|
||||
*/
|
||||
RegistryKey<Dialog> DIALOG = create("dialog");
|
||||
/**
|
||||
* Data-driven registry for world clocks.
|
||||
* @see io.papermc.paper.registry.keys.WorldClockKeys
|
||||
*/
|
||||
RegistryKey<WorldClock> WORLD_CLOCK = create("world_clock");
|
||||
/**
|
||||
* Data-driven registry for timelines.
|
||||
* @see io.papermc.paper.registry.keys.TimelineKeys
|
||||
*/
|
||||
RegistryKey<Timeline> TIMELINE = create("timeline");
|
||||
|
||||
|
||||
/* ******************* *
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
package io.papermc.paper.registry.data;
|
||||
|
||||
import io.papermc.paper.registry.RegistryBuilder;
|
||||
import io.papermc.paper.registry.TypedKey;
|
||||
import io.papermc.paper.world.Timeline;
|
||||
import io.papermc.paper.world.WorldClock;
|
||||
import java.util.Map;
|
||||
import java.util.OptionalInt;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.Range;
|
||||
|
||||
import static io.papermc.paper.util.BoundChecker.requireNonNegative;
|
||||
|
||||
/**
|
||||
* A data-centric version-specific registry entry for the {@link Timeline} type.
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
@ApiStatus.NonExtendable
|
||||
public interface TimelineRegistryEntry {
|
||||
|
||||
/**
|
||||
* Gets the clock that drives this timeline.
|
||||
*
|
||||
* @return the clock
|
||||
*/
|
||||
@Contract(pure = true)
|
||||
TypedKey<WorldClock> clock();
|
||||
|
||||
/**
|
||||
* Gets the timeline period, if any.
|
||||
*
|
||||
* @return the timeline period
|
||||
*/
|
||||
@Contract(pure = true)
|
||||
OptionalInt periodTicks();
|
||||
|
||||
/**
|
||||
* Gets the time markers defined by this timeline.
|
||||
*
|
||||
* @return the time markers
|
||||
*/
|
||||
@Contract(pure = true)
|
||||
Map<Key, TimeMarker> timeMarkers();
|
||||
|
||||
/**
|
||||
* A mutable builder for the {@link TimelineRegistryEntry} plugins may change in applicable registry events.
|
||||
* <p>
|
||||
* The following values are required for each builder:
|
||||
* <ul>
|
||||
* <li>{@link #clock(TypedKey)}</li>
|
||||
* </ul>
|
||||
*/
|
||||
@ApiStatus.NonExtendable
|
||||
interface Builder extends TimelineRegistryEntry, RegistryBuilder<Timeline> {
|
||||
|
||||
/**
|
||||
* Sets the clock that drives this timeline.
|
||||
*
|
||||
* @param clock the clock
|
||||
* @return this builder
|
||||
*/
|
||||
@Contract(value = "_ -> this", mutates = "this")
|
||||
Builder clock(TypedKey<WorldClock> clock);
|
||||
|
||||
/**
|
||||
* Sets the timeline period.
|
||||
*
|
||||
* @param periodTicks the period in ticks
|
||||
* @return this builder
|
||||
*/
|
||||
@Contract(value = "_ -> this", mutates = "this")
|
||||
Builder periodTicks(@Range(from = 1, to = Integer.MAX_VALUE) int periodTicks);
|
||||
|
||||
/**
|
||||
* Clears the timeline period.
|
||||
*
|
||||
* @return this builder
|
||||
*/
|
||||
@Contract(value = "-> this", mutates = "this")
|
||||
Builder clearPeriodTicks();
|
||||
|
||||
/**
|
||||
* Adds or replaces a time marker on this timeline.
|
||||
*
|
||||
* @param key the time marker key
|
||||
* @param ticks the marker tick
|
||||
* @param showInCommands whether the marker should be suggested in commands
|
||||
* @return this builder
|
||||
*/
|
||||
@Contract(value = "_, _, _ -> this", mutates = "this")
|
||||
Builder addTimeMarker(Key key, @Range(from = 0, to = Integer.MAX_VALUE) int ticks, boolean showInCommands);
|
||||
}
|
||||
|
||||
/**
|
||||
* A time marker defined by a timeline.
|
||||
*/
|
||||
@ApiStatus.NonExtendable
|
||||
interface TimeMarker {
|
||||
|
||||
/**
|
||||
* Gets the tick this marker occurs on.
|
||||
*
|
||||
* @return the marker tick
|
||||
*/
|
||||
@Range(from = 0, to = Integer.MAX_VALUE)
|
||||
int ticks();
|
||||
|
||||
/**
|
||||
* Gets whether this marker should be suggested in commands.
|
||||
*
|
||||
* @return whether the marker should be suggested in commands
|
||||
*/
|
||||
boolean showInCommands();
|
||||
|
||||
/**
|
||||
* Creates a new time marker instance based on the passed values.
|
||||
*
|
||||
* @param ticks the tick this marker occurs on, as returned by {@link #ticks()}
|
||||
* @param showInCommands whether the marker should be suggested in commands, as returned by {@link #showInCommands()}
|
||||
* @return the created instance
|
||||
*/
|
||||
@Contract(value = "_, _ -> new", pure = true)
|
||||
static TimeMarker of(@Range(from = 0, to = Integer.MAX_VALUE) final int ticks, final boolean showInCommands) {
|
||||
record Impl(int ticks, boolean showInCommands) implements TimeMarker {
|
||||
}
|
||||
|
||||
return new Impl(requireNonNegative(ticks, "ticks"), showInCommands);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package io.papermc.paper.registry.data;
|
||||
|
||||
import io.papermc.paper.registry.RegistryBuilder;
|
||||
import io.papermc.paper.world.WorldClock;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
/**
|
||||
* A data-centric version-specific registry entry for the {@link WorldClock} type.
|
||||
*/
|
||||
@ApiStatus.NonExtendable
|
||||
public interface WorldClockRegistryEntry {
|
||||
|
||||
/**
|
||||
* A mutable builder for the {@link WorldClockRegistryEntry} plugins may change in applicable registry events.
|
||||
*/
|
||||
@ApiStatus.NonExtendable
|
||||
interface Builder extends WorldClockRegistryEntry, RegistryBuilder<WorldClock> {
|
||||
}
|
||||
}
|
||||
@@ -17,11 +17,15 @@ import io.papermc.paper.registry.data.JukeboxSongRegistryEntry;
|
||||
import io.papermc.paper.registry.data.PaintingVariantRegistryEntry;
|
||||
import io.papermc.paper.registry.data.PigVariantRegistryEntry;
|
||||
import io.papermc.paper.registry.data.SulfurCubeArchetypeRegistryEntry;
|
||||
import io.papermc.paper.registry.data.TimelineRegistryEntry;
|
||||
import io.papermc.paper.registry.data.TrimMaterialRegistryEntry;
|
||||
import io.papermc.paper.registry.data.TrimPatternRegistryEntry;
|
||||
import io.papermc.paper.registry.data.WolfVariantRegistryEntry;
|
||||
import io.papermc.paper.registry.data.WorldClockRegistryEntry;
|
||||
import io.papermc.paper.registry.data.ZombieNautilusVariantRegistryEntry;
|
||||
import io.papermc.paper.registry.data.dialog.DialogRegistryEntry;
|
||||
import io.papermc.paper.world.Timeline;
|
||||
import io.papermc.paper.world.WorldClock;
|
||||
import org.bukkit.Art;
|
||||
import org.bukkit.GameEvent;
|
||||
import org.bukkit.JukeboxSong;
|
||||
@@ -68,6 +72,8 @@ public final class RegistryEvents {
|
||||
public static final RegistryEventProvider<ZombieNautilus.Variant, ZombieNautilusVariantRegistryEntry.Builder> ZOMBIE_NAUTILUS_VARIANT = create(RegistryKey.ZOMBIE_NAUTILUS_VARIANT);
|
||||
public static final RegistryEventProvider<SulfurCube.Archetype, SulfurCubeArchetypeRegistryEntry.Builder> SULFUR_CUBE_ARCHETYPE = create(RegistryKey.SULFUR_CUBE_ARCHETYPE);
|
||||
public static final RegistryEventProvider<Dialog, DialogRegistryEntry.Builder> DIALOG = create(RegistryKey.DIALOG);
|
||||
public static final RegistryEventProvider<WorldClock, WorldClockRegistryEntry.Builder> WORLD_CLOCK = create(RegistryKey.WORLD_CLOCK);
|
||||
public static final RegistryEventProvider<Timeline, TimelineRegistryEntry.Builder> TIMELINE = create(RegistryKey.TIMELINE);
|
||||
// End generate - RegistryEvents
|
||||
|
||||
private RegistryEvents() {
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package io.papermc.paper.world;
|
||||
|
||||
import io.papermc.paper.registry.RegistryAccess;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.key.KeyPattern;
|
||||
import org.bukkit.Keyed;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
/**
|
||||
* Represents a timeline that can apply environment attributes or define time markers for a {@link WorldClock}.
|
||||
*/
|
||||
@NullMarked
|
||||
@ApiStatus.NonExtendable
|
||||
public interface Timeline extends Keyed {
|
||||
|
||||
// Start generate - Timeline
|
||||
Timeline DAY = getTimeline("day");
|
||||
|
||||
Timeline EARLY_GAME = getTimeline("early_game");
|
||||
|
||||
Timeline MOON = getTimeline("moon");
|
||||
|
||||
Timeline VILLAGER_SCHEDULE = getTimeline("villager_schedule");
|
||||
// End generate - Timeline
|
||||
|
||||
private static Timeline getTimeline(@KeyPattern.Value final String key) {
|
||||
return RegistryAccess.registryAccess().getRegistry(RegistryKey.TIMELINE).getOrThrow(Key.key(Key.MINECRAFT_NAMESPACE, key));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package io.papermc.paper.world;
|
||||
|
||||
import io.papermc.paper.registry.RegistryAccess;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.key.KeyPattern;
|
||||
import org.bukkit.Keyed;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
/**
|
||||
* Represents a world clock that tracks time for worlds and drives timelines.
|
||||
*/
|
||||
@NullMarked
|
||||
@ApiStatus.NonExtendable
|
||||
public interface WorldClock extends Keyed {
|
||||
|
||||
// Start generate - WorldClock
|
||||
WorldClock OVERWORLD = getWorldClock("overworld");
|
||||
|
||||
WorldClock THE_END = getWorldClock("the_end");
|
||||
// End generate - WorldClock
|
||||
|
||||
private static WorldClock getWorldClock(@KeyPattern.Value final String key) {
|
||||
return RegistryAccess.registryAccess().getRegistry(RegistryKey.WORLD_CLOCK).getOrThrow(Key.key(Key.MINECRAFT_NAMESPACE, key));
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import io.papermc.paper.entity.poi.PoiSearchResult;
|
||||
import io.papermc.paper.entity.poi.PoiType;
|
||||
import io.papermc.paper.math.Position;
|
||||
import io.papermc.paper.raytracing.PositionedRayTraceConfigurationBuilder;
|
||||
import io.papermc.paper.world.WorldClock;
|
||||
import io.papermc.paper.world.chunk.ChunkGenerationState;
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
@@ -2116,7 +2117,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
|
||||
* @return The current relative time
|
||||
* @see #getFullTime() Returns an absolute time of this world
|
||||
*/
|
||||
public long getTime();
|
||||
long getTime();
|
||||
|
||||
/**
|
||||
* Sets the relative in-game time on the server.
|
||||
@@ -2131,7 +2132,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
|
||||
* hours*1000)
|
||||
* @see #setFullTime(long) Sets the absolute time of this world
|
||||
*/
|
||||
public void setTime(long time);
|
||||
void setTime(long time);
|
||||
|
||||
/**
|
||||
* Gets the full in-game time on this world, or {@code 0} if this world does not have a world clock.
|
||||
@@ -2139,7 +2140,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
|
||||
* @return The current absolute time
|
||||
* @see #getTime() Returns a relative time of this world
|
||||
*/
|
||||
public long getFullTime();
|
||||
long getFullTime();
|
||||
|
||||
/**
|
||||
* Sets the in-game time on the server
|
||||
@@ -2151,7 +2152,69 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
|
||||
* @see #setTime(long) Sets the relative time of this world
|
||||
* @throws IllegalArgumentException if this world does not have a world clock (e.g. the nether)
|
||||
*/
|
||||
public void setFullTime(long time);
|
||||
void setFullTime(long time);
|
||||
|
||||
/**
|
||||
* Gets the default clock of this world's dimension type.
|
||||
* <p>
|
||||
* This is the clock used by {@link #getTime()}, {@link #getFullTime()} and their setters.
|
||||
*
|
||||
* @return the default clock, or {@code null} if this world does not have one (e.g. the nether)
|
||||
*/
|
||||
@Nullable WorldClock getDefaultClock();
|
||||
|
||||
/**
|
||||
* Gets the total number of ticks the given clock has advanced in this world.
|
||||
* <p>
|
||||
* Clocks are per world unless the server is configured to share them between all worlds.
|
||||
*
|
||||
* @param clock the clock
|
||||
* @return the total ticks of the clock
|
||||
*/
|
||||
long getFullTime(@NotNull WorldClock clock);
|
||||
|
||||
/**
|
||||
* Sets the total number of ticks of the given clock in this world.
|
||||
* <p>
|
||||
* This calls a {@link org.bukkit.event.world.ClockTimeSkipEvent} and does nothing if it is cancelled.
|
||||
* Clocks are per world unless the server is configured to share them between all worlds.
|
||||
*
|
||||
* @param clock the clock
|
||||
* @param time the new total ticks of the clock, must not be negative
|
||||
*/
|
||||
void setFullTime(@NotNull WorldClock clock, long time);
|
||||
|
||||
/**
|
||||
* Gets whether the given clock is paused in this world.
|
||||
*
|
||||
* @param clock the clock
|
||||
* @return whether the clock is paused
|
||||
*/
|
||||
boolean isClockPaused(@NotNull WorldClock clock);
|
||||
|
||||
/**
|
||||
* Sets whether the given clock is paused in this world.
|
||||
*
|
||||
* @param clock the clock
|
||||
* @param paused whether the clock should be paused
|
||||
*/
|
||||
void setClockPaused(@NotNull WorldClock clock, boolean paused);
|
||||
|
||||
/**
|
||||
* Gets the rate at which the given clock advances in this world, in clock ticks per game tick.
|
||||
*
|
||||
* @param clock the clock
|
||||
* @return the clock rate
|
||||
*/
|
||||
float getClockRate(@NotNull WorldClock clock);
|
||||
|
||||
/**
|
||||
* Sets the rate at which the given clock advances in this world, in clock ticks per game tick.
|
||||
*
|
||||
* @param clock the clock
|
||||
* @param rate the new clock rate, must be positive
|
||||
*/
|
||||
void setClockRate(@NotNull WorldClock clock, float rate);
|
||||
|
||||
// Paper start
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.bukkit.event.world;
|
||||
|
||||
import io.papermc.paper.world.WorldClock;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
@@ -11,24 +12,33 @@ import org.jspecify.annotations.NullMarked;
|
||||
* <p>
|
||||
* If the event is cancelled the time will not change.
|
||||
*/
|
||||
// TODO - snapshot - 26.1 clock
|
||||
@ApiStatus.Experimental
|
||||
@NullMarked
|
||||
public class ClockTimeSkipEvent extends Event implements Cancellable {
|
||||
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
private final WorldClock clock;
|
||||
private final SkipReason skipReason;
|
||||
private long skipAmount;
|
||||
|
||||
private boolean cancelled;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public ClockTimeSkipEvent(final SkipReason skipReason, final long skipAmount) {
|
||||
public ClockTimeSkipEvent(final WorldClock clock, final SkipReason skipReason, final long skipAmount) {
|
||||
this.clock = clock;
|
||||
this.skipReason = skipReason;
|
||||
this.skipAmount = skipAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the clock whose time is skipping.
|
||||
*
|
||||
* @return the clock
|
||||
*/
|
||||
public WorldClock getClock() {
|
||||
return this.clock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the reason why the time has skipped.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.bukkit.event.world;
|
||||
|
||||
import io.papermc.paper.world.WorldClock;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -19,8 +20,8 @@ public class TimeSkipEvent extends ClockTimeSkipEvent {
|
||||
private final World world;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public TimeSkipEvent(@NotNull World world, @NotNull SkipReason skipReason, long skipAmount) {
|
||||
super(skipReason, skipAmount);
|
||||
public TimeSkipEvent(@NotNull World world, @NotNull WorldClock clock, @NotNull SkipReason skipReason, long skipAmount) {
|
||||
super(clock, skipReason, skipAmount);
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,9 @@ import io.papermc.paper.dialog.Dialog;
|
||||
import io.papermc.paper.entity.RemovalReason;
|
||||
import io.papermc.paper.entity.poi.PoiTypes;
|
||||
import io.papermc.paper.item.MapPostProcessing;
|
||||
import io.papermc.paper.world.Timeline;
|
||||
import io.papermc.paper.world.WeatheringCopperState;
|
||||
import io.papermc.paper.world.WorldClock;
|
||||
import io.papermc.typewriter.preset.EnumCloneRewriter;
|
||||
import io.papermc.typewriter.preset.model.EnumValue;
|
||||
import io.papermc.typewriter.replace.SearchMetadata;
|
||||
@@ -243,6 +245,8 @@ public final class Rewriters {
|
||||
.register("ZombieNautilusVariant", ZombieNautilus.Variant.class, new RegistryFieldRewriter<>(Registries.ZOMBIE_NAUTILUS_VARIANT, "getVariant"))
|
||||
.register("SulfurCubeArchetype", SulfurCube.Archetype.class, new RegistryFieldRewriter<>(Registries.SULFUR_CUBE_ARCHETYPE, "getArchetype"))
|
||||
.register("Dialog", Dialog.class, new RegistryFieldRewriter<>(Registries.DIALOG, "getDialog"))
|
||||
.register("WorldClock", WorldClock.class, new RegistryFieldRewriter<>(Registries.WORLD_CLOCK, "getWorldClock"))
|
||||
.register("Timeline", Timeline.class, new RegistryFieldRewriter<>(Registries.TIMELINE, "getTimeline"))
|
||||
.register("PoiTypes", PoiTypes.class, new RegistryFieldRewriter<>(Registries.POINT_OF_INTEREST_TYPE, "get"))
|
||||
.register("MemoryKey", MemoryKey.class, new MemoryKeyRewriter())
|
||||
// .register("ItemType", org.bukkit.inventory.ItemType.class, new io.papermc.generator.rewriter.types.simple.ItemTypeRewriter()) // - disable for now, lynx want the generic type
|
||||
|
||||
@@ -21,11 +21,15 @@ import io.papermc.paper.registry.data.PaintingVariantRegistryEntry;
|
||||
import io.papermc.paper.registry.data.PigVariantRegistryEntry;
|
||||
import io.papermc.paper.registry.data.SoundEventRegistryEntry;
|
||||
import io.papermc.paper.registry.data.SulfurCubeArchetypeRegistryEntry;
|
||||
import io.papermc.paper.registry.data.TimelineRegistryEntry;
|
||||
import io.papermc.paper.registry.data.TrimMaterialRegistryEntry;
|
||||
import io.papermc.paper.registry.data.TrimPatternRegistryEntry;
|
||||
import io.papermc.paper.registry.data.WolfVariantRegistryEntry;
|
||||
import io.papermc.paper.registry.data.WorldClockRegistryEntry;
|
||||
import io.papermc.paper.registry.data.ZombieNautilusVariantRegistryEntry;
|
||||
import io.papermc.paper.registry.data.dialog.DialogRegistryEntry;
|
||||
import io.papermc.paper.world.Timeline;
|
||||
import io.papermc.paper.world.WorldClock;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Type;
|
||||
@@ -45,6 +49,7 @@ import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.dialog.Dialogs;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.world.clock.WorldClocks;
|
||||
import net.minecraft.world.damagesource.DamageTypes;
|
||||
import net.minecraft.world.effect.MobEffects;
|
||||
import net.minecraft.world.entity.SulfurCubeArchetypes;
|
||||
@@ -80,6 +85,7 @@ import net.minecraft.world.level.gamerules.GameRules;
|
||||
import net.minecraft.world.level.levelgen.structure.BuiltinStructures;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
import net.minecraft.world.level.saveddata.maps.MapDecorationTypes;
|
||||
import net.minecraft.world.timeline.Timelines;
|
||||
import org.bukkit.Art;
|
||||
import org.bukkit.Fluid;
|
||||
import org.bukkit.GameEvent;
|
||||
@@ -213,7 +219,9 @@ public final class RegistryEntries {
|
||||
entry(Registries.PIG_SOUND_VARIANT, PigSoundVariants.class, Pig.SoundVariant.class),
|
||||
entry(Registries.ZOMBIE_NAUTILUS_VARIANT, ZombieNautilusVariants.class, ZombieNautilus.Variant.class).writableApiRegistryBuilder(ZombieNautilusVariantRegistryEntry.Builder.class, "PaperZombieNautilusVariantRegistryEntry.PaperBuilder"),
|
||||
entry(Registries.SULFUR_CUBE_ARCHETYPE, SulfurCubeArchetypes.class, SulfurCube.Archetype.class).writableApiRegistryBuilder(SulfurCubeArchetypeRegistryEntry.Builder.class, "PaperSulfurCubeArchetypeRegistryEntry.PaperBuilder"),
|
||||
entry(Registries.DIALOG, Dialogs.class, Dialog.class, "Paper").allowDirect().writableApiRegistryBuilder(DialogRegistryEntry.Builder.class, "PaperDialogRegistryEntry.PaperBuilder")
|
||||
entry(Registries.DIALOG, Dialogs.class, Dialog.class, "Paper").allowDirect().writableApiRegistryBuilder(DialogRegistryEntry.Builder.class, "PaperDialogRegistryEntry.PaperBuilder"),
|
||||
entry(Registries.WORLD_CLOCK, WorldClocks.class, WorldClock.class).writableApiRegistryBuilder(WorldClockRegistryEntry.Builder.class, "PaperWorldClockRegistryEntry.PaperBuilder").delayed(),
|
||||
entry(Registries.TIMELINE, Timelines.class, Timeline.class).writableApiRegistryBuilder(TimelineRegistryEntry.Builder.class, "PaperTimelineRegistryEntry.PaperBuilder").delayed()
|
||||
);
|
||||
|
||||
public static final List<RegistryEntry<?>> API_ONLY = List.of(
|
||||
|
||||
@@ -30067,7 +30067,7 @@ index e7ddd956a7f942f682f60062eecf0fad95b18749..267259a79c7668da85d206f9dcbde16b
|
||||
List<Entity> passengers = this.entity.getPassengers();
|
||||
if (!passengers.equals(this.lastPassengers)) {
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 9193fc073a6dbf0f7dcdd2b06ddf59a4e4355428..5090c9780ada3c8a7fd070bc6aec3ff1af034d73 100644
|
||||
index c4a9f7436de72d54cf67519be584f8862d289112..d7b6c1d9058df4615bf2ba807e5f3450c4c06d5a 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -183,7 +183,7 @@ import net.minecraft.world.waypoints.WaypointTransmitter;
|
||||
@@ -30489,7 +30489,7 @@ index 9193fc073a6dbf0f7dcdd2b06ddf59a4e4355428..5090c9780ada3c8a7fd070bc6aec3ff1
|
||||
this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit
|
||||
}
|
||||
|
||||
@@ -637,8 +895,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -638,8 +896,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
profiler.push("checkDespawn");
|
||||
entity.checkDespawn();
|
||||
profiler.pop();
|
||||
@@ -30499,7 +30499,7 @@ index 9193fc073a6dbf0f7dcdd2b06ddf59a4e4355428..5090c9780ada3c8a7fd070bc6aec3ff1
|
||||
Entity vehicle = entity.getVehicle();
|
||||
if (vehicle != null) {
|
||||
if (!vehicle.isRemoved() && vehicle.hasPassenger(entity)) {
|
||||
@@ -665,7 +922,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -666,7 +923,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
}
|
||||
|
||||
profiler.push("entityManagement");
|
||||
@@ -30508,7 +30508,7 @@ index 9193fc073a6dbf0f7dcdd2b06ddf59a4e4355428..5090c9780ada3c8a7fd070bc6aec3ff1
|
||||
profiler.pop();
|
||||
profiler.push("debugSynchronizers");
|
||||
if (this.debugSynchronizers.hasAnySubscriberFor(DebugSubscriptions.NEIGHBOR_UPDATES)) {
|
||||
@@ -682,7 +939,10 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -683,7 +940,10 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
|
||||
@Override
|
||||
public boolean shouldTickBlocksAt(final long chunkPos) {
|
||||
@@ -30520,7 +30520,7 @@ index 9193fc073a6dbf0f7dcdd2b06ddf59a4e4355428..5090c9780ada3c8a7fd070bc6aec3ff1
|
||||
}
|
||||
|
||||
protected void tickTime() {
|
||||
@@ -706,7 +966,60 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -707,7 +967,60 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
this.players.stream().filter(LivingEntity::isSleeping).collect(Collectors.toList()).forEach(player -> player.stopSleepInBed(false, false));
|
||||
}
|
||||
|
||||
@@ -30581,7 +30581,7 @@ index 9193fc073a6dbf0f7dcdd2b06ddf59a4e4355428..5090c9780ada3c8a7fd070bc6aec3ff1
|
||||
ChunkPos chunkPos = chunk.getPos();
|
||||
int minX = chunkPos.getMinBlockX();
|
||||
int minZ = chunkPos.getMinBlockZ();
|
||||
@@ -715,7 +1028,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -716,7 +1029,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
|
||||
if (!this.paperConfig().environment.disableIceAndSnow) { // Paper - Option to disable ice and snow
|
||||
for (int i = 0; i < tickSpeed; i++) {
|
||||
@@ -30590,7 +30590,7 @@ index 9193fc073a6dbf0f7dcdd2b06ddf59a4e4355428..5090c9780ada3c8a7fd070bc6aec3ff1
|
||||
this.tickPrecipitation(this.getBlockRandomPos(minX, 0, minZ, 15));
|
||||
}
|
||||
}
|
||||
@@ -723,31 +1036,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -724,31 +1037,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
|
||||
profiler.popPush("tickBlocks");
|
||||
if (tickSpeed > 0) {
|
||||
@@ -30623,7 +30623,7 @@ index 9193fc073a6dbf0f7dcdd2b06ddf59a4e4355428..5090c9780ada3c8a7fd070bc6aec3ff1
|
||||
}
|
||||
|
||||
profiler.pop();
|
||||
@@ -1070,6 +1359,12 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -1071,6 +1360,12 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
if (fluidState.is(type)) {
|
||||
fluidState.tick(this, pos, blockState);
|
||||
}
|
||||
@@ -30636,7 +30636,7 @@ index 9193fc073a6dbf0f7dcdd2b06ddf59a4e4355428..5090c9780ada3c8a7fd070bc6aec3ff1
|
||||
}
|
||||
|
||||
private void tickBlock(final BlockPos pos, final Block type) {
|
||||
@@ -1077,6 +1372,12 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -1078,6 +1373,12 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
if (state.is(type)) {
|
||||
state.tick(this, pos, this.random);
|
||||
}
|
||||
@@ -30649,7 +30649,7 @@ index 9193fc073a6dbf0f7dcdd2b06ddf59a4e4355428..5090c9780ada3c8a7fd070bc6aec3ff1
|
||||
}
|
||||
|
||||
// Paper start - log detailed entity tick information
|
||||
@@ -1157,6 +1458,11 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -1158,6 +1459,11 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
}
|
||||
|
||||
public void save(final @Nullable ProgressListener progressListener, final boolean flush, final boolean noSave) {
|
||||
@@ -30661,7 +30661,7 @@ index 9193fc073a6dbf0f7dcdd2b06ddf59a4e4355428..5090c9780ada3c8a7fd070bc6aec3ff1
|
||||
ServerChunkCache chunkSource = this.getChunkSource();
|
||||
if (!noSave) {
|
||||
new org.bukkit.event.world.WorldSaveEvent(this.getWorld()).callEvent(); // CraftBukkit
|
||||
@@ -1169,13 +1475,18 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -1170,13 +1476,18 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
progressListener.progressStage(Component.translatable("menu.savingChunks"));
|
||||
}
|
||||
|
||||
@@ -30685,7 +30685,7 @@ index 9193fc073a6dbf0f7dcdd2b06ddf59a4e4355428..5090c9780ada3c8a7fd070bc6aec3ff1
|
||||
}
|
||||
|
||||
private void saveLevelData(final boolean sync) {
|
||||
@@ -1296,7 +1607,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -1297,7 +1608,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
this.removePlayerImmediately((ServerPlayer)existing, Entity.RemovalReason.DISCARDED);
|
||||
}
|
||||
|
||||
@@ -30694,7 +30694,7 @@ index 9193fc073a6dbf0f7dcdd2b06ddf59a4e4355428..5090c9780ada3c8a7fd070bc6aec3ff1
|
||||
}
|
||||
|
||||
// CraftBukkit start
|
||||
@@ -1327,7 +1638,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -1328,7 +1639,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
@@ -30703,7 +30703,7 @@ index 9193fc073a6dbf0f7dcdd2b06ddf59a4e4355428..5090c9780ada3c8a7fd070bc6aec3ff1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1338,7 +1649,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -1339,7 +1650,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
|
||||
public boolean tryAddFreshEntityWithPassengers(final Entity entity, final org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) {
|
||||
// CraftBukkit end
|
||||
@@ -30712,7 +30712,7 @@ index 9193fc073a6dbf0f7dcdd2b06ddf59a4e4355428..5090c9780ada3c8a7fd070bc6aec3ff1
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2389,7 +2700,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -2390,7 +2701,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30721,7 +30721,7 @@ index 9193fc073a6dbf0f7dcdd2b06ddf59a4e4355428..5090c9780ada3c8a7fd070bc6aec3ff1
|
||||
output.write(String.format(Locale.ROOT, "block_entity_tickers: %d\n", this.blockEntityTickers.size()));
|
||||
output.write(String.format(Locale.ROOT, "block_ticks: %d\n", this.getBlockTicks().count()));
|
||||
output.write(String.format(Locale.ROOT, "fluid_ticks: %d\n", this.getFluidTicks().count()));
|
||||
@@ -2407,13 +2718,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -2408,13 +2719,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
Path chunks = rootDir.resolve("chunks.csv");
|
||||
|
||||
try (Writer output = Files.newBufferedWriter(chunks)) {
|
||||
@@ -30737,7 +30737,7 @@ index 9193fc073a6dbf0f7dcdd2b06ddf59a4e4355428..5090c9780ada3c8a7fd070bc6aec3ff1
|
||||
}
|
||||
|
||||
Path entities = rootDir.resolve("entities.csv");
|
||||
@@ -2508,8 +2819,8 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -2509,8 +2820,8 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
Locale.ROOT,
|
||||
"players: %s, entities: %s [%s], block_entities: %d [%s], block_ticks: %d, fluid_ticks: %d, chunk_source: %s",
|
||||
this.players.size(),
|
||||
@@ -30748,7 +30748,7 @@ index 9193fc073a6dbf0f7dcdd2b06ddf59a4e4355428..5090c9780ada3c8a7fd070bc6aec3ff1
|
||||
this.blockEntityTickers.size(),
|
||||
getTypeCount(this.blockEntityTickers, TickingBlockEntity::getType),
|
||||
this.getBlockTicks().count(),
|
||||
@@ -2542,15 +2853,25 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -2543,15 +2854,25 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@Override
|
||||
public LevelEntityGetter<Entity> getEntities() {
|
||||
org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot
|
||||
@@ -30777,7 +30777,7 @@ index 9193fc073a6dbf0f7dcdd2b06ddf59a4e4355428..5090c9780ada3c8a7fd070bc6aec3ff1
|
||||
}
|
||||
|
||||
public void startTickingChunk(final LevelChunk levelChunk) {
|
||||
@@ -2567,8 +2888,8 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -2568,8 +2889,8 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
|
||||
public void waitForEntities(final ChunkPos centerChunk, final int radius) {
|
||||
List<ChunkPos> chunks = ChunkPos.rangeClosed(centerChunk, radius).toList();
|
||||
@@ -30788,7 +30788,7 @@ index 9193fc073a6dbf0f7dcdd2b06ddf59a4e4355428..5090c9780ada3c8a7fd070bc6aec3ff1
|
||||
|
||||
for (ChunkPos chunk : chunks) {
|
||||
if (!this.areEntitiesLoaded(chunk.pack())) {
|
||||
@@ -2587,28 +2908,38 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -2588,28 +2909,38 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
@@ -30833,7 +30833,7 @@ index 9193fc073a6dbf0f7dcdd2b06ddf59a4e4355428..5090c9780ada3c8a7fd070bc6aec3ff1
|
||||
}
|
||||
|
||||
public boolean anyPlayerCloseEnoughForSpawning(final BlockPos pos) {
|
||||
@@ -2625,7 +2956,10 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -2626,7 +2957,10 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
}
|
||||
|
||||
public boolean canSpawnEntitiesInChunk(final ChunkPos pos) {
|
||||
@@ -30845,7 +30845,7 @@ index 9193fc073a6dbf0f7dcdd2b06ddf59a4e4355428..5090c9780ada3c8a7fd070bc6aec3ff1
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2663,7 +2997,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -2664,7 +2998,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
public CrashReportCategory fillReportDetails(final CrashReport report) {
|
||||
CrashReportCategory category = super.fillReportDetails(report);
|
||||
WeatherData weatherData = this.getWeatherData();
|
||||
|
||||
@@ -355,10 +355,10 @@ index 0000000000000000000000000000000000000000..829f7685904fd741e00403647ae76d32
|
||||
+ }
|
||||
+}
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 5090c9780ada3c8a7fd070bc6aec3ff1af034d73..a4e6225add32df93b0d6009d98ee322941b69938 100644
|
||||
index d7b6c1d9058df4615bf2ba807e5f3450c4c06d5a..1170fb4c074c495b1a8afb4c5d50a3904b11e0f7 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -887,6 +887,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -888,6 +888,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
profiler.pop();
|
||||
}
|
||||
|
||||
@@ -366,7 +366,7 @@ index 5090c9780ada3c8a7fd070bc6aec3ff1af034d73..a4e6225add32df93b0d6009d98ee3229
|
||||
this.entityTickList
|
||||
.forEach(
|
||||
entity -> {
|
||||
@@ -1404,12 +1405,15 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -1405,12 +1406,15 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
profiler.push(entity.typeHolder()::getRegisteredName);
|
||||
profiler.incrementCounter("tickNonPassenger");
|
||||
entity.commonTick();
|
||||
@@ -383,7 +383,7 @@ index 5090c9780ada3c8a7fd070bc6aec3ff1af034d73..a4e6225add32df93b0d6009d98ee3229
|
||||
}
|
||||
// Paper start - log detailed entity tick information
|
||||
} finally {
|
||||
@@ -1420,7 +1424,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -1421,7 +1425,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
// Paper end - log detailed entity tick information
|
||||
}
|
||||
|
||||
@@ -392,7 +392,7 @@ index 5090c9780ada3c8a7fd070bc6aec3ff1af034d73..a4e6225add32df93b0d6009d98ee3229
|
||||
if (entity.isRemoved() || entity.getVehicle() != vehicle) {
|
||||
entity.stopRiding();
|
||||
} else if (entity instanceof Player || this.entityTickList.contains(entity)) {
|
||||
@@ -1428,12 +1432,21 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -1429,12 +1433,21 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
profiler.push(entity.typeHolder()::getRegisteredName);
|
||||
profiler.incrementCounter("tickPassenger");
|
||||
entity.commonTick();
|
||||
@@ -463,7 +463,7 @@ index f74837dc0be560a1601132594587bcfc22dcf778..c5a212e73c2efeb1f440778cb3f1fa6e
|
||||
public void tick() {
|
||||
super.tick();
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index bb61d4e4ecfe5bab6269fa3d4303dab95719d7bb..3d219969a55896b1495c54c0a12a25b49ba093f0 100644
|
||||
index 71ce072c2c9a6349d895054184321cb336ae567b..62d534132f6a2d69df28e244fa296f24a007181f 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -388,6 +388,15 @@ public abstract class Entity
|
||||
@@ -822,7 +822,7 @@ index f46cca0467bb4da5511bc953ce5b43fa606bf978..445c5cafad71028171c1f26193966177
|
||||
+
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index d327301693c70affc866d355a08efe935e3656b4..efcf399ced67201525ea6e6b3bd46b93b7e1823d 100644
|
||||
index a828576457e0bb932750dba507bdef7e8903e144..2f5ec35bf7f104e259f85d15b17c8064daa05a5e 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -154,6 +154,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
|
||||
+2
-2
@@ -2321,7 +2321,7 @@ index 0000000000000000000000000000000000000000..505b5e39d0b4cf2a56c1c720f0c9ab01
|
||||
+ }
|
||||
+}
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index bc2bacabb588bd6a644ac5226720c7451ac0e475..e4d38cfdac2b926afae3b1b96679b6ce45ea256a 100644
|
||||
index 1170fb4c074c495b1a8afb4c5d50a3904b11e0f7..3560df07024e4423835bb724318fcea2adfd4cfe 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -238,6 +238,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -2332,7 +2332,7 @@ index bc2bacabb588bd6a644ac5226720c7451ac0e475..e4d38cfdac2b926afae3b1b96679b6ce
|
||||
|
||||
@Override
|
||||
public @Nullable LevelChunk getChunkIfLoaded(int x, int z) {
|
||||
@@ -3040,6 +3041,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -3041,6 +3042,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
return this.debugSynchronizers;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,10 +83,10 @@ index 07ba0aeefec186d7befe60c86dc5180e3131de51..482b428cab996c19664b57c341c55db5
|
||||
ProfilerFiller profiler = Profiler.get();
|
||||
this.server.spark.executeMainThreadTasks(); // Paper - spark
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index e197ac0ee5e49d7768a9de889c972b3d590f7951..85ab77c3d1d5420df648fd173eaf5ad4f4775a80 100644
|
||||
index 3560df07024e4423835bb724318fcea2adfd4cfe..377c4373785ec5c14a7d7ce9e710c02943546fbe 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -1470,6 +1470,15 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
@@ -1471,6 +1471,15 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||
public boolean mayInteract(final Entity entity, final BlockPos pos) {
|
||||
return !(entity instanceof Player player && (this.server.isUnderSpawnProtection(this, pos, player) || !this.getWorldBorder().isWithinBounds(pos)));
|
||||
}
|
||||
|
||||
@@ -45,11 +45,11 @@
|
||||
+ // Paper start - per-world time
|
||||
+ ServerClockManager clockManager = source.getLevel().clockManager();
|
||||
+ long currentTotalTicks = clockManager.getInstance(clock).totalTicks();
|
||||
+ org.bukkit.event.world.ClockTimeSkipEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.createTimeSkipEvent(source, totalTicks - currentTotalTicks);
|
||||
+ org.bukkit.event.world.ClockTimeSkipEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.createTimeSkipEvent(source, clock, totalTicks - currentTotalTicks);
|
||||
+ final long newTotalTicks;
|
||||
+ if (event.callEvent()) {
|
||||
+ newTotalTicks = currentTotalTicks + event.getSkipAmount();
|
||||
+ clockManager.setTotalTicks(clock, newTotalTicks);
|
||||
+ final boolean cancelled = !event.callEvent();
|
||||
+ if (!cancelled) {
|
||||
+ newTotalTicks = Math.max(currentTotalTicks + event.getSkipAmount(), 0L);
|
||||
+ } else {
|
||||
+ newTotalTicks = totalTicks; // just pass it through
|
||||
+ }
|
||||
@@ -60,7 +60,7 @@
|
||||
- clockManager.setTotalTicks(clock, totalTicks);
|
||||
- source.sendSuccess(() -> Component.translatable("commands.time.set.absolute", clock.getRegisteredName(), totalTicks), true);
|
||||
- return totalTicks;
|
||||
+ clockManager.setTotalTicks(clock, newTotalTicks);
|
||||
+ if (!cancelled) clockManager.setTotalTicks(clock, newTotalTicks);
|
||||
+ source.sendSuccess(() -> Component.translatable("commands.time.set.absolute", clock.getRegisteredName(), newTotalTicks), true);
|
||||
+ return wrapTime(newTotalTicks);
|
||||
+ // Paper end - per-world time
|
||||
@@ -71,7 +71,7 @@
|
||||
- clockManager.addTicks(clock, time);
|
||||
+ // Paper start - per-world time
|
||||
+ ServerClockManager clockManager = source.getLevel().clockManager();
|
||||
+ org.bukkit.event.world.ClockTimeSkipEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.createTimeSkipEvent(source, time);
|
||||
+ org.bukkit.event.world.ClockTimeSkipEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.createTimeSkipEvent(source, clock, time);
|
||||
+ if (event.callEvent()) {
|
||||
+ clockManager.addTicks(clock, event.getSkipAmount());
|
||||
+ }
|
||||
@@ -99,7 +99,7 @@
|
||||
+ if (timerMove == null) return ServerClockManager.MoveResult.NO_TIME_MARKER_FOUND;
|
||||
+
|
||||
+ // We consider it an attempted move even if the marker occurs at this point in time for event calling purposes.
|
||||
+ final org.bukkit.event.world.ClockTimeSkipEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.createTimeSkipEvent(source, timerMove.targetTime() - timerMove.currentTime());
|
||||
+ final org.bukkit.event.world.ClockTimeSkipEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.createTimeSkipEvent(source, clock, timerMove.targetTime() - timerMove.currentTime());
|
||||
+ if (!event.callEvent() || event.getSkipAmount() == 0) return ServerClockManager.MoveResult.NOT_MOVED;
|
||||
+
|
||||
+ clockManager.setTotalTicks(clock, timerMove.currentTime() + event.getSkipAmount());
|
||||
|
||||
@@ -276,7 +276,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -373,11 +_,25 @@
|
||||
@@ -373,11 +_,26 @@
|
||||
int percentage = this.getGameRules().get(GameRules.PLAYERS_SLEEPING_PERCENTAGE);
|
||||
if (this.sleepStatus.areEnoughSleeping(percentage) && this.sleepStatus.areEnoughDeepSleeping(percentage, this.players)) {
|
||||
Optional<Holder<WorldClock>> defaultClock = this.dimensionType().defaultClock();
|
||||
@@ -286,8 +286,9 @@
|
||||
+ // Paper start - per-world time
|
||||
+ ServerClockManager.TimerMove timerMove = this.clockManager().resolveTimerMove(defaultClock.get(), ClockTimeMarkers.WAKE_UP_FROM_SLEEP);
|
||||
+ if (timerMove != null) {
|
||||
+ event = new org.bukkit.event.world.TimeSkipEvent(
|
||||
+ this.getWorld(),
|
||||
+ event = org.bukkit.craftbukkit.event.CraftEventFactory.createTimeSkipEvent(
|
||||
+ this,
|
||||
+ defaultClock.get(),
|
||||
+ org.bukkit.event.world.ClockTimeSkipEvent.SkipReason.NIGHT_SKIP,
|
||||
+ timerMove.targetTime() - timerMove.currentTime()
|
||||
+ );
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
--- a/net/minecraft/world/timeline/Timeline.java
|
||||
+++ b/net/minecraft/world/timeline/Timeline.java
|
||||
@@ -142,6 +_,23 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - clock API - value equality for registry builder round-trips
|
||||
+ @Override
|
||||
+ public boolean equals(final Object o) {
|
||||
+ if (this == o) return true;
|
||||
+ if (!(o instanceof final Timeline other)) return false;
|
||||
+ return this.clock.equals(other.clock)
|
||||
+ && this.periodTicks.equals(other.periodTicks)
|
||||
+ && this.tracks.equals(other.tracks)
|
||||
+ && this.timeMarkers.equals(other.timeMarkers);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int hashCode() {
|
||||
+ return java.util.Objects.hash(this.clock, this.periodTicks, this.tracks, this.timeMarkers);
|
||||
+ }
|
||||
+ // Paper end - clock API - value equality for registry builder round-trips
|
||||
+
|
||||
public Set<EnvironmentAttribute<?>> attributes() {
|
||||
return this.tracks.keySet();
|
||||
}
|
||||
@@ -181,6 +_,13 @@
|
||||
this.tracks.put(attribute, new AttributeTrack<>(modifier, argumentTrack.build()));
|
||||
return this;
|
||||
}
|
||||
+
|
||||
+ // Paper start - clock API
|
||||
+ public Timeline.Builder addTracks(final Map<EnvironmentAttribute<?>, AttributeTrack<?, ?>> tracks) {
|
||||
+ this.tracks.putAll(tracks);
|
||||
+ return this;
|
||||
+ }
|
||||
+ // Paper end - clock API
|
||||
|
||||
public <Value> Timeline.Builder addTrack(final EnvironmentAttribute<Value> attribute, final Consumer<KeyframeTrack.Builder<Value>> builder) {
|
||||
return this.addModifierTrack(attribute, AttributeModifier.override(), builder);
|
||||
@@ -25,14 +25,18 @@ import io.papermc.paper.registry.data.PaperPaintingVariantRegistryEntry;
|
||||
import io.papermc.paper.registry.data.PaperPigVariantRegistryEntry;
|
||||
import io.papermc.paper.registry.data.PaperSoundEventRegistryEntry;
|
||||
import io.papermc.paper.registry.data.PaperSulfurCubeArchetypeRegistryEntry;
|
||||
import io.papermc.paper.registry.data.PaperTimelineRegistryEntry;
|
||||
import io.papermc.paper.registry.data.PaperTrimMaterialRegistryEntry;
|
||||
import io.papermc.paper.registry.data.PaperTrimPatternRegistryEntry;
|
||||
import io.papermc.paper.registry.data.PaperWolfVariantRegistryEntry;
|
||||
import io.papermc.paper.registry.data.PaperWorldClockRegistryEntry;
|
||||
import io.papermc.paper.registry.data.PaperZombieNautilusVariantRegistryEntry;
|
||||
import io.papermc.paper.registry.data.dialog.PaperDialogRegistryEntry;
|
||||
import io.papermc.paper.registry.entry.RegistryEntry;
|
||||
import io.papermc.paper.registry.entry.RegistryEntryMeta;
|
||||
import io.papermc.paper.registry.tag.TagKey;
|
||||
import io.papermc.paper.world.Timeline;
|
||||
import io.papermc.paper.world.WorldClock;
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
@@ -60,6 +64,8 @@ import org.bukkit.craftbukkit.CraftGameRule;
|
||||
import org.bukkit.craftbukkit.CraftJukeboxSong;
|
||||
import org.bukkit.craftbukkit.CraftMusicInstrument;
|
||||
import org.bukkit.craftbukkit.CraftSound;
|
||||
import org.bukkit.craftbukkit.CraftTimeline;
|
||||
import org.bukkit.craftbukkit.CraftWorldClock;
|
||||
import org.bukkit.craftbukkit.attribute.CraftAttribute;
|
||||
import org.bukkit.craftbukkit.block.CraftBiome;
|
||||
import org.bukkit.craftbukkit.block.CraftBlockType;
|
||||
@@ -159,6 +165,8 @@ public final class PaperRegistries {
|
||||
start(Registries.ZOMBIE_NAUTILUS_VARIANT, RegistryKey.ZOMBIE_NAUTILUS_VARIANT).craft(ZombieNautilus.Variant.class, CraftZombieNautilus.CraftVariant::new).writable(PaperZombieNautilusVariantRegistryEntry.PaperBuilder::new),
|
||||
start(Registries.SULFUR_CUBE_ARCHETYPE, RegistryKey.SULFUR_CUBE_ARCHETYPE).craft(SulfurCube.Archetype.class, CraftSulfurCube.CraftArchetype::new).writable(PaperSulfurCubeArchetypeRegistryEntry.PaperBuilder::new),
|
||||
start(Registries.DIALOG, RegistryKey.DIALOG).craft(Dialog.class, PaperDialog::new, true).writable(PaperDialogRegistryEntry.PaperBuilder::new),
|
||||
start(Registries.WORLD_CLOCK, RegistryKey.WORLD_CLOCK).craft(WorldClock.class, CraftWorldClock::new).writable(PaperWorldClockRegistryEntry.PaperBuilder::new).delayed(),
|
||||
start(Registries.TIMELINE, RegistryKey.TIMELINE).craft(Timeline.class, CraftTimeline::new).writable(PaperTimelineRegistryEntry.PaperBuilder::new).delayed(),
|
||||
|
||||
// api-only
|
||||
start(Registries.ENTITY_TYPE, RegistryKey.ENTITY_TYPE).apiOnly(PaperSimpleRegistry::entityType),
|
||||
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
package io.papermc.paper.registry.data;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import io.papermc.paper.registry.PaperRegistries;
|
||||
import io.papermc.paper.registry.PaperRegistryBuilder;
|
||||
import io.papermc.paper.registry.TypedKey;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import io.papermc.paper.world.WorldClock;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.OptionalInt;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.timeline.Timeline;
|
||||
import org.jetbrains.annotations.Range;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import static io.papermc.paper.registry.data.util.Checks.asArgument;
|
||||
import static io.papermc.paper.registry.data.util.Checks.asConfigured;
|
||||
|
||||
public class PaperTimelineRegistryEntry implements TimelineRegistryEntry {
|
||||
|
||||
protected final Conversions conversions;
|
||||
protected @Nullable Timeline internal;
|
||||
protected @Nullable Holder<net.minecraft.world.clock.WorldClock> clock;
|
||||
protected @Nullable Integer periodTicks;
|
||||
protected final Map<Key, TimeMarker> timeMarkers = new LinkedHashMap<>();
|
||||
|
||||
public PaperTimelineRegistryEntry(final Conversions conversions, final @Nullable Timeline internal) {
|
||||
this.conversions = conversions;
|
||||
this.internal = internal;
|
||||
|
||||
if (internal == null) {
|
||||
return;
|
||||
}
|
||||
this.clock = internal.clock();
|
||||
this.periodTicks = internal.periodTicks().orElse(null);
|
||||
internal.registerTimeMarkers((key, marker) -> this.timeMarkers.put(PaperAdventure.asAdventure(key.identifier()), TimeMarker.of(marker.ticks(), marker.showInCommands())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypedKey<WorldClock> clock() {
|
||||
return PaperRegistries.fromNms(asConfigured(this.clock, "clock").unwrapKey().orElseThrow());
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalInt periodTicks() {
|
||||
return this.periodTicks != null ? OptionalInt.of(this.periodTicks) : OptionalInt.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Key, TimeMarker> timeMarkers() {
|
||||
return Map.copyOf(this.timeMarkers);
|
||||
}
|
||||
|
||||
public static final class PaperBuilder extends PaperTimelineRegistryEntry implements TimelineRegistryEntry.Builder, PaperRegistryBuilder<Timeline, io.papermc.paper.world.Timeline> {
|
||||
|
||||
public PaperBuilder(final Conversions conversions, final @Nullable Timeline internal) {
|
||||
super(conversions, internal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder clock(final TypedKey<WorldClock> clock) {
|
||||
this.clock = this.conversions.getReferenceHolder(PaperRegistries.toNms(asArgument(clock, "clock")));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder periodTicks(final @Range(from = 1, to = Integer.MAX_VALUE) int periodTicks) {
|
||||
Preconditions.checkArgument(periodTicks >= 1, "periodTicks must be at least 1, was %s", periodTicks);
|
||||
this.periodTicks = periodTicks;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder clearPeriodTicks() {
|
||||
this.periodTicks = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder addTimeMarker(final Key key, final @Range(from = 0, to = Integer.MAX_VALUE) int ticks, final boolean showInCommands) {
|
||||
Preconditions.checkArgument(ticks >= 0, "ticks must be at least 0, was %s", ticks);
|
||||
this.timeMarkers.put(asArgument(key, "key"), TimeMarker.of(ticks, showInCommands));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timeline build() {
|
||||
final Timeline.Builder builder = Timeline.builder(asConfigured(this.clock, "clock"));
|
||||
if (this.periodTicks != null) {
|
||||
builder.setPeriodTicks(this.periodTicks);
|
||||
}
|
||||
if (this.internal != null) {
|
||||
builder.addTracks(this.internal.tracks);
|
||||
}
|
||||
this.timeMarkers.forEach((key, marker) -> builder.addTimeMarker(ResourceKey.create(net.minecraft.world.clock.ClockTimeMarkers.ROOT_ID, PaperAdventure.asVanilla(key)), marker.ticks(), marker.showInCommands()));
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package io.papermc.paper.registry.data;
|
||||
|
||||
import io.papermc.paper.registry.PaperRegistryBuilder;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import net.minecraft.world.clock.WorldClock;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public class PaperWorldClockRegistryEntry implements WorldClockRegistryEntry {
|
||||
|
||||
public PaperWorldClockRegistryEntry(final Conversions ignoredConversions, final @Nullable WorldClock ignoredInternal) {
|
||||
}
|
||||
|
||||
public static final class PaperBuilder extends PaperWorldClockRegistryEntry implements WorldClockRegistryEntry.Builder, PaperRegistryBuilder<WorldClock, io.papermc.paper.world.WorldClock> {
|
||||
|
||||
public PaperBuilder(final Conversions conversions, final @Nullable WorldClock internal) {
|
||||
super(conversions, internal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldClock build() {
|
||||
return new WorldClock();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import io.papermc.paper.registry.HolderableBase;
|
||||
import io.papermc.paper.world.Timeline;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
|
||||
public class CraftTimeline extends HolderableBase<net.minecraft.world.timeline.Timeline> implements Timeline {
|
||||
|
||||
public static Timeline minecraftHolderToBukkit(final Holder<net.minecraft.world.timeline.Timeline> minecraft) {
|
||||
return CraftRegistry.minecraftHolderToBukkit(minecraft, Registries.TIMELINE);
|
||||
}
|
||||
|
||||
public static Holder<net.minecraft.world.timeline.Timeline> bukkitToMinecraftHolder(final Timeline bukkit) {
|
||||
return CraftRegistry.bukkitToMinecraftHolder(bukkit);
|
||||
}
|
||||
|
||||
public CraftTimeline(final Holder<net.minecraft.world.timeline.Timeline> holder) {
|
||||
super(holder);
|
||||
}
|
||||
}
|
||||
@@ -143,7 +143,6 @@ import org.bukkit.event.weather.ThunderChangeEvent;
|
||||
import org.bukkit.event.weather.WeatherChangeEvent;
|
||||
import org.bukkit.event.world.ClockTimeSkipEvent;
|
||||
import org.bukkit.event.world.SpawnChangeEvent;
|
||||
import org.bukkit.event.world.TimeSkipEvent;
|
||||
import org.bukkit.generator.BiomeProvider;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
@@ -823,19 +822,63 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public void setFullTime(long time) {
|
||||
if (this.world.dimensionType().defaultClock().isEmpty()) {
|
||||
throw new IllegalArgumentException("Cannot set time in world without world clock");
|
||||
}
|
||||
final Holder<net.minecraft.world.clock.WorldClock> clock = this.world.dimensionType().defaultClock()
|
||||
.orElseThrow(() -> new IllegalArgumentException("Cannot set time in world without world clock"));
|
||||
this.setFullTime(clock, time);
|
||||
}
|
||||
|
||||
final long currentClockTime = this.world.getDefaultClockTime();
|
||||
final ClockTimeSkipEvent event = new TimeSkipEvent(this, ClockTimeSkipEvent.SkipReason.CUSTOM, time - currentClockTime);
|
||||
this.server.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
@Override
|
||||
public io.papermc.paper.world.@Nullable WorldClock getDefaultClock() {
|
||||
return this.world.dimensionType().defaultClock().map(CraftWorldClock::minecraftHolderToBukkit).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getFullTime(final io.papermc.paper.world.WorldClock clock) {
|
||||
Preconditions.checkArgument(clock != null, "clock cannot be null");
|
||||
return this.world.clockManager().getInstance(CraftWorldClock.bukkitToMinecraftHolder(clock)).totalTicks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFullTime(final io.papermc.paper.world.WorldClock clock, final long time) {
|
||||
Preconditions.checkArgument(clock != null, "clock cannot be null");
|
||||
this.setFullTime(CraftWorldClock.bukkitToMinecraftHolder(clock), time);
|
||||
}
|
||||
|
||||
private void setFullTime(final Holder<net.minecraft.world.clock.WorldClock> clock, final long time) {
|
||||
Preconditions.checkArgument(time >= 0, "time cannot be negative, was %s", time);
|
||||
final long currentClockTime = this.world.clockManager().getInstance(clock).totalTicks();
|
||||
final ClockTimeSkipEvent event = CraftEventFactory.createTimeSkipEvent(this.world, clock, ClockTimeSkipEvent.SkipReason.CUSTOM, time - currentClockTime);
|
||||
if (!event.callEvent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Updates the clock for all players
|
||||
this.world.clockManager().setTotalTicks(this.world.dimensionType().defaultClock().get(), currentClockTime + event.getSkipAmount());
|
||||
this.world.clockManager().setTotalTicks(clock, Math.max(currentClockTime + event.getSkipAmount(), 0L));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClockPaused(final io.papermc.paper.world.WorldClock clock) {
|
||||
Preconditions.checkArgument(clock != null, "clock cannot be null");
|
||||
return this.world.clockManager().getInstance(CraftWorldClock.bukkitToMinecraftHolder(clock)).isPaused();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClockPaused(final io.papermc.paper.world.WorldClock clock, final boolean paused) {
|
||||
Preconditions.checkArgument(clock != null, "clock cannot be null");
|
||||
this.world.clockManager().setPaused(CraftWorldClock.bukkitToMinecraftHolder(clock), paused);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getClockRate(final io.papermc.paper.world.WorldClock clock) {
|
||||
Preconditions.checkArgument(clock != null, "clock cannot be null");
|
||||
return this.world.clockManager().getInstance(CraftWorldClock.bukkitToMinecraftHolder(clock)).rate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClockRate(final io.papermc.paper.world.WorldClock clock, final float rate) {
|
||||
Preconditions.checkArgument(clock != null, "clock cannot be null");
|
||||
Preconditions.checkArgument(Float.isFinite(rate) && rate > 0.0F, "rate must be positive and finite, was %s", rate);
|
||||
this.world.clockManager().setRate(CraftWorldClock.bukkitToMinecraftHolder(clock), rate);
|
||||
}
|
||||
|
||||
// Paper start
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import io.papermc.paper.registry.HolderableBase;
|
||||
import io.papermc.paper.world.WorldClock;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
|
||||
public class CraftWorldClock extends HolderableBase<net.minecraft.world.clock.WorldClock> implements WorldClock {
|
||||
|
||||
public static WorldClock minecraftHolderToBukkit(final Holder<net.minecraft.world.clock.WorldClock> minecraft) {
|
||||
return CraftRegistry.minecraftHolderToBukkit(minecraft, Registries.WORLD_CLOCK);
|
||||
}
|
||||
|
||||
public static Holder<net.minecraft.world.clock.WorldClock> bukkitToMinecraftHolder(final WorldClock bukkit) {
|
||||
return CraftRegistry.bukkitToMinecraftHolder(bukkit);
|
||||
}
|
||||
|
||||
public CraftWorldClock(final Holder<net.minecraft.world.clock.WorldClock> holder) {
|
||||
super(holder);
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import net.minecraft.Optionull;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.game.ServerboundContainerClosePacket;
|
||||
@@ -2469,11 +2470,16 @@ public class CraftEventFactory {
|
||||
return new ItemTransportingEntitySortEvent(mob.getBukkitEntity(), CraftItemStack.asBukkitCopy(mob.getMainHandItem()), new CraftInventory(container));
|
||||
}
|
||||
|
||||
public static ClockTimeSkipEvent createTimeSkipEvent(final CommandSourceStack source, final long skipAmount) {
|
||||
public static ClockTimeSkipEvent createTimeSkipEvent(final CommandSourceStack source, final Holder<net.minecraft.world.clock.WorldClock> clock, final long skipAmount) {
|
||||
return createTimeSkipEvent(source.getLevel(), clock, ClockTimeSkipEvent.SkipReason.COMMAND, skipAmount);
|
||||
}
|
||||
|
||||
public static ClockTimeSkipEvent createTimeSkipEvent(final ServerLevel level, final Holder<net.minecraft.world.clock.WorldClock> clock, final ClockTimeSkipEvent.SkipReason reason, final long skipAmount) {
|
||||
final io.papermc.paper.world.WorldClock bukkitClock = org.bukkit.craftbukkit.CraftWorldClock.minecraftHolderToBukkit(clock);
|
||||
if (io.papermc.paper.configuration.GlobalConfiguration.get().time.affectsAllWorlds) {
|
||||
return new ClockTimeSkipEvent(ClockTimeSkipEvent.SkipReason.COMMAND, skipAmount);
|
||||
return new ClockTimeSkipEvent(bukkitClock, reason, skipAmount);
|
||||
}
|
||||
return new TimeSkipEvent(source.getLevel().getWorld(), ClockTimeSkipEvent.SkipReason.COMMAND, skipAmount);
|
||||
return new TimeSkipEvent(level.getWorld(), bukkitClock, reason, skipAmount);
|
||||
}
|
||||
|
||||
public static int callEntityIgniteEvent(Entity entity, int fuseTime) {
|
||||
|
||||
@@ -170,6 +170,8 @@ public class RegistriesArgumentProvider implements ArgumentsProvider {
|
||||
register(Registries.GAME_RULE, GameRule.class, GameRules.class, CraftGameRule.class, net.minecraft.world.level.gamerules.GameRule.class);
|
||||
register(Registries.POINT_OF_INTEREST_TYPE, PoiType.class, PoiTypes.class, PaperPoiType.class, net.minecraft.world.entity.ai.village.poi.PoiType.class);
|
||||
register(Registries.SULFUR_CUBE_ARCHETYPE, SulfurCube.Archetype.class, CraftSulfurCube.CraftArchetype.class, SulfurCubeArchetype.class);
|
||||
register(Registries.WORLD_CLOCK, io.papermc.paper.world.WorldClock.class, org.bukkit.craftbukkit.CraftWorldClock.class, net.minecraft.world.clock.WorldClock.class);
|
||||
register(Registries.TIMELINE, io.papermc.paper.world.Timeline.class, org.bukkit.craftbukkit.CraftTimeline.class, net.minecraft.world.timeline.Timeline.class);
|
||||
}
|
||||
|
||||
private static <M, B extends Keyed> void register(ResourceKey<? extends Registry<? extends M>> registryKey, Class<B> api, Class<? extends B> impl, Class<M> internal) {
|
||||
|
||||
Reference in new issue
Block a user