mirror of
https://github.com/Minestom/Minestom.git
synced 2025-03-02 11:21:15 +01:00
Rewrite Potions
This commit is contained in:
parent
50b44e46e0
commit
d7883d29ff
@ -33,7 +33,6 @@ import net.minestom.server.network.packet.server.play.UpdateViewDistancePacket;
|
||||
import net.minestom.server.particle.Particle;
|
||||
import net.minestom.server.ping.ResponseDataConsumer;
|
||||
import net.minestom.server.potion.PotionEffect;
|
||||
import net.minestom.server.potion.PotionEffectManager;
|
||||
import net.minestom.server.potion.PotionType;
|
||||
import net.minestom.server.recipe.RecipeManager;
|
||||
import net.minestom.server.registry.ResourceGatherer;
|
||||
@ -117,7 +116,6 @@ public final class MinecraftServer {
|
||||
private static DimensionTypeManager dimensionTypeManager;
|
||||
private static BiomeManager biomeManager;
|
||||
private static AdvancementManager advancementManager;
|
||||
private static PotionEffectManager potionEffectManager;
|
||||
|
||||
private static ExtensionManager extensionManager;
|
||||
|
||||
@ -179,7 +177,6 @@ public final class MinecraftServer {
|
||||
dimensionTypeManager = new DimensionTypeManager();
|
||||
biomeManager = new BiomeManager();
|
||||
advancementManager = new AdvancementManager();
|
||||
potionEffectManager = new PotionEffectManager();
|
||||
|
||||
updateManager = new UpdateManager();
|
||||
|
||||
@ -624,16 +621,6 @@ public final class MinecraftServer {
|
||||
return advancementManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the manager handling potions.
|
||||
*
|
||||
* @return the potion effect manager
|
||||
*/
|
||||
public static PotionEffectManager getPotionEffectManager() {
|
||||
checkInitStatus(potionEffectManager);
|
||||
return potionEffectManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the manager handling {@link Extension}.
|
||||
*
|
||||
|
@ -22,6 +22,8 @@ import net.minestom.server.instance.block.CustomBlock;
|
||||
import net.minestom.server.network.packet.server.play.*;
|
||||
import net.minestom.server.permission.Permission;
|
||||
import net.minestom.server.permission.PermissionHandler;
|
||||
import net.minestom.server.potion.Potion;
|
||||
import net.minestom.server.potion.PotionEffect;
|
||||
import net.minestom.server.thread.ThreadProvider;
|
||||
import net.minestom.server.utils.BlockPosition;
|
||||
import net.minestom.server.utils.Position;
|
||||
@ -130,6 +132,9 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
|
||||
protected boolean noGravity;
|
||||
protected Pose pose = Pose.STANDING;
|
||||
|
||||
private ArrayList<Potion> effects = new ArrayList<>();
|
||||
private ArrayList<Long> effectTimes = new ArrayList<>();
|
||||
|
||||
// list of scheduled tasks to be executed during the next entity tick
|
||||
protected final Queue<Consumer<Entity>> nextTick = Queues.newConcurrentLinkedQueue();
|
||||
|
||||
@ -396,6 +401,29 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
|
||||
return;
|
||||
}
|
||||
|
||||
// remove expired effects
|
||||
{
|
||||
if (effects.size() > 0) {
|
||||
boolean foundToRemove = true;
|
||||
while (foundToRemove) {
|
||||
foundToRemove = false;
|
||||
int i = 0;
|
||||
while (i < effects.size()) {
|
||||
if (effects.get(i).duration * 50 +
|
||||
effectTimes.get(i) <= System.nanoTime() / 1000000) {
|
||||
foundToRemove = true;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (foundToRemove) {
|
||||
effects.remove(i);
|
||||
effectTimes.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// scheduled tasks
|
||||
if (!nextTick.isEmpty()) {
|
||||
Consumer<Entity> callback;
|
||||
@ -1442,6 +1470,45 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
|
||||
DYING
|
||||
}
|
||||
|
||||
public List<Potion> getActiveEffects() {
|
||||
return effects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes effect from entity, if it has it.
|
||||
*
|
||||
* @param effect The effect to remove
|
||||
*/
|
||||
public void removeEffect(@NotNull PotionEffect effect) {
|
||||
if (effects.size() == 0) return;
|
||||
int i = 0;
|
||||
boolean found = false;
|
||||
while (i < effects.size()) {
|
||||
if (effects.get(i).effect == effect) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (found) {
|
||||
effects.get(i).sendRemovePacket(this);
|
||||
effects.remove(i);
|
||||
effectTimes.remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an effect to an entity
|
||||
*
|
||||
* @param potion The potion to add
|
||||
*/
|
||||
public void addEffect(@NotNull Potion potion) {
|
||||
removeEffect(potion.effect);
|
||||
effects.add(potion);
|
||||
effectTimes.add(System.nanoTime() / 1000000);
|
||||
potion.sendAddPacket(this);
|
||||
}
|
||||
|
||||
protected boolean shouldRemove() {
|
||||
return shouldRemove;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.minestom.server.potion;
|
||||
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.network.packet.server.play.EntityEffectPacket;
|
||||
import net.minestom.server.network.packet.server.play.RemoveEntityEffectPacket;
|
||||
@ -42,17 +43,17 @@ public class Potion {
|
||||
return computed;
|
||||
}
|
||||
|
||||
public void sendAddPacket(@NotNull Player player) {
|
||||
public void sendAddPacket(@NotNull Entity entity) {
|
||||
EntityEffectPacket eep = new EntityEffectPacket();
|
||||
eep.entityId = player.getEntityId();
|
||||
eep.entityId = entity.getEntityId();
|
||||
eep.potion = this;
|
||||
player.sendPacketToViewersAndSelf(eep);
|
||||
entity.sendPacketToViewersAndSelf(eep);
|
||||
}
|
||||
|
||||
public void sendRemovePacket(@NotNull Player player) {
|
||||
public void sendRemovePacket(@NotNull Entity entity) {
|
||||
RemoveEntityEffectPacket reep = new RemoveEntityEffectPacket();
|
||||
reep.entityId = player.getEntityId();
|
||||
reep.entityId = entity.getEntityId();
|
||||
reep.effect = effect;
|
||||
player.sendPacketToViewersAndSelf(reep);
|
||||
entity.sendPacketToViewersAndSelf(reep);
|
||||
}
|
||||
}
|
||||
|
@ -1,185 +0,0 @@
|
||||
package net.minestom.server.potion;
|
||||
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.GlobalEventHandler;
|
||||
import net.minestom.server.event.player.PlayerDisconnectEvent;
|
||||
import net.minestom.server.event.player.PlayerSpawnEvent;
|
||||
import net.minestom.server.timer.SchedulerManager;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Manages active potion effects on players
|
||||
*/
|
||||
public class PotionEffectManager {
|
||||
|
||||
private HashMap<UUID, ArrayList<PotionTask>> playerEffects;
|
||||
private boolean persistEffects = false;
|
||||
|
||||
/**
|
||||
* Creates a new PotionEffectManager
|
||||
*/
|
||||
public PotionEffectManager() {
|
||||
playerEffects = new HashMap<>();
|
||||
|
||||
addEventHandlers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the active effects of a player.
|
||||
*
|
||||
* @param player The player to get the effects of.
|
||||
* @return Null if no active effects, otherwise the active effects.
|
||||
*/
|
||||
public @Nullable List<PotionTask> getActiveEffects(@Nullable Player player) {
|
||||
if (player == null) return null;
|
||||
return playerEffects.get(player.getUuid());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link PotionTask} on a player of a type {@link PotionEffect}
|
||||
*
|
||||
* @param player The player with the effect.
|
||||
* @param potionEffect The type of potion to look for.
|
||||
* @return Null if the player does not have the effect, otherwise the effect.
|
||||
*/
|
||||
public @Nullable PotionTask getPotionTask(@Nullable Player player, @Nullable PotionEffect potionEffect) {
|
||||
if (player == null) return null;
|
||||
if (potionEffect == null) return null;
|
||||
|
||||
ArrayList<PotionTask> potionTasks = playerEffects.get(player.getUuid());
|
||||
if (potionTasks == null) return null;
|
||||
|
||||
for (PotionTask potionTask : potionTasks) {
|
||||
if (potionTask.getPotion().effect == potionEffect) {
|
||||
return potionTask;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the player has an effect of specified type.
|
||||
*
|
||||
* @param player The player to check.
|
||||
* @param potionEffect The type of potion to check for.
|
||||
* @return If the player has a potion effect with the specified type.
|
||||
*/
|
||||
public boolean hasPotionEffect(@Nullable Player player, @Nullable PotionEffect potionEffect) {
|
||||
return getPotionTask(player, potionEffect) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the {@link PotionTask}.
|
||||
*
|
||||
* @param task The {@link PotionTask} to remove.
|
||||
*/
|
||||
public void removeEffect(@NotNull PotionTask task) {
|
||||
task.getValue().task.cancel();
|
||||
for (UUID uuid : playerEffects.keySet()) {
|
||||
if (playerEffects.get(uuid).contains(task)) {
|
||||
playerEffects.get(uuid).remove(task);
|
||||
Player player = MinecraftServer.getConnectionManager().getPlayer(uuid);
|
||||
if (player != null && player.isOnline()) {
|
||||
task.getPotion().sendRemovePacket(player);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the player has a potion of type effect, remove it.
|
||||
*
|
||||
* @param player The player to remove from.
|
||||
* @param effect The {@link PotionEffect} to remove.
|
||||
*/
|
||||
public void removeEffect(@NotNull Player player, @NotNull PotionEffect effect) {
|
||||
PotionTask task = null;
|
||||
ArrayList<PotionTask> potionTasks = playerEffects.get(player.getUuid());
|
||||
if (potionTasks == null) return;
|
||||
for (PotionTask potionTask : potionTasks) {
|
||||
if (potionTask.getPotion().effect == effect) {
|
||||
task = potionTask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (task == null) return;
|
||||
removeEffect(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears a player's effects.
|
||||
*
|
||||
* @param player The player to clear.
|
||||
*/
|
||||
public void clearEffects(@Nullable Player player) {
|
||||
if (player == null) return;
|
||||
|
||||
ArrayList<PotionTask> potionTasks = playerEffects.get(player.getUuid());
|
||||
if (potionTasks == null) return;
|
||||
for (PotionTask potionTask : potionTasks) {
|
||||
potionTask.getValue().task.cancel();
|
||||
if (player.isOnline()) {
|
||||
potionTask.getPotion().sendRemovePacket(player);
|
||||
}
|
||||
}
|
||||
potionTasks.clear();
|
||||
playerEffects.remove(player.getUuid());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives a player a potion effect.
|
||||
*
|
||||
* @param player The player to give to.
|
||||
* @param potion The {@link Potion} to give.
|
||||
*/
|
||||
public void addPotion(@Nullable Player player, @Nullable Potion potion) {
|
||||
if (player == null) return;
|
||||
if (potion == null) return;
|
||||
removeEffect(player, potion.effect);
|
||||
ArrayList<PotionTask> potionTasks = playerEffects.computeIfAbsent(player.getUuid(), k -> new ArrayList<>());
|
||||
SchedulerManager schedulerManager = MinecraftServer.getSchedulerManager();
|
||||
PotionTimeTask ptt = new PotionTimeTask(MinecraftServer.getSchedulerManager(),
|
||||
TimeUnit.TICK.toMilliseconds(potion.duration));
|
||||
potionTasks.add(new PotionTask(potion, ptt));
|
||||
potion.sendAddPacket(player);
|
||||
}
|
||||
|
||||
// NOT IMPLEMENTED
|
||||
// public void setPersistEffects(Boolean persistEffects) {
|
||||
// this.persistEffects = persistEffects;
|
||||
// }
|
||||
//
|
||||
// public boolean getPersistEffects() {
|
||||
// return persistEffects;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Adds a {@link PlayerSpawnEvent} and {@link PlayerDisconnectEvent} handler to pause and resume potion effects.
|
||||
*/
|
||||
private void addEventHandlers() {
|
||||
GlobalEventHandler globalEventHandler = MinecraftServer.getGlobalEventHandler();
|
||||
globalEventHandler.addEventCallback(PlayerSpawnEvent.class, playerSpawnEvent -> {
|
||||
if (persistEffects) {
|
||||
// TODO: Implement persist
|
||||
}
|
||||
});
|
||||
|
||||
globalEventHandler.addEventCallback(PlayerDisconnectEvent.class, playerDisconnectEvent -> {
|
||||
if (persistEffects) {
|
||||
// TODO: Implement persist
|
||||
} else {
|
||||
clearEffects(playerDisconnectEvent.getPlayer());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
package net.minestom.server.potion;
|
||||
|
||||
import javafx.util.Pair;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
|
||||
public class PotionTask extends Pair<Potion, PotionTimeTask> {
|
||||
/**
|
||||
* Creates a new PotionTask
|
||||
*
|
||||
* @param potion The {@link Potion}
|
||||
* @param task The {@link PotionTimeTask}
|
||||
*/
|
||||
public PotionTask(Potion potion, PotionTimeTask task) {
|
||||
super(potion, task);
|
||||
task.potionTask = this;
|
||||
}
|
||||
|
||||
public Potion getPotion() {
|
||||
return this.getKey();
|
||||
}
|
||||
|
||||
public void removeEffect() {
|
||||
MinecraftServer.getPotionEffectManager().removeEffect(this);
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
package net.minestom.server.potion;
|
||||
|
||||
import net.minestom.server.timer.SchedulerManager;
|
||||
import net.minestom.server.timer.Task;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PotionTimeTask {
|
||||
|
||||
public Long remainingTime;
|
||||
public Task task;
|
||||
public PotionTask potionTask;
|
||||
|
||||
/**
|
||||
* Creates a task.
|
||||
*
|
||||
* @param schedulerManager The manager for the task
|
||||
* @param delay The time to delay
|
||||
*/
|
||||
public PotionTimeTask(@NotNull SchedulerManager schedulerManager, long delay) {
|
||||
Runnable runTask = () -> {
|
||||
potionTask.removeEffect();
|
||||
};
|
||||
task = schedulerManager.buildTask(runTask).delay(delay, TimeUnit.MILLISECOND).schedule();
|
||||
this.remainingTime = delay;
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package net.minestom.server.potion;
|
||||
|
||||
public class PotionTimeTaskHolder {
|
||||
/**
|
||||
* Only updates when task is paused
|
||||
*/
|
||||
public Long timeRemaining;
|
||||
|
||||
public PotionTimeTaskHolder() {
|
||||
// TODO: Implement persist
|
||||
}
|
||||
}
|
@ -9,9 +9,6 @@ import net.minestom.server.command.builder.arguments.ArgumentType;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.potion.Potion;
|
||||
import net.minestom.server.potion.PotionEffect;
|
||||
import net.minestom.server.potion.PotionTask;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PotionCommand extends Command {
|
||||
|
||||
@ -43,10 +40,12 @@ public class PotionCommand extends Command {
|
||||
final PotionEffect potion = args.getPotionEffect("potion");
|
||||
final int duration = args.getInteger("duration");
|
||||
|
||||
MinecraftServer.getPotionEffectManager().addPotion(player, new Potion(
|
||||
player.sendMessage(player.getActiveEffects().toString());
|
||||
|
||||
player.addEffect(new Potion(
|
||||
potion,
|
||||
(byte) 1,
|
||||
duration * 20
|
||||
(byte) 0,
|
||||
duration
|
||||
));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user