mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-02 14:38:26 +01:00
Merge branch 'master' into new-block-api
# Conflicts: # src/main/java/net/minestom/server/instance/DynamicChunk.java # src/main/java/net/minestom/server/instance/Instance.java # src/main/java/net/minestom/server/instance/InstanceContainer.java # src/main/java/net/minestom/server/instance/SharedInstance.java # src/main/java/net/minestom/server/instance/block/CustomBlock.java # src/test/java/demo/Main.java # src/test/java/demo/blocks/CustomBlockSample.java # src/test/java/demo/blocks/UpdatableBlockDemo.java
This commit is contained in:
commit
0d031d4c15
@ -4,7 +4,6 @@ import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.map.Framebuffer;
|
||||
import net.minestom.server.map.MapColors;
|
||||
import net.minestom.server.timer.Task;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.glfw.GLFWErrorCallback;
|
||||
@ -12,6 +11,8 @@ import org.lwjgl.opengl.GL;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.TemporalUnit;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.*;
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
@ -71,7 +72,11 @@ public abstract class GLFWCapableBuffer {
|
||||
GL.createCapabilities();
|
||||
}
|
||||
|
||||
public Task setupRenderLoop(long period, TimeUnit unit, Runnable rendering) {
|
||||
public Task setupRenderLoop(long period, TemporalUnit unit, Runnable rendering) {
|
||||
return setupRenderLoop(Duration.of(period, unit), rendering);
|
||||
}
|
||||
|
||||
public Task setupRenderLoop(Duration period, Runnable rendering) {
|
||||
return MinecraftServer.getSchedulerManager()
|
||||
.buildTask(new Runnable() {
|
||||
private boolean first = true;
|
||||
@ -85,7 +90,7 @@ public abstract class GLFWCapableBuffer {
|
||||
render(rendering);
|
||||
}
|
||||
})
|
||||
.repeat(period, unit)
|
||||
.repeat(period)
|
||||
.schedule();
|
||||
}
|
||||
|
||||
@ -97,7 +102,7 @@ public abstract class GLFWCapableBuffer {
|
||||
|
||||
/**
|
||||
* Called in render after glFlush to read the pixel buffer contents and convert it to map colors.
|
||||
* Only call if you do not use {@link #render(Runnable)} nor {@link #setupRenderLoop(long, TimeUnit, Runnable)}
|
||||
* Only call if you do not use {@link #render(Runnable)} nor {@link #setupRenderLoop}
|
||||
*/
|
||||
public void prepareMapColors() {
|
||||
if(onlyMapColors) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
package net.minestom.server.map.framebuffers;
|
||||
|
||||
import net.minestom.server.map.Framebuffer;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import org.lwjgl.BufferUtils;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
@ -22,7 +21,7 @@ import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_API;
|
||||
* to automatically render to the offscreen buffer on a specialized thread.
|
||||
*
|
||||
* GLFWFramebuffer does not provide guarantee that the result of {@link #toMapColors()} is synchronized with rendering, but
|
||||
* it will be updated after each frame rendered through {@link #render(Runnable)} or {@link #setupRenderLoop(long, TimeUnit, Runnable)}.
|
||||
* it will be updated after each frame rendered through {@link #render(Runnable)} or {@link #setupRenderLoop(long, java.time.temporal.TemporalUnit, Runnable)}.
|
||||
*
|
||||
* This framebuffer is meant to render to a single map (ie it is only compatible with 128x128 rendering)
|
||||
*/
|
||||
|
@ -7,15 +7,17 @@ import net.minestom.server.command.builder.arguments.Argument;
|
||||
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
|
||||
import net.minestom.server.network.packet.server.play.DeclareCommandsPacket;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.utils.time.UpdateOption;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.TemporalUnit;
|
||||
|
||||
/**
|
||||
* Represents an argument giving a time (day/second/tick).
|
||||
* <p>
|
||||
* Example: 50d, 25s, 75t
|
||||
*/
|
||||
public class ArgumentTime extends Argument<UpdateOption> {
|
||||
public class ArgumentTime extends Argument<Duration> {
|
||||
|
||||
public static final int INVALID_TIME_FORMAT = -2;
|
||||
public static final int NO_NUMBER = -3;
|
||||
@ -28,12 +30,12 @@ public class ArgumentTime extends Argument<UpdateOption> {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public UpdateOption parse(@NotNull String input) throws ArgumentSyntaxException {
|
||||
public Duration parse(@NotNull String input) throws ArgumentSyntaxException {
|
||||
final char lastChar = input.charAt(input.length() - 1);
|
||||
|
||||
TimeUnit timeUnit;
|
||||
TemporalUnit timeUnit;
|
||||
if (Character.isDigit(lastChar))
|
||||
timeUnit = TimeUnit.TICK;
|
||||
timeUnit = TimeUnit.SERVER_TICK;
|
||||
else if (SUFFIXES.contains(lastChar)) {
|
||||
input = input.substring(0, input.length() - 1);
|
||||
|
||||
@ -42,7 +44,7 @@ public class ArgumentTime extends Argument<UpdateOption> {
|
||||
} else if (lastChar == 's') {
|
||||
timeUnit = TimeUnit.SECOND;
|
||||
} else if (lastChar == 't') {
|
||||
timeUnit = TimeUnit.TICK;
|
||||
timeUnit = TimeUnit.SERVER_TICK;
|
||||
} else {
|
||||
throw new ArgumentSyntaxException("Time needs to have the unit d, s, t, or none", input, NO_NUMBER);
|
||||
}
|
||||
@ -52,7 +54,7 @@ public class ArgumentTime extends Argument<UpdateOption> {
|
||||
try {
|
||||
// Check if value is a number
|
||||
final int time = Integer.parseInt(input);
|
||||
return new UpdateOption(time, timeUnit);
|
||||
return Duration.of(time, timeUnit);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new ArgumentSyntaxException("Time needs to be a number", input, NO_NUMBER);
|
||||
}
|
||||
|
@ -47,13 +47,14 @@ import net.minestom.server.utils.entity.EntityUtils;
|
||||
import net.minestom.server.utils.player.PlayerUtils;
|
||||
import net.minestom.server.utils.time.Cooldown;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.utils.time.UpdateOption;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.TemporalUnit;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
@ -128,8 +129,8 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
protected EntityType entityType; // UNSAFE to change, modify at your own risk
|
||||
|
||||
// Network synchronization, send the absolute position of the entity each X milliseconds
|
||||
private static final UpdateOption SYNCHRONIZATION_COOLDOWN = new UpdateOption(1, TimeUnit.MINUTE);
|
||||
private UpdateOption customSynchronizationCooldown;
|
||||
private static final Duration SYNCHRONIZATION_COOLDOWN = Duration.of(1, TimeUnit.MINUTE);
|
||||
private Duration customSynchronizationCooldown;
|
||||
private long lastAbsoluteSynchronizationTime;
|
||||
|
||||
// Events
|
||||
@ -1123,7 +1124,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
* Sets the entity in fire visually.
|
||||
* <p>
|
||||
* WARNING: if you want to apply damage or specify a duration,
|
||||
* see {@link LivingEntity#setFireForDuration(int, TimeUnit)}.
|
||||
* see {@link LivingEntity#setFireForDuration(int, TemporalUnit)}.
|
||||
*
|
||||
* @param fire should the entity be set in fire
|
||||
*/
|
||||
@ -1509,18 +1510,28 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
*
|
||||
* @param delay the time before removing the entity,
|
||||
* 0 to cancel the removing
|
||||
* @param timeUnit the unit of the delay
|
||||
* @param temporalUnit the unit of the delay
|
||||
*/
|
||||
public void scheduleRemove(long delay, @NotNull TimeUnit timeUnit) {
|
||||
if (delay == 0) { // Cancel the scheduled remove
|
||||
this.scheduledRemoveTime = 0;
|
||||
return;
|
||||
}
|
||||
this.scheduledRemoveTime = System.currentTimeMillis() + timeUnit.toMilliseconds(delay);
|
||||
public void scheduleRemove(long delay, @NotNull TemporalUnit temporalUnit) {
|
||||
scheduleRemove(Duration.of(delay, temporalUnit));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if the entity removal has been scheduled with {@link #scheduleRemove(long, TimeUnit)}.
|
||||
* Triggers {@link #remove()} after the specified time.
|
||||
*
|
||||
* @param delay the time before removing the entity,
|
||||
* 0 to cancel the removing
|
||||
*/
|
||||
public void scheduleRemove(Duration delay) {
|
||||
if (delay.isZero()) { // Cancel the scheduled remove
|
||||
this.scheduledRemoveTime = 0;
|
||||
return;
|
||||
}
|
||||
this.scheduledRemoveTime = System.currentTimeMillis() + delay.toMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if the entity removal has been scheduled with {@link #scheduleRemove(Duration)}.
|
||||
*
|
||||
* @return true if the entity removal has been scheduled
|
||||
*/
|
||||
@ -1590,8 +1601,20 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
* Set custom cooldown for position synchronization.
|
||||
*
|
||||
* @param cooldown custom cooldown for position synchronization.
|
||||
* @deprecated Replaced by {@link #setCustomSynchronizationCooldown(Duration)}
|
||||
*/
|
||||
public void setCustomSynchronizationCooldown(@Nullable UpdateOption cooldown) {
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(forRemoval = true)
|
||||
public void setCustomSynchronizationCooldown(@Nullable net.minestom.server.utils.time.UpdateOption cooldown) {
|
||||
setCustomSynchronizationCooldown(cooldown != null ? Duration.ofMillis(cooldown.toMilliseconds()) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set custom cooldown for position synchronization.
|
||||
*
|
||||
* @param cooldown custom cooldown for position synchronization.
|
||||
*/
|
||||
public void setCustomSynchronizationCooldown(@Nullable Duration cooldown) {
|
||||
this.customSynchronizationCooldown = cooldown;
|
||||
}
|
||||
|
||||
@ -1600,7 +1623,7 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
||||
return HoverEvent.showEntity(ShowEntity.of(this.entityType, this.uuid));
|
||||
}
|
||||
|
||||
private UpdateOption getSynchronizationCooldown() {
|
||||
private Duration getSynchronizationCooldown() {
|
||||
return Objects.requireNonNullElse(this.customSynchronizationCooldown, SYNCHRONIZATION_COOLDOWN);
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ import net.minestom.server.utils.time.TimeUnit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
@ -80,7 +81,7 @@ public class EntityCreature extends LivingEntity implements NavigableEntity, Ent
|
||||
|
||||
if (removalAnimationDelay > 0) {
|
||||
// Needed for proper death animation (wait for it to finish before destroying the entity)
|
||||
scheduleRemove(removalAnimationDelay, TimeUnit.MILLISECOND);
|
||||
scheduleRemove(Duration.of(removalAnimationDelay, TimeUnit.MILLISECOND));
|
||||
} else {
|
||||
// Instant removal without animation playback
|
||||
remove();
|
||||
|
@ -10,10 +10,11 @@ import net.minestom.server.item.StackingRule;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.time.Cooldown;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.utils.time.UpdateOption;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.TemporalUnit;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@ -24,7 +25,7 @@ public class ItemEntity extends Entity {
|
||||
/**
|
||||
* Used to slow down the merge check delay
|
||||
*/
|
||||
private static UpdateOption mergeUpdateOption = new UpdateOption(10, TimeUnit.TICK);
|
||||
private static Duration mergeDelay = Duration.of(10, TimeUnit.SERVER_TICK);
|
||||
|
||||
/**
|
||||
* The last time that this item has checked his neighbors for merge
|
||||
@ -60,8 +61,8 @@ public class ItemEntity extends Entity {
|
||||
* @return the merge update option
|
||||
*/
|
||||
@Nullable
|
||||
public static UpdateOption getMergeUpdateOption() {
|
||||
return mergeUpdateOption;
|
||||
public static Duration getMergeDelay() {
|
||||
return mergeDelay;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -69,15 +70,29 @@ public class ItemEntity extends Entity {
|
||||
* Can be set to null to entirely remove the delay.
|
||||
*
|
||||
* @param mergeUpdateOption the new merge update option
|
||||
*
|
||||
* @deprecated Replaced by {@link #setMergeDelay(Duration)}
|
||||
*/
|
||||
public static void setMergeUpdateOption(@Nullable UpdateOption mergeUpdateOption) {
|
||||
ItemEntity.mergeUpdateOption = mergeUpdateOption;
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(forRemoval = true)
|
||||
public static void setMergeUpdateOption(@Nullable net.minestom.server.utils.time.UpdateOption mergeUpdateOption) {
|
||||
setMergeDelay(mergeUpdateOption != null ? mergeUpdateOption.toDuration() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the merge delay.
|
||||
* Can be set to null to entirely remove the delay.
|
||||
*
|
||||
* @param delay the new merge delay
|
||||
*/
|
||||
public static void setMergeDelay(@Nullable Duration delay) {
|
||||
ItemEntity.mergeDelay = delay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(long time) {
|
||||
if (isMergeable() && isPickable() &&
|
||||
(mergeUpdateOption == null || !Cooldown.hasCooldown(time, lastMergeCheck, mergeUpdateOption))) {
|
||||
(mergeDelay == null || !Cooldown.hasCooldown(time, lastMergeCheck, mergeDelay))) {
|
||||
this.lastMergeCheck = time;
|
||||
|
||||
final Chunk chunk = instance.getChunkAt(getPosition());
|
||||
@ -213,7 +228,7 @@ public class ItemEntity extends Entity {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pickup delay in milliseconds, defined by {@link #setPickupDelay(long, TimeUnit)}.
|
||||
* Gets the pickup delay in milliseconds, defined by {@link #setPickupDelay(Duration)}.
|
||||
*
|
||||
* @return the pickup delay
|
||||
*/
|
||||
@ -225,10 +240,19 @@ public class ItemEntity extends Entity {
|
||||
* Sets the pickup delay of the ItemEntity.
|
||||
*
|
||||
* @param delay the pickup delay
|
||||
* @param timeUnit the unit of the delay
|
||||
* @param temporalUnit the unit of the delay
|
||||
*/
|
||||
public void setPickupDelay(long delay, @NotNull TimeUnit timeUnit) {
|
||||
this.pickupDelay = timeUnit.toMilliseconds(delay);
|
||||
public void setPickupDelay(long delay, @NotNull TemporalUnit temporalUnit) {
|
||||
setPickupDelay(Duration.of(delay, temporalUnit));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pickup delay of the ItemEntity.
|
||||
*
|
||||
* @param delay the pickup delay
|
||||
*/
|
||||
public void setPickupDelay(Duration delay) {
|
||||
this.pickupDelay = delay.toMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -31,10 +31,11 @@ import net.minestom.server.utils.Vector;
|
||||
import net.minestom.server.utils.block.BlockIterator;
|
||||
import net.minestom.server.utils.time.Cooldown;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.utils.time.UpdateOption;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.TemporalUnit;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@ -42,7 +43,7 @@ public class LivingEntity extends Entity implements EquipmentHandler {
|
||||
|
||||
// ItemStack pickup
|
||||
protected boolean canPickupItem;
|
||||
protected Cooldown itemPickupCooldown = new Cooldown(new UpdateOption(5, TimeUnit.TICK));
|
||||
protected Cooldown itemPickupCooldown = new Cooldown(Duration.of(5, TimeUnit.SERVER_TICK));
|
||||
|
||||
protected boolean isDead;
|
||||
|
||||
@ -316,21 +317,31 @@ public class LivingEntity extends Entity implements EquipmentHandler {
|
||||
* @param duration duration in ticks of the effect
|
||||
*/
|
||||
public void setFireForDuration(int duration) {
|
||||
setFireForDuration(duration, TimeUnit.TICK);
|
||||
setFireForDuration(duration, TimeUnit.SERVER_TICK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets fire to this entity for a given duration.
|
||||
*
|
||||
* @param duration duration of the effect
|
||||
* @param unit unit used to express the duration
|
||||
* @param temporalUnit unit used to express the duration
|
||||
* @see #setOnFire(boolean) if you want it to be permanent without any event callback
|
||||
*/
|
||||
public void setFireForDuration(int duration, TimeUnit unit) {
|
||||
EntityFireEvent entityFireEvent = new EntityFireEvent(this, duration, unit);
|
||||
public void setFireForDuration(int duration, TemporalUnit temporalUnit) {
|
||||
setFireForDuration(Duration.of(duration, temporalUnit));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets fire to this entity for a given duration.
|
||||
*
|
||||
* @param duration duration of the effect
|
||||
* @see #setOnFire(boolean) if you want it to be permanent without any event callback
|
||||
*/
|
||||
public void setFireForDuration(Duration duration) {
|
||||
EntityFireEvent entityFireEvent = new EntityFireEvent(this, duration);
|
||||
|
||||
// Do not start fire event if the fire needs to be removed (< 0 duration)
|
||||
if (duration > 0) {
|
||||
if (duration.toMillis() > 0) {
|
||||
EventDispatcher.callCancellable(entityFireEvent, () -> {
|
||||
final long fireTime = entityFireEvent.getFireTime(TimeUnit.MILLISECOND);
|
||||
setOnFire(true);
|
||||
@ -659,7 +670,7 @@ public class LivingEntity extends Entity implements EquipmentHandler {
|
||||
* Gets the time in ms between two fire damage applications.
|
||||
*
|
||||
* @return the time in ms
|
||||
* @see #setFireDamagePeriod(long, TimeUnit)
|
||||
* @see #setFireDamagePeriod(Duration)
|
||||
*/
|
||||
public long getFireDamagePeriod() {
|
||||
return fireDamagePeriod;
|
||||
@ -669,11 +680,19 @@ public class LivingEntity extends Entity implements EquipmentHandler {
|
||||
* Changes the delay between two fire damage applications.
|
||||
*
|
||||
* @param fireDamagePeriod the delay
|
||||
* @param timeUnit the time unit
|
||||
* @param temporalUnit the time unit
|
||||
*/
|
||||
public void setFireDamagePeriod(long fireDamagePeriod, @NotNull TimeUnit timeUnit) {
|
||||
fireDamagePeriod = timeUnit.toMilliseconds(fireDamagePeriod);
|
||||
this.fireDamagePeriod = fireDamagePeriod;
|
||||
public void setFireDamagePeriod(long fireDamagePeriod, @NotNull TemporalUnit temporalUnit) {
|
||||
setFireDamagePeriod(Duration.of(fireDamagePeriod, temporalUnit));
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the delay between two fire damage applications.
|
||||
*
|
||||
* @param fireDamagePeriod the delay
|
||||
*/
|
||||
public void setFireDamagePeriod(Duration fireDamagePeriod) {
|
||||
this.fireDamagePeriod = fireDamagePeriod.toMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -74,7 +74,6 @@ import net.minestom.server.utils.instance.InstanceUtils;
|
||||
import net.minestom.server.utils.inventory.PlayerInventoryUtils;
|
||||
import net.minestom.server.utils.time.Cooldown;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.utils.time.UpdateOption;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import net.minestom.server.world.DimensionType;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@ -82,6 +81,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
@ -143,7 +143,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
private boolean enableRespawnScreen;
|
||||
|
||||
// Experience orb pickup
|
||||
protected Cooldown experiencePickupCooldown = new Cooldown(new UpdateOption(10, TimeUnit.TICK));
|
||||
protected Cooldown experiencePickupCooldown = new Cooldown(Duration.of(10, TimeUnit.SERVER_TICK));
|
||||
|
||||
private BelowNameTag belowNameTag;
|
||||
|
||||
|
@ -9,10 +9,11 @@ import net.minestom.server.entity.EntityProjectile;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.time.Cooldown;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.utils.time.UpdateOption;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.TemporalUnit;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
@ -20,16 +21,14 @@ import java.util.function.Function;
|
||||
*/
|
||||
public class CombinedAttackGoal extends GoalSelector {
|
||||
|
||||
private final Cooldown cooldown = new Cooldown(new UpdateOption(5, TimeUnit.TICK));
|
||||
private final Cooldown cooldown = new Cooldown(Duration.of(5, TimeUnit.SERVER_TICK));
|
||||
|
||||
private final int meleeRangeSquared;
|
||||
private final int meleeDelay;
|
||||
private final TimeUnit meleeTimeUnit;
|
||||
private final Duration meleeDelay;
|
||||
private final int rangedRangeSquared;
|
||||
private final double rangedPower;
|
||||
private final double rangedSpread;
|
||||
private final int rangedDelay;
|
||||
private final TimeUnit rangedTimeUnit;
|
||||
private final Duration rangedDelay;
|
||||
private final int desirableRangeSquared;
|
||||
private final boolean comeClose;
|
||||
|
||||
@ -52,7 +51,7 @@ public class CombinedAttackGoal extends GoalSelector {
|
||||
*/
|
||||
public CombinedAttackGoal(@NotNull EntityCreature entityCreature,
|
||||
int meleeRange, int rangedRange, double rangedPower, double rangedSpread,
|
||||
int delay, TimeUnit timeUnit,
|
||||
int delay, TemporalUnit timeUnit,
|
||||
int desirableRange, boolean comeClose) {
|
||||
this(
|
||||
entityCreature,
|
||||
@ -62,6 +61,28 @@ public class CombinedAttackGoal extends GoalSelector {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param entityCreature the entity to add the goal to.
|
||||
* @param meleeRange the allowed range the entity can hit others in melee.
|
||||
* @param rangedRange the allowed range the entity can shoot others.
|
||||
* @param rangedPower shot power (1 for normal).
|
||||
* @param rangedSpread shot spread (0 for best accuracy).
|
||||
* @param delay the delay between any attacks.
|
||||
* @param desirableRange the desirable range: the entity will try to stay no further than this distance.
|
||||
* @param comeClose if entity should go as close as possible to the target whether target is not in line of sight for a ranged attack.
|
||||
*/
|
||||
public CombinedAttackGoal(@NotNull EntityCreature entityCreature,
|
||||
int meleeRange, int rangedRange, double rangedPower, double rangedSpread,
|
||||
Duration delay,
|
||||
int desirableRange, boolean comeClose) {
|
||||
this(
|
||||
entityCreature,
|
||||
meleeRange, delay,
|
||||
rangedRange, rangedPower, rangedSpread, delay,
|
||||
desirableRange, comeClose
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param entityCreature the entity to add the goal to.
|
||||
* @param meleeRange the allowed range the entity can hit others in melee.
|
||||
@ -76,18 +97,35 @@ public class CombinedAttackGoal extends GoalSelector {
|
||||
* @param comeClose if entity should go as close as possible to the target whether target is not in line of sight for a ranged attack.
|
||||
*/
|
||||
public CombinedAttackGoal(@NotNull EntityCreature entityCreature,
|
||||
int meleeRange, int meleeDelay, TimeUnit meleeTimeUnit,
|
||||
int rangedRange, double rangedPower, double rangedSpread, int rangedDelay, TimeUnit rangedTimeUnit,
|
||||
int meleeRange, int meleeDelay, TemporalUnit meleeTimeUnit,
|
||||
int rangedRange, double rangedPower, double rangedSpread, int rangedDelay, TemporalUnit rangedTimeUnit,
|
||||
int desirableRange, boolean comeClose) {
|
||||
this(entityCreature, meleeRange, Duration.of(meleeDelay, meleeTimeUnit), rangedRange, rangedPower, rangedSpread,
|
||||
Duration.of(rangedDelay, rangedTimeUnit), desirableRange, comeClose);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param entityCreature the entity to add the goal to.
|
||||
* @param meleeRange the allowed range the entity can hit others in melee.
|
||||
* @param meleeDelay the delay between melee attacks.
|
||||
* @param rangedRange the allowed range the entity can shoot others.
|
||||
* @param rangedPower shot power (1 for normal).
|
||||
* @param rangedSpread shot spread (0 for best accuracy).
|
||||
* @param rangedDelay the delay between ranged attacks.
|
||||
* @param desirableRange the desirable range: the entity will try to stay no further than this distance.
|
||||
* @param comeClose if entity should go as close as possible to the target whether target is not in line of sight for a ranged attack.
|
||||
*/
|
||||
public CombinedAttackGoal(@NotNull EntityCreature entityCreature,
|
||||
int meleeRange, Duration meleeDelay,
|
||||
int rangedRange, double rangedPower, double rangedSpread, Duration rangedDelay,
|
||||
int desirableRange, boolean comeClose) {
|
||||
super(entityCreature);
|
||||
this.meleeRangeSquared = meleeRange * meleeRange;
|
||||
this.meleeDelay = meleeDelay;
|
||||
this.meleeTimeUnit = meleeTimeUnit;
|
||||
this.rangedRangeSquared = rangedRange * rangedRange;
|
||||
this.rangedPower = rangedPower;
|
||||
this.rangedSpread = rangedSpread;
|
||||
this.rangedDelay = rangedDelay;
|
||||
this.rangedTimeUnit = rangedTimeUnit;
|
||||
this.desirableRangeSquared = desirableRange * desirableRange;
|
||||
this.comeClose = comeClose;
|
||||
Check.argCondition(desirableRange > rangedRange, "Desirable range can not exceed ranged range!");
|
||||
@ -129,12 +167,12 @@ public class CombinedAttackGoal extends GoalSelector {
|
||||
boolean comeClose = false;
|
||||
// First of all, checking if to perform melee or ranged attack depending on the distance to target.
|
||||
if (distanceSquared <= this.meleeRangeSquared) {
|
||||
if (!Cooldown.hasCooldown(time, this.lastAttack, this.meleeTimeUnit, this.meleeDelay)) {
|
||||
if (!Cooldown.hasCooldown(time, this.lastAttack, this.meleeDelay)) {
|
||||
this.entityCreature.attack(target, true);
|
||||
this.lastAttack = time;
|
||||
}
|
||||
} else if (distanceSquared <= this.rangedRangeSquared) {
|
||||
if (!Cooldown.hasCooldown(time, this.lastAttack, this.rangedTimeUnit, this.rangedDelay)) {
|
||||
if (!Cooldown.hasCooldown(time, this.lastAttack, this.rangedDelay)) {
|
||||
if (this.entityCreature.hasLineOfSight(target)) {
|
||||
// If target is on line of entity sight, ranged attack can be performed
|
||||
Position to = target.getPosition().clone().add(0D, target.getEyeHeight(), 0D);
|
||||
|
@ -6,12 +6,13 @@ import net.minestom.server.entity.ai.GoalSelector;
|
||||
import net.minestom.server.entity.pathfinding.Navigator;
|
||||
import net.minestom.server.utils.MathUtils;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.time.UpdateOption;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
public class FollowTargetGoal extends GoalSelector {
|
||||
|
||||
private final UpdateOption pathUpdateOption;
|
||||
private final Duration pathDuration;
|
||||
private long lastUpdateTime = 0;
|
||||
private boolean forceEnd = false;
|
||||
private Position lastTargetPos;
|
||||
@ -21,10 +22,24 @@ public class FollowTargetGoal extends GoalSelector {
|
||||
*
|
||||
* @param entityCreature the entity
|
||||
* @param pathUpdateOption the time between each path update (to check if the target moved)
|
||||
*
|
||||
* @deprecated Replaced by {@link #FollowTargetGoal(EntityCreature, Duration)}
|
||||
*/
|
||||
public FollowTargetGoal(@NotNull EntityCreature entityCreature, @NotNull UpdateOption pathUpdateOption) {
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(forRemoval = true)
|
||||
public FollowTargetGoal(@NotNull EntityCreature entityCreature, @NotNull net.minestom.server.utils.time.UpdateOption pathUpdateOption) {
|
||||
this(entityCreature, pathUpdateOption.toDuration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a follow target goal object.
|
||||
*
|
||||
* @param entityCreature the entity
|
||||
* @param pathDuration the time between each path update (to check if the target moved)
|
||||
*/
|
||||
public FollowTargetGoal(@NotNull EntityCreature entityCreature, @NotNull Duration pathDuration) {
|
||||
super(entityCreature);
|
||||
this.pathUpdateOption = pathUpdateOption;
|
||||
this.pathDuration = pathDuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -64,8 +79,8 @@ public class FollowTargetGoal extends GoalSelector {
|
||||
@Override
|
||||
public void tick(long time) {
|
||||
if (forceEnd ||
|
||||
pathUpdateOption.getValue() == 0 ||
|
||||
pathUpdateOption.getTimeUnit().toMilliseconds(pathUpdateOption.getValue()) + lastUpdateTime > time) {
|
||||
pathDuration.isZero() ||
|
||||
pathDuration.toMillis() + lastUpdateTime > time) {
|
||||
return;
|
||||
}
|
||||
Position targetPos = entityCreature.getTarget() != null ? entityCreature.getTarget().getPosition() : null;
|
||||
|
@ -8,21 +8,22 @@ import net.minestom.server.entity.pathfinding.Navigator;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.time.Cooldown;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.utils.time.UpdateOption;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.TemporalUnit;
|
||||
|
||||
/**
|
||||
* Attacks the entity's target ({@link EntityCreature#getTarget()}) OR the closest entity
|
||||
* which can be targeted with the entity {@link TargetSelector}.
|
||||
*/
|
||||
public class MeleeAttackGoal extends GoalSelector {
|
||||
|
||||
private final Cooldown cooldown = new Cooldown(new UpdateOption(5, TimeUnit.TICK));
|
||||
private final Cooldown cooldown = new Cooldown(Duration.of(5, TimeUnit.SERVER_TICK));
|
||||
|
||||
private long lastHit;
|
||||
private final double range;
|
||||
private final int delay;
|
||||
private final TimeUnit timeUnit;
|
||||
private final Duration delay;
|
||||
|
||||
private boolean stop;
|
||||
private Entity cachedTarget;
|
||||
@ -33,11 +34,19 @@ public class MeleeAttackGoal extends GoalSelector {
|
||||
* @param delay the delay between each attacks
|
||||
* @param timeUnit the unit of the delay
|
||||
*/
|
||||
public MeleeAttackGoal(@NotNull EntityCreature entityCreature, double range, int delay, @NotNull TimeUnit timeUnit) {
|
||||
public MeleeAttackGoal(@NotNull EntityCreature entityCreature, double range, int delay, @NotNull TemporalUnit timeUnit) {
|
||||
this(entityCreature, range, Duration.of(delay, timeUnit));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param entityCreature the entity to add the goal to
|
||||
* @param range the allowed range the entity can attack others.
|
||||
* @param delay the delay between each attacks
|
||||
*/
|
||||
public MeleeAttackGoal(@NotNull EntityCreature entityCreature, double range, Duration delay) {
|
||||
super(entityCreature);
|
||||
this.range = range;
|
||||
this.delay = delay;
|
||||
this.timeUnit = timeUnit;
|
||||
}
|
||||
|
||||
public @NotNull Cooldown getCooldown() {
|
||||
@ -72,7 +81,7 @@ public class MeleeAttackGoal extends GoalSelector {
|
||||
|
||||
// Attack the target entity
|
||||
if (entityCreature.getDistance(target) <= range) {
|
||||
if (!Cooldown.hasCooldown(time, lastHit, timeUnit, delay)) {
|
||||
if (!Cooldown.hasCooldown(time, lastHit, delay)) {
|
||||
entityCreature.attack(target, true);
|
||||
this.lastHit = time;
|
||||
}
|
||||
|
@ -9,19 +9,19 @@ import net.minestom.server.entity.EntityProjectile;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.time.Cooldown;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.utils.time.UpdateOption;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.TemporalUnit;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class RangedAttackGoal extends GoalSelector {
|
||||
|
||||
private final Cooldown cooldown = new Cooldown(new UpdateOption(5, TimeUnit.TICK));
|
||||
private final Cooldown cooldown = new Cooldown(Duration.of(5, TimeUnit.SERVER_TICK));
|
||||
|
||||
private long lastShot;
|
||||
private final int delay;
|
||||
private final TimeUnit timeUnit;
|
||||
private final Duration delay;
|
||||
private final int attackRangeSquared;
|
||||
private final int desirableRangeSquared;
|
||||
private final boolean comeClose;
|
||||
@ -43,10 +43,22 @@ public class RangedAttackGoal extends GoalSelector {
|
||||
* @param power shot power (1 for normal).
|
||||
* @param timeUnit the unit of the delay.
|
||||
*/
|
||||
public RangedAttackGoal(@NotNull EntityCreature entityCreature, int delay, int attackRange, int desirableRange, boolean comeClose, double power, double spread, @NotNull TimeUnit timeUnit) {
|
||||
public RangedAttackGoal(@NotNull EntityCreature entityCreature, int delay, int attackRange, int desirableRange, boolean comeClose, double power, double spread, @NotNull TemporalUnit timeUnit) {
|
||||
this(entityCreature, Duration.of(delay, timeUnit), attackRange, desirableRange, comeClose, power, spread);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param entityCreature the entity to add the goal to.
|
||||
* @param delay the delay between each shots.
|
||||
* @param attackRange the allowed range the entity can shoot others.
|
||||
* @param desirableRange the desirable range: the entity will try to stay no further than this distance.
|
||||
* @param comeClose whether entity should go as close as possible to the target whether target is not in line of sight.
|
||||
* @param spread shot spread (0 for best accuracy).
|
||||
* @param power shot power (1 for normal).
|
||||
*/
|
||||
public RangedAttackGoal(@NotNull EntityCreature entityCreature, Duration delay, int attackRange, int desirableRange, boolean comeClose, double power, double spread) {
|
||||
super(entityCreature);
|
||||
this.delay = delay;
|
||||
this.timeUnit = timeUnit;
|
||||
this.attackRangeSquared = attackRange * attackRange;
|
||||
this.desirableRangeSquared = desirableRange * desirableRange;
|
||||
this.comeClose = comeClose;
|
||||
@ -90,7 +102,7 @@ public class RangedAttackGoal extends GoalSelector {
|
||||
double distanceSquared = this.entityCreature.getDistanceSquared(target);
|
||||
boolean comeClose = false;
|
||||
if (distanceSquared <= this.attackRangeSquared) {
|
||||
if (!Cooldown.hasCooldown(time, this.lastShot, this.timeUnit, this.delay)) {
|
||||
if (!Cooldown.hasCooldown(time, this.lastShot, this.delay)) {
|
||||
if (this.entityCreature.hasLineOfSight(target)) {
|
||||
Position to = target.getPosition().clone().add(0D, target.getEyeHeight(), 0D);
|
||||
|
||||
|
@ -151,7 +151,7 @@ public class FakePlayer extends Player implements NavigableEntity {
|
||||
private void handleTabList(PlayerConnection connection) {
|
||||
if (!option.isInTabList()) {
|
||||
// Remove from tab-list
|
||||
MinecraftServer.getSchedulerManager().buildTask(() -> connection.sendPacket(getRemovePlayerToList())).delay(20, TimeUnit.TICK).schedule();
|
||||
MinecraftServer.getSchedulerManager().buildTask(() -> connection.sendPacket(getRemovePlayerToList())).delay(20, TimeUnit.SERVER_TICK).schedule();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,8 +20,10 @@ import java.util.Set;
|
||||
public class Hologram implements Viewable {
|
||||
|
||||
private static final float OFFSET_Y = -0.9875f;
|
||||
private static final float MARKER_OFFSET_Y = -0.40625f;
|
||||
|
||||
private final Entity entity;
|
||||
private final float yOffset;
|
||||
|
||||
private Position position;
|
||||
private Component text;
|
||||
@ -75,13 +77,31 @@ public class Hologram implements Viewable {
|
||||
* @param autoViewable {@code true}if the hologram should be visible automatically, otherwise {@code false}.
|
||||
*/
|
||||
public Hologram(Instance instance, Position spawnPosition, Component text, boolean autoViewable) {
|
||||
this(instance, spawnPosition, text, autoViewable, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link Hologram} with the given parameters.
|
||||
*
|
||||
* @param instance The instance where the hologram should be spawned.
|
||||
* @param spawnPosition The spawn position of this hologram.
|
||||
* @param text The text of this hologram.
|
||||
* @param autoViewable {@code true}if the hologram should be visible automatically, otherwise {@code false}.
|
||||
*/
|
||||
public Hologram(Instance instance, Position spawnPosition, Component text, boolean autoViewable, boolean marker) {
|
||||
this.entity = new Entity(EntityType.ARMOR_STAND);
|
||||
|
||||
ArmorStandMeta armorStandMeta = (ArmorStandMeta) entity.getEntityMeta();
|
||||
|
||||
armorStandMeta.setNotifyAboutChanges(false);
|
||||
|
||||
armorStandMeta.setSmall(true);
|
||||
if(marker) {
|
||||
this.yOffset = MARKER_OFFSET_Y;
|
||||
armorStandMeta.setMarker(true);
|
||||
} else {
|
||||
this.yOffset = OFFSET_Y;
|
||||
armorStandMeta.setSmall(true);
|
||||
}
|
||||
armorStandMeta.setHasNoGravity(true);
|
||||
armorStandMeta.setCustomName(Component.empty());
|
||||
armorStandMeta.setCustomNameVisible(true);
|
||||
@ -89,7 +109,7 @@ public class Hologram implements Viewable {
|
||||
|
||||
armorStandMeta.setNotifyAboutChanges(true);
|
||||
|
||||
this.entity.setInstance(instance, spawnPosition.clone().add(0, OFFSET_Y, 0));
|
||||
this.entity.setInstance(instance, spawnPosition.clone().add(0, this.yOffset, 0));
|
||||
this.entity.setAutoViewable(autoViewable);
|
||||
|
||||
this.position = spawnPosition;
|
||||
@ -112,7 +132,7 @@ public class Hologram implements Viewable {
|
||||
*/
|
||||
public void setPosition(Position position) {
|
||||
checkRemoved();
|
||||
position.add(0, OFFSET_Y, 0);
|
||||
position.add(0, this.yOffset, 0);
|
||||
this.position = position;
|
||||
this.entity.teleport(position);
|
||||
}
|
||||
|
@ -3,37 +3,37 @@ package net.minestom.server.event.entity;
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.event.trait.CancellableEvent;
|
||||
import net.minestom.server.event.trait.EntityEvent;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.TemporalUnit;
|
||||
|
||||
public class EntityFireEvent implements EntityEvent, CancellableEvent {
|
||||
|
||||
private final Entity entity;
|
||||
private int duration;
|
||||
private TimeUnit timeUnit;
|
||||
private Duration duration;
|
||||
|
||||
private boolean cancelled;
|
||||
|
||||
public EntityFireEvent(Entity entity, int duration, TimeUnit timeUnit) {
|
||||
public EntityFireEvent(Entity entity, int duration, TemporalUnit temporalUnit) {
|
||||
this(entity, Duration.of(duration, temporalUnit));
|
||||
}
|
||||
|
||||
public EntityFireEvent(Entity entity, Duration duration) {
|
||||
this.entity = entity;
|
||||
setFireTime(duration, timeUnit);
|
||||
setFireTime(duration);
|
||||
}
|
||||
|
||||
public long getFireTime(TimeUnit timeUnit) {
|
||||
switch (timeUnit) {
|
||||
case TICK:
|
||||
return duration;
|
||||
case MILLISECOND:
|
||||
return timeUnit.toMilliseconds(duration);
|
||||
default:
|
||||
// Unexpected
|
||||
return -1;
|
||||
}
|
||||
public long getFireTime(TemporalUnit temporalUnit) {
|
||||
return duration.toNanos() / temporalUnit.getDuration().toNanos();
|
||||
}
|
||||
|
||||
public void setFireTime(int duration, TimeUnit timeUnit) {
|
||||
public void setFireTime(int duration, TemporalUnit temporalUnit) {
|
||||
setFireTime(Duration.of(duration, temporalUnit));
|
||||
}
|
||||
|
||||
public void setFireTime(Duration duration) {
|
||||
this.duration = duration;
|
||||
this.timeUnit = timeUnit;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3,9 +3,10 @@ package net.minestom.server.event.server;
|
||||
import net.minestom.server.event.trait.CancellableEvent;
|
||||
import net.minestom.server.network.player.PlayerConnection;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.utils.time.UpdateOption;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
|
||||
/**
|
||||
* Called when a {@link PlayerConnection} sends a ping packet,
|
||||
@ -14,13 +15,13 @@ import org.jetbrains.annotations.NotNull;
|
||||
* @see ServerListPingEvent
|
||||
*/
|
||||
public class ClientPingServerEvent implements CancellableEvent {
|
||||
private static final UpdateOption DEFAULT_DELAY = new UpdateOption(0, TimeUnit.MILLISECOND);
|
||||
private static final Duration DEFAULT_DELAY = Duration.of(0, TimeUnit.MILLISECOND);
|
||||
|
||||
private final PlayerConnection connection;
|
||||
private long payload;
|
||||
|
||||
private boolean cancelled = false;
|
||||
private UpdateOption delay;
|
||||
private Duration delay;
|
||||
|
||||
/**
|
||||
* Creates a new client ping server event with 0 delay
|
||||
@ -40,13 +41,24 @@ public class ClientPingServerEvent implements CancellableEvent {
|
||||
* @param connection the player connection
|
||||
* @param payload the payload the client sent
|
||||
*/
|
||||
public ClientPingServerEvent(@NotNull PlayerConnection connection, long payload, UpdateOption delay) {
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(forRemoval = true)
|
||||
public ClientPingServerEvent(@NotNull PlayerConnection connection, long payload, net.minestom.server.utils.time.UpdateOption delay) {
|
||||
this(connection, payload, delay.toDuration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new client ping server event with 0 delay
|
||||
*
|
||||
* @param connection the player connection
|
||||
* @param payload the payload the client sent
|
||||
*/
|
||||
public ClientPingServerEvent(@NotNull PlayerConnection connection, long payload, Duration delay) {
|
||||
this.connection = connection;
|
||||
this.payload = payload;
|
||||
this.delay = delay;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* PlayerConnection of received packet. Note that the player has not joined the server
|
||||
* at this time.
|
||||
@ -82,7 +94,7 @@ public class ClientPingServerEvent implements CancellableEvent {
|
||||
*
|
||||
* @return the delay
|
||||
*/
|
||||
public @NotNull UpdateOption getDelay() {
|
||||
public @NotNull Duration getDelay() {
|
||||
return delay;
|
||||
}
|
||||
|
||||
@ -90,9 +102,35 @@ public class ClientPingServerEvent implements CancellableEvent {
|
||||
* Adds to the delay until minestom will send the ping response packet.
|
||||
*
|
||||
* @param delay the delay
|
||||
*
|
||||
* @deprecated Replaced by {@link #addDelay(Duration)}
|
||||
*/
|
||||
public void addDelay(@NotNull UpdateOption delay) {
|
||||
this.delay = new UpdateOption(this.delay.toMilliseconds() + delay.toMilliseconds(), TimeUnit.MILLISECOND);
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(forRemoval = true)
|
||||
public void addDelay(@NotNull net.minestom.server.utils.time.UpdateOption delay) {
|
||||
addDelay(delay.toDuration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds to the delay until minestom will send the ping response packet.
|
||||
*
|
||||
* @param delay the delay
|
||||
*/
|
||||
public void addDelay(@NotNull Duration delay) {
|
||||
this.delay = this.delay.plus(delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the delay until minestom will send the ping response packet.
|
||||
*
|
||||
* @param delay the delay
|
||||
*
|
||||
* @deprecated Replaced by {@link #setDelay(Duration)}
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(forRemoval = true)
|
||||
public void setDelay(@NotNull net.minestom.server.utils.time.UpdateOption delay) {
|
||||
setDelay(delay.toDuration());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -100,7 +138,7 @@ public class ClientPingServerEvent implements CancellableEvent {
|
||||
*
|
||||
* @param delay the delay
|
||||
*/
|
||||
public void setDelay(@NotNull UpdateOption delay) {
|
||||
public void setDelay(@NotNull Duration delay) {
|
||||
this.delay = delay;
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ public class OpenToLAN {
|
||||
|
||||
eventCooldown = new Cooldown(config.delayBetweenEvent);
|
||||
task = MinecraftServer.getSchedulerManager().buildTask(OpenToLAN::ping)
|
||||
.repeat(config.delayBetweenPings.getValue(), config.delayBetweenPings.getTimeUnit())
|
||||
.repeat(config.delayBetweenPings)
|
||||
.schedule();
|
||||
return true;
|
||||
}
|
||||
|
@ -2,10 +2,10 @@ package net.minestom.server.extras.lan;
|
||||
|
||||
import net.minestom.server.event.server.ServerListPingEvent;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.utils.time.UpdateOption;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@ -15,7 +15,7 @@ import java.util.Objects;
|
||||
*/
|
||||
public class OpenToLANConfig {
|
||||
int port;
|
||||
UpdateOption delayBetweenPings, delayBetweenEvent;
|
||||
Duration delayBetweenPings, delayBetweenEvent;
|
||||
|
||||
/**
|
||||
* Creates a new config with the port set to random and the delay between pings set
|
||||
@ -23,8 +23,8 @@ public class OpenToLANConfig {
|
||||
*/
|
||||
public OpenToLANConfig() {
|
||||
this.port = 0;
|
||||
this.delayBetweenPings = new UpdateOption(1500, TimeUnit.MILLISECOND);
|
||||
this.delayBetweenEvent = new UpdateOption(30, TimeUnit.SECOND);
|
||||
this.delayBetweenPings = Duration.of(1500, TimeUnit.MILLISECOND);
|
||||
this.delayBetweenEvent = Duration.of(30, TimeUnit.SECOND);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -46,7 +46,7 @@ public class OpenToLANConfig {
|
||||
* @return {@code this}, for chaining
|
||||
*/
|
||||
@Contract("_ -> this")
|
||||
public @NotNull OpenToLANConfig pingDelay(@NotNull UpdateOption delay) {
|
||||
public @NotNull OpenToLANConfig pingDelay(@NotNull Duration delay) {
|
||||
this.delayBetweenPings = Objects.requireNonNull(delay, "delay");
|
||||
return this;
|
||||
}
|
||||
@ -58,7 +58,7 @@ public class OpenToLANConfig {
|
||||
* @return {@code this}, for chaining
|
||||
*/
|
||||
@Contract("_ -> this")
|
||||
public @NotNull OpenToLANConfig eventCallDelay(@NotNull UpdateOption delay) {
|
||||
public @NotNull OpenToLANConfig eventCallDelay(@NotNull Duration delay) {
|
||||
this.delayBetweenEvent = Objects.requireNonNull(delay, "delay");
|
||||
return this;
|
||||
}
|
||||
|
@ -42,12 +42,16 @@ public class MinestomRootClassLoader extends HierarchyClassLoader {
|
||||
};
|
||||
public final Set<String> protectedPackages = new HashSet<>() {
|
||||
{
|
||||
add("com.google");
|
||||
add("com.google.j2objc");
|
||||
add("com.google.common"); // guava
|
||||
add("com.google.errorprone");
|
||||
add("com.google.gson");
|
||||
add("com.mojang");
|
||||
add("org.objectweb.asm");
|
||||
add("org.slf4j");
|
||||
add("org.apache");
|
||||
add("org.spongepowered");
|
||||
add("org.apache.logging");
|
||||
add("org.spongepowered.asm"); // Mixin
|
||||
add("org.spongepowered.tools"); // Mixin
|
||||
add("net.minestom.server.extras.selfmodification");
|
||||
add("org.jboss.shrinkwrap.resolver");
|
||||
add("kotlin");
|
||||
|
@ -8,6 +8,8 @@ import net.minestom.server.instance.block.BlockHandler;
|
||||
import net.minestom.server.network.packet.server.play.ChunkDataPacket;
|
||||
import net.minestom.server.utils.BlockPosition;
|
||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||
import net.minestom.server.utils.time.Cooldown;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import net.minestom.server.world.biomes.Biome;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@ -15,6 +17,7 @@ import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.Map;
|
||||
import java.time.Duration;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
|
@ -37,7 +37,6 @@ import net.minestom.server.utils.chunk.ChunkUtils;
|
||||
import net.minestom.server.utils.entity.EntityUtils;
|
||||
import net.minestom.server.utils.time.Cooldown;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.utils.time.UpdateOption;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import net.minestom.server.world.DimensionType;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@ -45,6 +44,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.TemporalUnit;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
@ -78,7 +79,7 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable,Tag
|
||||
// The time of the instance
|
||||
private long time;
|
||||
private int timeRate = 1;
|
||||
private UpdateOption timeUpdate = new UpdateOption(1, TimeUnit.SECOND);
|
||||
private Duration timeUpdate = Duration.of(1, TimeUnit.SECOND);
|
||||
private long lastTimeUpdate;
|
||||
|
||||
// Field for tick events
|
||||
@ -409,7 +410,7 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable,Tag
|
||||
* @return the client update rate for time related packet
|
||||
*/
|
||||
@Nullable
|
||||
public UpdateOption getTimeUpdate() {
|
||||
public Duration getTimeUpdate() {
|
||||
return timeUpdate;
|
||||
}
|
||||
|
||||
@ -421,7 +422,21 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable,Tag
|
||||
*
|
||||
* @param timeUpdate the new update rate concerning time
|
||||
*/
|
||||
public void setTimeUpdate(@Nullable UpdateOption timeUpdate) {
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(forRemoval = true)
|
||||
public void setTimeUpdate(@Nullable net.minestom.server.utils.time.UpdateOption timeUpdate) {
|
||||
setTimeUpdate(timeUpdate != null ? timeUpdate.toDuration() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the rate at which the client is updated about the time
|
||||
* <p>
|
||||
* Setting it to null means that the client will never know about time change
|
||||
* (but will still change server-side)
|
||||
*
|
||||
* @param timeUpdate the new update rate concerning time
|
||||
*/
|
||||
public void setTimeUpdate(@Nullable Duration timeUpdate) {
|
||||
this.timeUpdate = timeUpdate;
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ import net.minestom.server.world.biomes.Biome;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.time.temporal.TemporalUnit;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
@ -10,6 +10,7 @@ import net.minestom.server.utils.chunk.ChunkCallback;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.time.temporal.TemporalUnit;
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -6,13 +6,13 @@ import net.minestom.server.item.ItemMetaBuilder;
|
||||
import net.minestom.server.potion.CustomPotionEffect;
|
||||
import net.minestom.server.potion.PotionType;
|
||||
import net.minestom.server.registry.Registries;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTList;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTTypes;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
@ -98,7 +98,7 @@ public class PotionMeta extends ItemMeta implements ItemMetaBuilder.Provider<Pot
|
||||
for (NBTCompound potionCompound : customEffectList) {
|
||||
final byte id = potionCompound.getAsByte("Id");
|
||||
final byte amplifier = potionCompound.getAsByte("Amplifier");
|
||||
final int duration = potionCompound.containsKey("Duration") ? potionCompound.getNumber("Duration").intValue() : (int) TimeUnit.SECOND.toMilliseconds(30);
|
||||
final int duration = potionCompound.containsKey("Duration") ? potionCompound.getNumber("Duration").intValue() : (int) Duration.ofSeconds(30).toMillis();
|
||||
final boolean ambient = potionCompound.containsKey("Ambient") ? potionCompound.getAsByte("Ambient") == 1 : false;
|
||||
final boolean showParticles = potionCompound.containsKey("ShowParticles") ? potionCompound.getAsByte("ShowParticles") == 1 : true;
|
||||
final boolean showIcon = potionCompound.containsKey("ShowIcon") ? potionCompound.getAsByte("ShowIcon") == 1 : true;
|
||||
|
@ -5,6 +5,7 @@ import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.EntityType;
|
||||
import net.minestom.server.entity.GameMode;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.entity.metadata.other.ArmorStandMeta;
|
||||
import net.minestom.server.event.EventDispatcher;
|
||||
import net.minestom.server.event.player.PlayerBlockInteractEvent;
|
||||
import net.minestom.server.event.player.PlayerBlockPlaceEvent;
|
||||
@ -124,6 +125,14 @@ public class BlockPlacementListener {
|
||||
entity.getEntityType() == EntityType.ITEM)
|
||||
continue;
|
||||
|
||||
// Marker Armor Stands should not prevent block placement
|
||||
if(entity.getEntityMeta() instanceof ArmorStandMeta) {
|
||||
ArmorStandMeta armorStandMeta = (ArmorStandMeta) entity.getEntityMeta();
|
||||
if(armorStandMeta.isMarker()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
intersect = entity.getBoundingBox().intersect(blockPosition);
|
||||
if (intersect)
|
||||
break;
|
||||
|
@ -7,13 +7,13 @@ import net.kyori.adventure.text.TextComponent;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.utils.MathUtils;
|
||||
import net.minestom.server.utils.time.UpdateOption;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.ThreadInfo;
|
||||
import java.lang.management.ThreadMXBean;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@ -25,7 +25,7 @@ import static net.minestom.server.MinecraftServer.*;
|
||||
/**
|
||||
* Small monitoring tools that can be used to check the current memory usage and Minestom threads CPU usage.
|
||||
* <p>
|
||||
* Needs to be enabled with {@link #enable(UpdateOption)}. Memory can then be accessed with {@link #getUsedMemory()}
|
||||
* Needs to be enabled with {@link #enable(Duration)}. Memory can then be accessed with {@link #getUsedMemory()}
|
||||
* and the CPUs usage with {@link #getResultMap()} or {@link #getCpuMonitoringMessage()}.
|
||||
* <p>
|
||||
* Be aware that this is not the most accurate method, you should use a proper java profiler depending on your needs.
|
||||
@ -57,10 +57,10 @@ public final class BenchmarkManager {
|
||||
|
||||
private long time;
|
||||
|
||||
public void enable(@NotNull UpdateOption updateOption) {
|
||||
public void enable(@NotNull Duration duration) {
|
||||
Check.stateCondition(enabled, "A benchmark is already running, please disable it first.");
|
||||
|
||||
time = updateOption.getTimeUnit().toMilliseconds(updateOption.getValue());
|
||||
time = duration.toMillis();
|
||||
|
||||
final Thread thread = new Thread(null, () -> {
|
||||
|
||||
|
@ -25,7 +25,7 @@ public class PingPacket implements ClientPreplayPacket {
|
||||
if (clientPingEvent.isCancelled()) {
|
||||
connection.disconnect();
|
||||
} else {
|
||||
if (clientPingEvent.getDelay().toMilliseconds() == 0) {
|
||||
if (clientPingEvent.getDelay().isZero()) {
|
||||
connection.sendPacket(new PongPacket(clientPingEvent.getPayload()));
|
||||
connection.disconnect();
|
||||
} else {
|
||||
|
@ -20,8 +20,8 @@ import java.util.stream.Collectors;
|
||||
* An object which manages all the {@link Task}'s.
|
||||
* <p>
|
||||
* {@link Task} first need to be built with {@link #buildTask(Runnable)}, you can then specify a delay with as example
|
||||
* {@link TaskBuilder#delay(long, net.minestom.server.utils.time.TimeUnit)}
|
||||
* or {@link TaskBuilder#repeat(long, net.minestom.server.utils.time.TimeUnit)},
|
||||
* {@link TaskBuilder#delay(long, java.time.temporal.TemporalUnit)}
|
||||
* or {@link TaskBuilder#repeat(long, java.time.temporal.TemporalUnit)},
|
||||
* and to finally schedule: {@link TaskBuilder#schedule()}.
|
||||
* <p>
|
||||
* Shutdown tasks are built with {@link #buildShutdownTask(Runnable)} and are executed, as the name implies, when the server stops.
|
||||
|
@ -3,13 +3,15 @@ package net.minestom.server.timer;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import net.minestom.server.extras.selfmodification.MinestomRootClassLoader;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.utils.time.UpdateOption;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.TemporalUnit;
|
||||
|
||||
/**
|
||||
* A builder which represents a fluent Object to schedule tasks.
|
||||
* <p>
|
||||
* You can specify a delay with {@link #delay(long, TimeUnit)} or {@link #repeat(long, TimeUnit)}
|
||||
* You can specify a delay with {@link #delay(long, TemporalUnit)} or {@link #repeat(long, TemporalUnit)}
|
||||
* and then schedule the {@link Task} with {@link #schedule()}.
|
||||
*/
|
||||
public class TaskBuilder {
|
||||
@ -68,9 +70,8 @@ public class TaskBuilder {
|
||||
* @return this builder, for chaining
|
||||
*/
|
||||
@NotNull
|
||||
public TaskBuilder delay(long time, @NotNull TimeUnit unit) {
|
||||
this.delay = unit.toMilliseconds(time);
|
||||
return this;
|
||||
public TaskBuilder delay(long time, @NotNull TemporalUnit unit) {
|
||||
return delay(Duration.of(time, unit));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -78,10 +79,25 @@ public class TaskBuilder {
|
||||
*
|
||||
* @param updateOption the UpdateOption for this builder.
|
||||
* @return this builder, for chaining
|
||||
*
|
||||
* @deprecated Replaced by {@link #delay(Duration)}
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
@NotNull
|
||||
@Deprecated(forRemoval = true)
|
||||
public TaskBuilder delay(net.minestom.server.utils.time.UpdateOption updateOption) {
|
||||
return delay(updateOption.toDuration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies that the {@link Task} should delay its execution by the specified amount of time.
|
||||
*
|
||||
* @param duration the Duration for this builder.
|
||||
* @return this builder, for chaining
|
||||
*/
|
||||
@NotNull
|
||||
public TaskBuilder delay(UpdateOption updateOption) {
|
||||
this.delay = updateOption.toMilliseconds();
|
||||
public TaskBuilder delay(Duration duration) {
|
||||
this.delay = duration.toMillis();
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -89,13 +105,12 @@ public class TaskBuilder {
|
||||
* Specifies that the {@link Task} should continue to run after waiting for the specified value until it is terminated.
|
||||
*
|
||||
* @param time The time until the repetition
|
||||
* @param unit The {@link TimeUnit} for {@code time}
|
||||
* @param unit The {@link TemporalUnit} for {@code time}
|
||||
* @return this builder, for chaining
|
||||
*/
|
||||
@NotNull
|
||||
public TaskBuilder repeat(long time, @NotNull TimeUnit unit) {
|
||||
this.repeat = unit.toMilliseconds(time);
|
||||
return this;
|
||||
public TaskBuilder repeat(long time, @NotNull TemporalUnit unit) {
|
||||
return repeat(Duration.of(time, unit));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -103,10 +118,25 @@ public class TaskBuilder {
|
||||
*
|
||||
* @param updateOption the UpdateOption for this builder.
|
||||
* @return this builder, for chaining
|
||||
*
|
||||
* @deprecated Replaced by {@link #repeat(Duration)}
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
@NotNull
|
||||
@Deprecated(forRemoval = true)
|
||||
public TaskBuilder repeat(net.minestom.server.utils.time.UpdateOption updateOption) {
|
||||
return repeat(updateOption.toDuration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies that the {@link Task} should continue to run after waiting for the specified value until it is terminated.
|
||||
*
|
||||
* @param duration the Duration for this builder.
|
||||
* @return this builder, for chaining
|
||||
*/
|
||||
@NotNull
|
||||
public TaskBuilder repeat(UpdateOption updateOption) {
|
||||
this.repeat = updateOption.toMilliseconds();
|
||||
public TaskBuilder repeat(Duration duration) {
|
||||
this.repeat = duration.toMillis();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -327,8 +327,11 @@ public class Vector implements PublicCloneable<Vector> {
|
||||
double angleCos = Math.cos(angle);
|
||||
double angleSin = Math.sin(angle);
|
||||
|
||||
this.y = angleCos * getY() - angleSin * getZ();
|
||||
this.z = angleSin * getY() + angleCos * getZ();
|
||||
double oldY = getY();
|
||||
double oldZ = getZ();
|
||||
|
||||
this.y = angleCos * oldY - angleSin * oldZ;
|
||||
this.z = angleSin * oldY + angleCos * oldZ;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -349,8 +352,11 @@ public class Vector implements PublicCloneable<Vector> {
|
||||
double angleCos = Math.cos(angle);
|
||||
double angleSin = Math.sin(angle);
|
||||
|
||||
this.x = angleCos * getX() + angleSin * getZ();
|
||||
this.z = -angleSin * getX() + angleCos * getZ();
|
||||
double oldX = getX();
|
||||
double oldZ = getZ();
|
||||
|
||||
this.x = angleCos * oldX + angleSin * oldZ;
|
||||
this.z = -angleSin * oldX + angleCos * oldZ;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -371,8 +377,11 @@ public class Vector implements PublicCloneable<Vector> {
|
||||
double angleCos = Math.cos(angle);
|
||||
double angleSin = Math.sin(angle);
|
||||
|
||||
this.x = angleCos * getX() - angleSin * getY();
|
||||
this.y = angleSin * getX() + angleCos * getY();
|
||||
double oldX = getX();
|
||||
double oldY = getY();
|
||||
|
||||
this.x = angleCos * oldX - angleSin * oldY;
|
||||
this.y = angleSin * oldX + angleCos * oldY;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -2,18 +2,30 @@ package net.minestom.server.utils.time;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.TemporalUnit;
|
||||
|
||||
public final class Cooldown {
|
||||
|
||||
private UpdateOption updateOption;
|
||||
private final Duration duration;
|
||||
private long lastUpdate;
|
||||
|
||||
/**
|
||||
* @deprecated Replaced by {@link #Cooldown(Duration)}
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(forRemoval = true)
|
||||
public Cooldown(@NotNull UpdateOption updateOption) {
|
||||
this.updateOption = updateOption;
|
||||
this(updateOption.toDuration());
|
||||
}
|
||||
|
||||
public Cooldown(Duration duration) {
|
||||
this.duration = duration;
|
||||
this.lastUpdate = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public UpdateOption getUpdateOption() {
|
||||
return this.updateOption;
|
||||
public Duration getDuration() {
|
||||
return this.duration;
|
||||
}
|
||||
|
||||
public void refreshLastUpdate(long lastUpdate) {
|
||||
@ -21,7 +33,7 @@ public final class Cooldown {
|
||||
}
|
||||
|
||||
public boolean isReady(long time) {
|
||||
return !hasCooldown(time, lastUpdate, updateOption.getTimeUnit(), updateOption.getValue());
|
||||
return !hasCooldown(time, lastUpdate, duration);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -29,13 +41,12 @@ public final class Cooldown {
|
||||
*
|
||||
* @param currentTime the current time in milliseconds
|
||||
* @param lastUpdate the last update in milliseconds
|
||||
* @param timeUnit the time unit of the cooldown
|
||||
* @param temporalUnit the time unit of the cooldown
|
||||
* @param cooldown the value of the cooldown
|
||||
* @return true if the cooldown is in progress, false otherwise
|
||||
*/
|
||||
public static boolean hasCooldown(long currentTime, long lastUpdate, @NotNull TimeUnit timeUnit, long cooldown) {
|
||||
final long cooldownMs = timeUnit.toMilliseconds(cooldown);
|
||||
return currentTime - lastUpdate < cooldownMs;
|
||||
public static boolean hasCooldown(long currentTime, long lastUpdate, @NotNull TemporalUnit temporalUnit, long cooldown) {
|
||||
return hasCooldown(currentTime, lastUpdate, Duration.of(cooldown, temporalUnit));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -45,20 +56,37 @@ public final class Cooldown {
|
||||
* @param lastUpdate the last update in milliseconds
|
||||
* @param updateOption the cooldown
|
||||
* @return true if the cooldown is in progress, false otherwise
|
||||
*
|
||||
* @deprecated Replaced by {@link #hasCooldown(long, long, Duration)}
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(forRemoval = true)
|
||||
public static boolean hasCooldown(long currentTime, long lastUpdate, @NotNull UpdateOption updateOption) {
|
||||
return hasCooldown(currentTime, lastUpdate, updateOption.getTimeUnit(), updateOption.getValue());
|
||||
return hasCooldown(currentTime, lastUpdate, updateOption.toDuration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if something is in cooldown based on the current time.
|
||||
*
|
||||
* @param currentTime the current time in milliseconds
|
||||
* @param lastUpdate the last update in milliseconds
|
||||
* @param duration the cooldown
|
||||
* @return true if the cooldown is in progress, false otherwise
|
||||
*/
|
||||
public static boolean hasCooldown(long currentTime, long lastUpdate, @NotNull Duration duration) {
|
||||
final long cooldownMs = duration.toMillis();
|
||||
return currentTime - lastUpdate < cooldownMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if something is in cooldown based on the current time ({@link System#currentTimeMillis()}).
|
||||
*
|
||||
* @param lastUpdate the last update in milliseconds
|
||||
* @param timeUnit the time unit of the cooldown
|
||||
* @param temporalUnit the time unit of the cooldown
|
||||
* @param cooldown the value of the cooldown
|
||||
* @return true if the cooldown is in progress, false otherwise
|
||||
*/
|
||||
public static boolean hasCooldown(long lastUpdate, @NotNull TimeUnit timeUnit, int cooldown) {
|
||||
return hasCooldown(System.currentTimeMillis(), lastUpdate, timeUnit, cooldown);
|
||||
public static boolean hasCooldown(long lastUpdate, @NotNull TemporalUnit temporalUnit, int cooldown) {
|
||||
return hasCooldown(System.currentTimeMillis(), lastUpdate, temporalUnit, cooldown);
|
||||
}
|
||||
}
|
||||
|
112
src/main/java/net/minestom/server/utils/time/Tick.java
Normal file
112
src/main/java/net/minestom/server/utils/time/Tick.java
Normal file
@ -0,0 +1,112 @@
|
||||
package net.minestom.server.utils.time;
|
||||
|
||||
import net.minestom.server.MinecraftServer;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.Temporal;
|
||||
import java.time.temporal.TemporalUnit;
|
||||
|
||||
/**
|
||||
* A TemporalUnit that represents one tick.
|
||||
*/
|
||||
public final class Tick implements TemporalUnit {
|
||||
/**
|
||||
* A TemporalUnit representing the server tick. This is defined using
|
||||
* {@link MinecraftServer#TICK_MS}.
|
||||
*/
|
||||
public static Tick SERVER_TICKS = new Tick(MinecraftServer.TICK_MS);
|
||||
|
||||
/**
|
||||
* A TemporalUnit representing the client tick. This is always equal to 50ms.
|
||||
*/
|
||||
public static Tick CLIENT_TICKS = new Tick(50);
|
||||
|
||||
private final long milliseconds;
|
||||
private final int tps;
|
||||
|
||||
/**
|
||||
* Creates a new tick.
|
||||
*
|
||||
* @param length the length of the tick in milliseconds
|
||||
*/
|
||||
private Tick(long length) {
|
||||
if (length <= 0) {
|
||||
throw new IllegalArgumentException("length cannot be negative");
|
||||
}
|
||||
|
||||
this.milliseconds = length;
|
||||
this.tps = Math.toIntExact(Duration.ofSeconds(1).dividedBy(Duration.ofMillis(this.milliseconds)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a duration from an amount of ticks.
|
||||
*
|
||||
* @param ticks the amount of ticks
|
||||
* @return the duration
|
||||
*/
|
||||
public static Duration server(long ticks) {
|
||||
return Duration.of(ticks, SERVER_TICKS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a duration from an amount of client-side ticks.
|
||||
*
|
||||
* @param ticks the amount of ticks
|
||||
* @return the duration
|
||||
*/
|
||||
public static Duration client(long ticks) {
|
||||
return Duration.of(ticks, CLIENT_TICKS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of whole ticks that occur in the provided duration. Note that this
|
||||
* method returns an {@code int} as this is the unit that Minecraft stores ticks in.
|
||||
*
|
||||
* @param duration the duration
|
||||
* @return the number of whole ticks in this duration
|
||||
* @throws ArithmeticException if the duration is zero or an overflow occurs
|
||||
*/
|
||||
public int fromDuration(Duration duration) {
|
||||
return Math.toIntExact(duration.dividedBy(this.getDuration()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the whole number of these ticks that occur in one second.
|
||||
*
|
||||
* @return the number
|
||||
*/
|
||||
public int getTicksPerSecond() {
|
||||
return this.tps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getDuration() {
|
||||
return Duration.ofMillis(this.milliseconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDurationEstimated() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDateBased() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTimeBased() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // following ChronoUnit#addTo
|
||||
@Override
|
||||
public <R extends Temporal> R addTo(R temporal, long amount) {
|
||||
return (R) temporal.plus(amount, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long between(Temporal start, Temporal end) {
|
||||
return start.until(end, this);
|
||||
}
|
||||
}
|
@ -1,34 +1,22 @@
|
||||
package net.minestom.server.utils.time;
|
||||
|
||||
import net.minestom.server.MinecraftServer;
|
||||
|
||||
public enum TimeUnit {
|
||||
|
||||
TICK, DAY, HOUR, MINUTE, SECOND, MILLISECOND;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.time.temporal.TemporalUnit;
|
||||
|
||||
public class TimeUnit {
|
||||
public static final TemporalUnit DAY = ChronoUnit.DAYS;
|
||||
public static final TemporalUnit HOUR = ChronoUnit.HOURS;
|
||||
public static final TemporalUnit MINUTE = ChronoUnit.MINUTES;
|
||||
public static final TemporalUnit SECOND = ChronoUnit.SECONDS;
|
||||
public static final TemporalUnit MILLISECOND = ChronoUnit.MILLIS;
|
||||
public static final TemporalUnit SERVER_TICK = Tick.SERVER_TICKS;
|
||||
public static final TemporalUnit CLIENT_TICK = Tick.CLIENT_TICKS;
|
||||
/**
|
||||
* Converts a value and its unit to milliseconds.
|
||||
*
|
||||
* @param value the time value
|
||||
* @return the converted milliseconds based on the time value and the unit
|
||||
* @deprecated Please use either {@link #SERVER_TICK} or {@link #CLIENT_TICK}
|
||||
*/
|
||||
public long toMilliseconds(long value) {
|
||||
switch (this) {
|
||||
case TICK:
|
||||
return MinecraftServer.TICK_MS * value;
|
||||
case DAY:
|
||||
return value * 86_400_000;
|
||||
case HOUR:
|
||||
return value * 3_600_000;
|
||||
case MINUTE:
|
||||
return value * 60_000;
|
||||
case SECOND:
|
||||
return value * 1000;
|
||||
case MILLISECOND:
|
||||
return value;
|
||||
default:
|
||||
return -1; // Unexpected
|
||||
}
|
||||
}
|
||||
@Deprecated(forRemoval = true)
|
||||
public static final TemporalUnit TICK = CLIENT_TICK;
|
||||
|
||||
private TimeUnit() {
|
||||
}
|
||||
}
|
||||
|
@ -2,16 +2,22 @@ package net.minestom.server.utils.time;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.TemporalUnit;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @deprecated Replaced by {@link java.time.Duration}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public class UpdateOption {
|
||||
|
||||
private final long value;
|
||||
private final TimeUnit timeUnit;
|
||||
private final TemporalUnit temporalUnit;
|
||||
|
||||
public UpdateOption(long value, @NotNull TimeUnit timeUnit) {
|
||||
public UpdateOption(long value, @NotNull TemporalUnit temporalUnit) {
|
||||
this.value = value;
|
||||
this.timeUnit = timeUnit;
|
||||
this.temporalUnit = temporalUnit;
|
||||
}
|
||||
|
||||
public long getValue() {
|
||||
@ -19,13 +25,13 @@ public class UpdateOption {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TimeUnit getTimeUnit() {
|
||||
return timeUnit;
|
||||
public TemporalUnit getTemporalUnit() {
|
||||
return temporalUnit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(value, timeUnit);
|
||||
return Objects.hash(value, temporalUnit);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -33,7 +39,7 @@ public class UpdateOption {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
UpdateOption updateOption = (UpdateOption) o;
|
||||
return Objects.equals(value, updateOption.value) && Objects.equals(timeUnit, updateOption.timeUnit);
|
||||
return Objects.equals(value, updateOption.value) && Objects.equals(temporalUnit, updateOption.temporalUnit);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -42,6 +48,10 @@ public class UpdateOption {
|
||||
* @return the converted milliseconds based on the time value and the unit
|
||||
*/
|
||||
public long toMilliseconds() {
|
||||
return timeUnit.toMilliseconds(value);
|
||||
return toDuration().toMillis();
|
||||
}
|
||||
|
||||
public Duration toDuration() {
|
||||
return Duration.of(value, temporalUnit);
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,8 @@ import net.minestom.server.instance.block.rule.vanilla.RedstonePlacementRule;
|
||||
import net.minestom.server.ping.ResponseData;
|
||||
import net.minestom.server.utils.identity.NamedAndIdentified;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.utils.time.UpdateOption;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
public class Main {
|
||||
|
||||
@ -99,7 +100,7 @@ public class Main {
|
||||
//MojangAuth.init();
|
||||
|
||||
// useful for testing - we don't need to worry about event calls so just set this to a long time
|
||||
OpenToLAN.open(new OpenToLANConfig().eventCallDelay(new UpdateOption(1, TimeUnit.DAY)));
|
||||
OpenToLAN.open(new OpenToLANConfig().eventCallDelay(Duration.of(1, TimeUnit.DAY)));
|
||||
|
||||
minecraftServer.start("0.0.0.0", 25565);
|
||||
//Runtime.getRuntime().addShutdownHook(new Thread(MinecraftServer::stopCleanly));
|
||||
|
@ -35,6 +35,7 @@ import net.minestom.server.utils.Vector;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.world.DimensionType;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collection;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
@ -76,7 +77,7 @@ public class PlayerInit {
|
||||
|
||||
Position position = player.getPosition().clone().add(0, 1.5f, 0);
|
||||
ItemEntity itemEntity = new ItemEntity(droppedItem, position);
|
||||
itemEntity.setPickupDelay(500, TimeUnit.MILLISECOND);
|
||||
itemEntity.setPickupDelay(Duration.of(500, TimeUnit.MILLISECOND));
|
||||
itemEntity.setInstance(player.getInstance());
|
||||
Vector velocity = player.getPosition().clone().getDirection().multiply(6);
|
||||
itemEntity.setVelocity(velocity);
|
||||
@ -142,6 +143,6 @@ public class PlayerInit {
|
||||
.append(Component.text("ACQ TIME: " + MathUtils.round(tickMonitor.getAcquisitionTime(), 2) + "ms"));
|
||||
final Component footer = benchmarkManager.getCpuMonitoringMessage();
|
||||
Audiences.players().sendPlayerListHeaderAndFooter(header, footer);
|
||||
}).repeat(10, TimeUnit.TICK).schedule();
|
||||
}).repeat(10, TimeUnit.SERVER_TICK).schedule();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user