mirror of
https://github.com/Xiao-MoMi/Custom-Crops.git
synced 2025-12-28 03:19:15 +00:00
Fix some logics
This commit is contained in:
@@ -19,6 +19,7 @@ package net.momirealms.customcrops.api.action;
|
||||
|
||||
import dev.dejvokep.boostedyaml.block.implementation.Section;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.momirealms.customcrops.api.BukkitCustomCropsPlugin;
|
||||
import net.momirealms.customcrops.api.context.Context;
|
||||
import net.momirealms.customcrops.api.context.ContextKeys;
|
||||
@@ -32,6 +33,7 @@ import net.momirealms.customcrops.api.core.world.CustomCropsWorld;
|
||||
import net.momirealms.customcrops.api.core.world.Pos3;
|
||||
import net.momirealms.customcrops.api.core.wrapper.WrappedBreakEvent;
|
||||
import net.momirealms.customcrops.api.event.CropPlantEvent;
|
||||
import net.momirealms.customcrops.api.misc.HologramManager;
|
||||
import net.momirealms.customcrops.api.misc.placeholder.BukkitPlaceholderManager;
|
||||
import net.momirealms.customcrops.api.misc.value.MathValue;
|
||||
import net.momirealms.customcrops.api.misc.value.TextValue;
|
||||
@@ -40,7 +42,10 @@ import net.momirealms.customcrops.api.util.*;
|
||||
import net.momirealms.customcrops.common.helper.AdventureHelper;
|
||||
import net.momirealms.customcrops.common.helper.VersionHelper;
|
||||
import net.momirealms.customcrops.common.plugin.scheduler.SchedulerTask;
|
||||
import net.momirealms.customcrops.common.util.*;
|
||||
import net.momirealms.customcrops.common.util.ClassUtils;
|
||||
import net.momirealms.customcrops.common.util.ListUtils;
|
||||
import net.momirealms.customcrops.common.util.Pair;
|
||||
import net.momirealms.customcrops.common.util.RandomUtils;
|
||||
import net.momirealms.sparrow.heart.SparrowHeart;
|
||||
import net.momirealms.sparrow.heart.feature.entity.FakeEntity;
|
||||
import net.momirealms.sparrow.heart.feature.entity.armorstand.FakeArmorStand;
|
||||
@@ -83,6 +88,7 @@ public abstract class AbstractActionManager<T> implements ActionManager<T> {
|
||||
this.registerDropItemsAction();
|
||||
this.registerLegacyDropItemsAction();
|
||||
this.registerFakeItemAction();
|
||||
this.registerHologramAction();
|
||||
this.registerPlantAction();
|
||||
this.registerBreakAction();
|
||||
}
|
||||
@@ -725,21 +731,84 @@ public abstract class AbstractActionManager<T> implements ActionManager<T> {
|
||||
}, "drop-items");
|
||||
}
|
||||
|
||||
private void registerFakeItemAction() {
|
||||
protected void registerHologramAction() {
|
||||
registerAction(((args, chance) -> {
|
||||
if (args instanceof Section section) {
|
||||
TextValue<T> text = TextValue.auto(section.getString("text", ""));
|
||||
MathValue<T> duration = MathValue.auto(section.get("duration", 20));
|
||||
boolean other = section.getString("position", "other").equals("other");
|
||||
MathValue<T> x = MathValue.auto(section.get("x", 0));
|
||||
MathValue<T> y = MathValue.auto(section.get("y", 0));
|
||||
MathValue<T> z = MathValue.auto(section.get("z", 0));
|
||||
boolean applyCorrection = section.getBoolean("apply-correction", false);
|
||||
boolean onlyShowToOne = !section.getBoolean("visible-to-all", false);
|
||||
int range = section.getInt("range", 32);
|
||||
return context -> {
|
||||
if (context.holder() == null) return;
|
||||
if (Math.random() > chance) return;
|
||||
Player owner = null;
|
||||
if (context.holder() instanceof Player p) {
|
||||
owner = p;
|
||||
}
|
||||
Location location = other ? requireNonNull(context.arg(ContextKeys.LOCATION)).clone() : owner.getLocation().clone();
|
||||
Pos3 pos3 = Pos3.from(location).add(0,1,0);
|
||||
location.add(x.evaluate(context), y.evaluate(context), z.evaluate(context));
|
||||
Optional<CustomCropsWorld<?>> optionalWorld = plugin.getWorldManager().getWorld(location.getWorld());
|
||||
if (optionalWorld.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (applyCorrection) {
|
||||
Optional<CustomCropsBlockState> optionalState = optionalWorld.get().getBlockState(pos3);
|
||||
if (optionalState.isPresent()) {
|
||||
if (optionalState.get().type() instanceof CropBlock cropBlock) {
|
||||
CropConfig config = cropBlock.config(optionalState.get());
|
||||
int point = cropBlock.point(optionalState.get());
|
||||
if (config != null) {
|
||||
CropStageConfig stageConfig = config.stageWithModelByPoint(point);
|
||||
location.add(0,stageConfig.displayInfoOffset(),0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ArrayList<Player> viewers = new ArrayList<>();
|
||||
if (onlyShowToOne) {
|
||||
if (owner == null) return;
|
||||
viewers.add(owner);
|
||||
} else {
|
||||
for (Player player : location.getWorld().getPlayers()) {
|
||||
if (LocationUtils.getDistance(player.getLocation(), location) <= range) {
|
||||
viewers.add(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (viewers.isEmpty()) return;
|
||||
Component component = AdventureHelper.miniMessage(text.render(context));
|
||||
for (Player viewer : viewers) {
|
||||
HologramManager.getInstance().showHologram(viewer, location, AdventureHelper.componentToJson(component), (int) (duration.evaluate(context) * 50));
|
||||
}
|
||||
};
|
||||
} else {
|
||||
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at hologram action which is expected to be `Section`");
|
||||
return Action.empty();
|
||||
}
|
||||
}), "hologram");
|
||||
}
|
||||
|
||||
protected void registerFakeItemAction() {
|
||||
registerAction(((args, chance) -> {
|
||||
if (args instanceof Section section) {
|
||||
String itemID = section.getString("item", "");
|
||||
String[] split = itemID.split(":");
|
||||
if (split.length >= 2) itemID = split[split.length - 1];
|
||||
MathValue<T> duration = MathValue.auto(section.get("duration", 20));
|
||||
boolean position = !section.getString("position", "player").equals("player");
|
||||
boolean other = section.getString("position", "other").equals("other");
|
||||
MathValue<T> x = MathValue.auto(section.get("x", 0));
|
||||
MathValue<T> y = MathValue.auto(section.get("y", 0));
|
||||
MathValue<T> z = MathValue.auto(section.get("z", 0));
|
||||
MathValue<T> yaw = MathValue.auto(section.get("yaw", 0));
|
||||
int range = section.getInt("range", 0);
|
||||
int range = section.getInt("range", 32);
|
||||
boolean visibleToAll = section.getBoolean("visible-to-all", true);
|
||||
boolean useItemDisplay = section.getBoolean("use-item-display", false);
|
||||
boolean onlyShowToOne = !section.getBoolean("visible-to-all", true);
|
||||
String finalItemID = itemID;
|
||||
return context -> {
|
||||
if (Math.random() > chance) return;
|
||||
@@ -748,8 +817,8 @@ public abstract class AbstractActionManager<T> implements ActionManager<T> {
|
||||
if (context.holder() instanceof Player p) {
|
||||
owner = p;
|
||||
}
|
||||
Location location = position ? requireNonNull(context.arg(ContextKeys.LOCATION)).clone() : requireNonNull(owner).getLocation().clone();
|
||||
location.add(x.evaluate(context), y.evaluate(context) - 1, z.evaluate(context));
|
||||
Location location = other ? requireNonNull(context.arg(ContextKeys.LOCATION)).clone() : requireNonNull(owner).getLocation().clone();
|
||||
location.add(x.evaluate(context), y.evaluate(context), z.evaluate(context));
|
||||
location.setPitch(0);
|
||||
location.setYaw((float) yaw.evaluate(context));
|
||||
FakeEntity fakeEntity;
|
||||
@@ -765,19 +834,18 @@ public abstract class AbstractActionManager<T> implements ActionManager<T> {
|
||||
fakeEntity = armorStand;
|
||||
}
|
||||
ArrayList<Player> viewers = new ArrayList<>();
|
||||
if (onlyShowToOne) {
|
||||
viewers.add(owner);
|
||||
} else {
|
||||
if (range > 0) {
|
||||
for (Player player : location.getWorld().getPlayers()) {
|
||||
if (LocationUtils.getDistance(player.getLocation(), location) <= range) {
|
||||
viewers.add(player);
|
||||
}
|
||||
if (range > 0 && visibleToAll) {
|
||||
for (Player player : location.getWorld().getPlayers()) {
|
||||
if (LocationUtils.getDistance(player.getLocation(), location) <= range) {
|
||||
viewers.add(player);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
if (owner != null) {
|
||||
viewers.add(owner);
|
||||
}
|
||||
}
|
||||
if (viewers.isEmpty()) return;
|
||||
for (Player player : viewers) {
|
||||
fakeEntity.spawn(player);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package net.momirealms.customcrops.api.context;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
|
||||
import java.util.Objects;
|
||||
@@ -41,6 +42,7 @@ public class ContextKeys<T> {
|
||||
public static final ContextKeys<EquipmentSlot> SLOT = of("slot", EquipmentSlot.class);
|
||||
public static final ContextKeys<String> TEMP_NEAR_PLAYER = of("near", String.class);
|
||||
public static final ContextKeys<Boolean> OFFLINE = of("offline", Boolean.class);
|
||||
public static final ContextKeys<Player> PLAYER_INSTANCE = of("player_instance", Player.class);
|
||||
|
||||
private final String key;
|
||||
private final Class<T> type;
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
package net.momirealms.customcrops.api.core;
|
||||
|
||||
import net.momirealms.customcrops.common.util.Key;
|
||||
import net.momirealms.customcrops.api.core.item.CustomCropsItem;
|
||||
import net.momirealms.customcrops.common.util.Key;
|
||||
|
||||
public class BuiltInItemMechanics {
|
||||
|
||||
|
||||
@@ -16,9 +16,9 @@ import net.momirealms.customcrops.api.core.block.*;
|
||||
import net.momirealms.customcrops.api.core.item.FertilizerConfig;
|
||||
import net.momirealms.customcrops.api.core.item.FertilizerType;
|
||||
import net.momirealms.customcrops.api.core.item.WateringCanConfig;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
|
||||
import net.momirealms.customcrops.api.misc.water.FillMethod;
|
||||
import net.momirealms.customcrops.api.misc.water.WateringMethod;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
|
||||
import net.momirealms.customcrops.api.util.PluginUtils;
|
||||
import net.momirealms.customcrops.common.config.ConfigLoader;
|
||||
import net.momirealms.customcrops.common.plugin.feature.Reloadable;
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
|
||||
package net.momirealms.customcrops.api.core;
|
||||
|
||||
import net.momirealms.customcrops.common.util.Key;
|
||||
import net.momirealms.customcrops.api.core.block.CustomCropsBlock;
|
||||
import net.momirealms.customcrops.api.core.item.CustomCropsItem;
|
||||
import net.momirealms.customcrops.api.core.item.FertilizerType;
|
||||
import net.momirealms.customcrops.common.util.Key;
|
||||
|
||||
public interface RegistryAccess {
|
||||
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
|
||||
package net.momirealms.customcrops.api.core;
|
||||
|
||||
import net.momirealms.customcrops.common.util.Key;
|
||||
import net.momirealms.customcrops.api.BukkitCustomCropsPlugin;
|
||||
import net.momirealms.customcrops.api.core.block.CustomCropsBlock;
|
||||
import net.momirealms.customcrops.api.core.item.CustomCropsItem;
|
||||
import net.momirealms.customcrops.api.core.item.FertilizerType;
|
||||
import net.momirealms.customcrops.common.util.Key;
|
||||
|
||||
public class SimpleRegistryAccess implements RegistryAccess {
|
||||
|
||||
|
||||
@@ -21,13 +21,13 @@ import com.flowpowered.nbt.CompoundMap;
|
||||
import com.flowpowered.nbt.IntTag;
|
||||
import com.flowpowered.nbt.StringTag;
|
||||
import com.flowpowered.nbt.Tag;
|
||||
import net.momirealms.customcrops.common.util.Key;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsWorld;
|
||||
import net.momirealms.customcrops.api.core.world.Pos3;
|
||||
import net.momirealms.customcrops.api.core.wrapper.WrappedBreakEvent;
|
||||
import net.momirealms.customcrops.api.core.wrapper.WrappedInteractEvent;
|
||||
import net.momirealms.customcrops.api.core.wrapper.WrappedPlaceEvent;
|
||||
import net.momirealms.customcrops.common.util.Key;
|
||||
|
||||
public abstract class AbstractCustomCropsBlock implements CustomCropsBlock {
|
||||
|
||||
|
||||
@@ -99,6 +99,7 @@ public class CropBlock extends AbstractCustomCropsBlock {
|
||||
|
||||
final Player player = event.playerBreaker();
|
||||
Context<Player> context = Context.player(player);
|
||||
context.arg(ContextKeys.LOCATION, LocationUtils.toBlockLocation(event.location()));
|
||||
|
||||
// check requirements
|
||||
if (!RequirementManager.isSatisfied(context, cropConfig.breakRequirements())) {
|
||||
@@ -156,6 +157,7 @@ public class CropBlock extends AbstractCustomCropsBlock {
|
||||
public void onInteract(WrappedInteractEvent event) {
|
||||
final Player player = event.player();
|
||||
Context<Player> context = Context.player(player);
|
||||
context.arg(ContextKeys.SLOT, event.hand());
|
||||
|
||||
// data first
|
||||
CustomCropsWorld<?> world = event.world();
|
||||
@@ -171,7 +173,8 @@ public class CropBlock extends AbstractCustomCropsBlock {
|
||||
}
|
||||
|
||||
int point = point(state);
|
||||
CropStageConfig stageConfig = cropConfig.getFloorStageEntry(point).getValue();
|
||||
CropStageConfig stageConfig = cropConfig.stageByID(event.relatedID());
|
||||
assert stageConfig != null;
|
||||
if (!RequirementManager.isSatisfied(context, stageConfig.interactRequirements())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
package net.momirealms.customcrops.api.core.block;
|
||||
|
||||
import com.flowpowered.nbt.CompoundMap;
|
||||
import net.momirealms.customcrops.common.util.Key;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsWorld;
|
||||
import net.momirealms.customcrops.api.core.world.Pos3;
|
||||
import net.momirealms.customcrops.api.core.wrapper.WrappedBreakEvent;
|
||||
import net.momirealms.customcrops.api.core.wrapper.WrappedInteractEvent;
|
||||
import net.momirealms.customcrops.api.core.wrapper.WrappedPlaceEvent;
|
||||
import net.momirealms.customcrops.common.util.Key;
|
||||
|
||||
public interface CustomCropsBlock {
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ import net.momirealms.customcrops.api.context.ContextKeys;
|
||||
import net.momirealms.customcrops.api.core.*;
|
||||
import net.momirealms.customcrops.api.core.item.Fertilizer;
|
||||
import net.momirealms.customcrops.api.core.item.FertilizerConfig;
|
||||
import net.momirealms.customcrops.api.misc.water.WateringMethod;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsWorld;
|
||||
import net.momirealms.customcrops.api.core.world.Pos3;
|
||||
@@ -33,6 +32,7 @@ import net.momirealms.customcrops.api.core.wrapper.WrappedBreakEvent;
|
||||
import net.momirealms.customcrops.api.core.wrapper.WrappedInteractEvent;
|
||||
import net.momirealms.customcrops.api.core.wrapper.WrappedPlaceEvent;
|
||||
import net.momirealms.customcrops.api.event.*;
|
||||
import net.momirealms.customcrops.api.misc.water.WateringMethod;
|
||||
import net.momirealms.customcrops.api.requirement.RequirementManager;
|
||||
import net.momirealms.customcrops.api.util.EventUtils;
|
||||
import net.momirealms.customcrops.api.util.LocationUtils;
|
||||
@@ -222,6 +222,7 @@ public class PotBlock extends AbstractCustomCropsBlock {
|
||||
|
||||
final Player player = event.player();
|
||||
Context<Player> context = Context.player(player);
|
||||
context.arg(ContextKeys.SLOT, event.hand());
|
||||
context.arg(ContextKeys.LOCATION, LocationUtils.toBlockLocation(location));
|
||||
|
||||
// check use requirements
|
||||
|
||||
@@ -19,9 +19,9 @@ package net.momirealms.customcrops.api.core.block;
|
||||
|
||||
import net.momirealms.customcrops.api.action.Action;
|
||||
import net.momirealms.customcrops.api.core.item.FertilizerType;
|
||||
import net.momirealms.customcrops.api.misc.water.WateringMethod;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
|
||||
import net.momirealms.customcrops.api.misc.water.WaterBar;
|
||||
import net.momirealms.customcrops.api.misc.water.WateringMethod;
|
||||
import net.momirealms.customcrops.api.requirement.Requirement;
|
||||
import net.momirealms.customcrops.common.util.Pair;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@@ -20,9 +20,9 @@ package net.momirealms.customcrops.api.core.block;
|
||||
import net.momirealms.customcrops.api.action.Action;
|
||||
import net.momirealms.customcrops.api.core.ExistenceForm;
|
||||
import net.momirealms.customcrops.api.core.item.FertilizerType;
|
||||
import net.momirealms.customcrops.api.misc.water.WateringMethod;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
|
||||
import net.momirealms.customcrops.api.misc.water.WaterBar;
|
||||
import net.momirealms.customcrops.api.misc.water.WateringMethod;
|
||||
import net.momirealms.customcrops.api.requirement.Requirement;
|
||||
import net.momirealms.customcrops.common.util.Pair;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@@ -26,7 +26,9 @@ import net.momirealms.customcrops.api.core.world.Pos3;
|
||||
import net.momirealms.customcrops.api.core.wrapper.WrappedBreakEvent;
|
||||
import net.momirealms.customcrops.api.core.wrapper.WrappedInteractEvent;
|
||||
import net.momirealms.customcrops.api.core.wrapper.WrappedPlaceEvent;
|
||||
import net.momirealms.customcrops.api.event.*;
|
||||
import net.momirealms.customcrops.api.event.ScarecrowBreakEvent;
|
||||
import net.momirealms.customcrops.api.event.ScarecrowInteractEvent;
|
||||
import net.momirealms.customcrops.api.event.ScarecrowPlaceEvent;
|
||||
import net.momirealms.customcrops.api.util.EventUtils;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -18,11 +18,12 @@
|
||||
package net.momirealms.customcrops.api.core.block;
|
||||
|
||||
import com.flowpowered.nbt.IntTag;
|
||||
import com.flowpowered.nbt.Tag;
|
||||
import net.momirealms.customcrops.api.BukkitCustomCropsPlugin;
|
||||
import net.momirealms.customcrops.api.action.ActionManager;
|
||||
import net.momirealms.customcrops.api.context.Context;
|
||||
import net.momirealms.customcrops.api.context.ContextKeys;
|
||||
import net.momirealms.customcrops.api.core.*;
|
||||
import net.momirealms.customcrops.api.misc.water.WateringMethod;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsWorld;
|
||||
import net.momirealms.customcrops.api.core.world.Pos3;
|
||||
@@ -33,8 +34,10 @@ import net.momirealms.customcrops.api.event.SprinklerBreakEvent;
|
||||
import net.momirealms.customcrops.api.event.SprinklerFillEvent;
|
||||
import net.momirealms.customcrops.api.event.SprinklerInteractEvent;
|
||||
import net.momirealms.customcrops.api.event.SprinklerPlaceEvent;
|
||||
import net.momirealms.customcrops.api.misc.water.WateringMethod;
|
||||
import net.momirealms.customcrops.api.requirement.RequirementManager;
|
||||
import net.momirealms.customcrops.api.util.EventUtils;
|
||||
import net.momirealms.customcrops.api.util.LocationUtils;
|
||||
import net.momirealms.customcrops.api.util.PlayerUtils;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
@@ -77,6 +80,7 @@ public class SprinklerBlock extends AbstractCustomCropsBlock {
|
||||
|
||||
final Player player = event.playerBreaker();
|
||||
Context<Player> context = Context.player(player);
|
||||
context.arg(ContextKeys.LOCATION, LocationUtils.toBlockLocation(event.location()));
|
||||
CustomCropsBlockState state = fixOrGetState(world, pos3, config, event.brokenID());
|
||||
if (!RequirementManager.isSatisfied(context, config.breakRequirements())) {
|
||||
event.setCancelled(true);
|
||||
@@ -103,6 +107,7 @@ public class SprinklerBlock extends AbstractCustomCropsBlock {
|
||||
|
||||
final Player player = event.player();
|
||||
Context<Player> context = Context.player(player);
|
||||
context.arg(ContextKeys.LOCATION, LocationUtils.toBlockLocation(event.location()));
|
||||
if (!RequirementManager.isSatisfied(context, config.placeRequirements())) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
@@ -140,8 +145,11 @@ public class SprinklerBlock extends AbstractCustomCropsBlock {
|
||||
}
|
||||
|
||||
final Player player = event.player();
|
||||
Location location = LocationUtils.toBlockLocation(event.location());
|
||||
Context<Player> context = Context.player(player);
|
||||
CustomCropsBlockState state = fixOrGetState(event.world(), Pos3.from(event.location()), config, event.relatedID());
|
||||
context.arg(ContextKeys.SLOT, event.hand());
|
||||
context.arg(ContextKeys.LOCATION, location);
|
||||
CustomCropsBlockState state = fixOrGetState(event.world(), Pos3.from(location), config, event.relatedID());
|
||||
if (!RequirementManager.isSatisfied(context, config.useRequirements())) {
|
||||
return;
|
||||
}
|
||||
@@ -149,14 +157,20 @@ public class SprinklerBlock extends AbstractCustomCropsBlock {
|
||||
int waterInSprinkler = water(state);
|
||||
String itemID = event.itemID();
|
||||
ItemStack itemInHand = event.itemInHand();
|
||||
|
||||
context.arg(ContextKeys.STORAGE, config.storage());
|
||||
|
||||
if (!config.infinite()) {
|
||||
for (WateringMethod method : config.wateringMethods()) {
|
||||
if (method.getUsed().equals(itemID) && method.getUsedAmount() <= itemInHand.getAmount()) {
|
||||
if (method.checkRequirements(context)) {
|
||||
if (waterInSprinkler >= config.storage()) {
|
||||
context.arg(ContextKeys.CURRENT_WATER, waterInSprinkler);
|
||||
context.arg(ContextKeys.WATER_BAR, Optional.ofNullable(config.waterBar()).map(it -> it.getWaterBar(waterInSprinkler, config.storage())).orElse(""));
|
||||
ActionManager.trigger(context, config.fullWaterActions());
|
||||
ActionManager.trigger(context, config.interactActions());
|
||||
} else {
|
||||
SprinklerFillEvent waterEvent = new SprinklerFillEvent(player, itemInHand, event.hand(), event.location(), method, state, config);
|
||||
SprinklerFillEvent waterEvent = new SprinklerFillEvent(player, itemInHand, event.hand(), location, method, state, config);
|
||||
if (EventUtils.fireAndCheckCancel(waterEvent))
|
||||
return;
|
||||
if (player.getGameMode() != GameMode.CREATIVE) {
|
||||
@@ -168,8 +182,16 @@ public class SprinklerBlock extends AbstractCustomCropsBlock {
|
||||
}
|
||||
}
|
||||
}
|
||||
int currentWater = Math.min(config.storage(), waterInSprinkler + method.amountOfWater());
|
||||
context.arg(ContextKeys.CURRENT_WATER, currentWater);
|
||||
context.arg(ContextKeys.WATER_BAR, Optional.ofNullable(config.waterBar()).map(it -> it.getWaterBar(currentWater, config.storage())).orElse(""));
|
||||
if (addWater(state, config, method.amountOfWater()) && !config.threeDItem().equals(config.threeDItemWithWater())) {
|
||||
updateBlockAppearance(location, config, false);
|
||||
}
|
||||
|
||||
method.triggerActions(context);
|
||||
ActionManager.trigger(context, config.addWaterActions());
|
||||
ActionManager.trigger(context, config.interactActions());
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -177,7 +199,10 @@ public class SprinklerBlock extends AbstractCustomCropsBlock {
|
||||
}
|
||||
}
|
||||
|
||||
SprinklerInteractEvent interactEvent = new SprinklerInteractEvent(player, event.itemInHand(), event.location(), config, state, event.hand());
|
||||
context.arg(ContextKeys.WATER_BAR, Optional.ofNullable(config.waterBar()).map(it -> it.getWaterBar(waterInSprinkler, config.storage())).orElse(""));
|
||||
context.arg(ContextKeys.CURRENT_WATER, waterInSprinkler);
|
||||
|
||||
SprinklerInteractEvent interactEvent = new SprinklerInteractEvent(player, itemInHand, location, config, state, event.hand());
|
||||
if (EventUtils.fireAndCheckCancel(interactEvent)) {
|
||||
return;
|
||||
}
|
||||
@@ -220,8 +245,7 @@ public class SprinklerBlock extends AbstractCustomCropsBlock {
|
||||
if (water <= 0) {
|
||||
return;
|
||||
}
|
||||
water(state, --water);
|
||||
updateState = water == 0;
|
||||
updateState = water(state, config, water - 1);
|
||||
} else {
|
||||
updateState = false;
|
||||
}
|
||||
@@ -229,6 +253,7 @@ public class SprinklerBlock extends AbstractCustomCropsBlock {
|
||||
Context<CustomCropsBlockState> context = Context.block(state);
|
||||
World bukkitWorld = world.bukkitWorld();
|
||||
Location bukkitLocation = location.toLocation(bukkitWorld);
|
||||
context.arg(ContextKeys.LOCATION, bukkitLocation);
|
||||
|
||||
CompletableFuture<Boolean> syncCheck = new CompletableFuture<>();
|
||||
|
||||
@@ -300,7 +325,11 @@ public class SprinklerBlock extends AbstractCustomCropsBlock {
|
||||
}
|
||||
|
||||
public int water(CustomCropsBlockState state) {
|
||||
return state.get("water").getAsIntTag().map(IntTag::getValue).orElse(0);
|
||||
Tag<?> tag = state.get("water");
|
||||
if (tag == null) {
|
||||
return 0;
|
||||
}
|
||||
return tag.getAsIntTag().map(IntTag::getValue).orElse(0);
|
||||
}
|
||||
|
||||
public boolean water(CustomCropsBlockState state, int water) {
|
||||
|
||||
@@ -19,9 +19,9 @@ package net.momirealms.customcrops.api.core.block;
|
||||
|
||||
import net.momirealms.customcrops.api.action.Action;
|
||||
import net.momirealms.customcrops.api.core.ExistenceForm;
|
||||
import net.momirealms.customcrops.api.misc.water.WateringMethod;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
|
||||
import net.momirealms.customcrops.api.misc.water.WaterBar;
|
||||
import net.momirealms.customcrops.api.misc.water.WateringMethod;
|
||||
import net.momirealms.customcrops.api.requirement.Requirement;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -19,9 +19,9 @@ package net.momirealms.customcrops.api.core.block;
|
||||
|
||||
import net.momirealms.customcrops.api.action.Action;
|
||||
import net.momirealms.customcrops.api.core.ExistenceForm;
|
||||
import net.momirealms.customcrops.api.misc.water.WateringMethod;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
|
||||
import net.momirealms.customcrops.api.misc.water.WaterBar;
|
||||
import net.momirealms.customcrops.api.misc.water.WateringMethod;
|
||||
import net.momirealms.customcrops.api.requirement.Requirement;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
|
||||
package net.momirealms.customcrops.api.core.item;
|
||||
|
||||
import net.momirealms.customcrops.common.util.Key;
|
||||
import net.momirealms.customcrops.api.core.InteractionResult;
|
||||
import net.momirealms.customcrops.api.core.wrapper.WrappedInteractAirEvent;
|
||||
import net.momirealms.customcrops.api.core.wrapper.WrappedInteractEvent;
|
||||
import net.momirealms.customcrops.common.util.Key;
|
||||
|
||||
public abstract class AbstractCustomCropsItem implements CustomCropsItem {
|
||||
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
|
||||
package net.momirealms.customcrops.api.core.item;
|
||||
|
||||
import net.momirealms.customcrops.common.util.Key;
|
||||
import net.momirealms.customcrops.api.core.InteractionResult;
|
||||
import net.momirealms.customcrops.api.core.wrapper.WrappedInteractAirEvent;
|
||||
import net.momirealms.customcrops.api.core.wrapper.WrappedInteractEvent;
|
||||
import net.momirealms.customcrops.common.util.Key;
|
||||
|
||||
public interface CustomCropsItem {
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ package net.momirealms.customcrops.api.core.item;
|
||||
import net.momirealms.customcrops.api.BukkitCustomCropsPlugin;
|
||||
import net.momirealms.customcrops.api.action.ActionManager;
|
||||
import net.momirealms.customcrops.api.context.Context;
|
||||
import net.momirealms.customcrops.api.context.ContextKeys;
|
||||
import net.momirealms.customcrops.api.core.BuiltInBlockMechanics;
|
||||
import net.momirealms.customcrops.api.core.BuiltInItemMechanics;
|
||||
import net.momirealms.customcrops.api.core.InteractionResult;
|
||||
@@ -35,6 +36,7 @@ import net.momirealms.customcrops.api.core.wrapper.WrappedInteractEvent;
|
||||
import net.momirealms.customcrops.api.event.FertilizerUseEvent;
|
||||
import net.momirealms.customcrops.api.requirement.RequirementManager;
|
||||
import net.momirealms.customcrops.api.util.EventUtils;
|
||||
import net.momirealms.customcrops.api.util.LocationUtils;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -56,12 +58,14 @@ public class FertilizerItem extends AbstractCustomCropsItem {
|
||||
return InteractionResult.COMPLETE;
|
||||
}
|
||||
|
||||
Location targetLocation = LocationUtils.toBlockLocation(event.location());
|
||||
final Player player = event.player();
|
||||
final Context<Player> context = Context.player(player);
|
||||
context.arg(ContextKeys.SLOT, event.hand());
|
||||
|
||||
final CustomCropsWorld<?> world = event.world();
|
||||
final ItemStack itemInHand = event.itemInHand();
|
||||
String targetBlockID = event.relatedID();
|
||||
Location targetLocation = event.location();
|
||||
|
||||
// if the clicked block is a crop, correct the target block
|
||||
List<CropConfig> cropConfigs = Registries.STAGE_TO_CROP_UNSAFE.get(event.relatedID());
|
||||
@@ -71,6 +75,8 @@ public class FertilizerItem extends AbstractCustomCropsItem {
|
||||
targetBlockID = BukkitCustomCropsPlugin.getInstance().getItemManager().blockID(targetLocation);
|
||||
}
|
||||
|
||||
context.arg(ContextKeys.LOCATION, targetLocation);
|
||||
|
||||
// if the clicked block is a pot
|
||||
PotConfig potConfig = Registries.ITEM_TO_POT.get(targetBlockID);
|
||||
if (potConfig != null) {
|
||||
|
||||
@@ -64,7 +64,10 @@ public class SeedItem extends AbstractCustomCropsItem {
|
||||
if (event.clickedBlockFace() != BlockFace.UP)
|
||||
return InteractionResult.PASS;
|
||||
final Player player = event.player();
|
||||
Location seedLocation = LocationUtils.toBlockLocation(event.location().add(0, 1, 0));
|
||||
Context<Player> context = Context.player(player);
|
||||
context.arg(ContextKeys.SLOT, event.hand());
|
||||
context.arg(ContextKeys.LOCATION, seedLocation);
|
||||
// check pot whitelist
|
||||
if (!cropConfig.potWhitelist().contains(potConfig.id())) {
|
||||
ActionManager.trigger(context, cropConfig.wrongPotActions());
|
||||
@@ -74,7 +77,6 @@ public class SeedItem extends AbstractCustomCropsItem {
|
||||
return InteractionResult.COMPLETE;
|
||||
}
|
||||
// check if the block is empty
|
||||
Location seedLocation = event.location().add(0, 1, 0);
|
||||
if (!suitableForSeed(seedLocation)) {
|
||||
return InteractionResult.COMPLETE;
|
||||
}
|
||||
@@ -112,7 +114,7 @@ public class SeedItem extends AbstractCustomCropsItem {
|
||||
if (player.getGameMode() != GameMode.CREATIVE)
|
||||
itemInHand.setAmount(itemInHand.getAmount() - 1);
|
||||
// place model
|
||||
BukkitCustomCropsPlugin.getInstance().getItemManager().place(seedLocation, form, stageID, cropConfig.rotation() ? FurnitureRotation.random() : FurnitureRotation.NONE);
|
||||
BukkitCustomCropsPlugin.getInstance().getItemManager().place(LocationUtils.toSurfaceCenterLocation(seedLocation), form, stageID, cropConfig.rotation() ? FurnitureRotation.random() : FurnitureRotation.NONE);
|
||||
cropBlock.point(state, point);
|
||||
world.addBlockState(pos3, state).ifPresent(previous -> {
|
||||
BukkitCustomCropsPlugin.getInstance().debug(
|
||||
|
||||
@@ -20,6 +20,7 @@ package net.momirealms.customcrops.api.core.item;
|
||||
import net.momirealms.customcrops.api.BukkitCustomCropsPlugin;
|
||||
import net.momirealms.customcrops.api.action.ActionManager;
|
||||
import net.momirealms.customcrops.api.context.Context;
|
||||
import net.momirealms.customcrops.api.context.ContextKeys;
|
||||
import net.momirealms.customcrops.api.core.*;
|
||||
import net.momirealms.customcrops.api.core.block.SprinklerBlock;
|
||||
import net.momirealms.customcrops.api.core.block.SprinklerConfig;
|
||||
@@ -54,7 +55,7 @@ public class SprinklerItem extends AbstractCustomCropsItem {
|
||||
// should be place on block
|
||||
if (event.existenceForm() != ExistenceForm.BLOCK)
|
||||
return InteractionResult.PASS;
|
||||
SprinklerConfig config = Registries.SPRINKLER.get(event.itemID());
|
||||
SprinklerConfig config = Registries.ITEM_TO_SPRINKLER.get(event.itemID());
|
||||
if (config == null) {
|
||||
return InteractionResult.COMPLETE;
|
||||
}
|
||||
@@ -68,7 +69,7 @@ public class SprinklerItem extends AbstractCustomCropsItem {
|
||||
return InteractionResult.PASS;
|
||||
if (!clicked.isSolid())
|
||||
return InteractionResult.PASS;
|
||||
targetLocation = event.location().clone().add(0,1,0);
|
||||
targetLocation = LocationUtils.toBlockLocation(event.location().clone().add(0,1,0));
|
||||
if (!suitableForSprinkler(targetLocation)) {
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
@@ -77,6 +78,7 @@ public class SprinklerItem extends AbstractCustomCropsItem {
|
||||
final Player player = event.player();
|
||||
final ItemStack itemInHand = event.itemInHand();
|
||||
Context<Player> context = Context.player(player);
|
||||
context.arg(ContextKeys.LOCATION, targetLocation);
|
||||
// check requirements
|
||||
if (!RequirementManager.isSatisfied(context, config.placeRequirements())) {
|
||||
return InteractionResult.COMPLETE;
|
||||
@@ -100,11 +102,11 @@ public class SprinklerItem extends AbstractCustomCropsItem {
|
||||
SprinklerPlaceEvent placeEvent = new SprinklerPlaceEvent(player, itemInHand, event.hand(), targetLocation.clone(), config, state);
|
||||
if (EventUtils.fireAndCheckCancel(placeEvent))
|
||||
return InteractionResult.COMPLETE;
|
||||
|
||||
// clear replaceable block
|
||||
targetLocation.getBlock().setType(Material.AIR, false);
|
||||
if (player.getGameMode() != GameMode.CREATIVE)
|
||||
itemInHand.setAmount(itemInHand.getAmount() - 1);
|
||||
|
||||
// place the sprinkler
|
||||
BukkitCustomCropsPlugin.getInstance().getItemManager().place(LocationUtils.toSurfaceCenterLocation(targetLocation), config.existenceForm(), config.threeDItem(), FurnitureRotation.NONE);
|
||||
world.addBlockState(pos3, state).ifPresent(previous -> {
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
package net.momirealms.customcrops.api.core.item;
|
||||
|
||||
import net.momirealms.customcrops.api.action.Action;
|
||||
import net.momirealms.customcrops.api.misc.value.TextValue;
|
||||
import net.momirealms.customcrops.api.misc.water.FillMethod;
|
||||
import net.momirealms.customcrops.api.misc.water.WaterBar;
|
||||
import net.momirealms.customcrops.api.misc.value.TextValue;
|
||||
import net.momirealms.customcrops.api.requirement.Requirement;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
package net.momirealms.customcrops.api.core.item;
|
||||
|
||||
import net.momirealms.customcrops.api.action.Action;
|
||||
import net.momirealms.customcrops.api.misc.value.TextValue;
|
||||
import net.momirealms.customcrops.api.misc.water.FillMethod;
|
||||
import net.momirealms.customcrops.api.misc.water.WaterBar;
|
||||
import net.momirealms.customcrops.api.misc.value.TextValue;
|
||||
import net.momirealms.customcrops.api.requirement.Requirement;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ import net.momirealms.customcrops.api.context.Context;
|
||||
import net.momirealms.customcrops.api.context.ContextKeys;
|
||||
import net.momirealms.customcrops.api.core.*;
|
||||
import net.momirealms.customcrops.api.core.block.*;
|
||||
import net.momirealms.customcrops.api.misc.water.FillMethod;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsWorld;
|
||||
import net.momirealms.customcrops.api.core.world.Pos3;
|
||||
@@ -35,8 +34,10 @@ import net.momirealms.customcrops.api.event.WateringCanFillEvent;
|
||||
import net.momirealms.customcrops.api.event.WateringCanWaterPotEvent;
|
||||
import net.momirealms.customcrops.api.event.WateringCanWaterSprinklerEvent;
|
||||
import net.momirealms.customcrops.api.misc.value.TextValue;
|
||||
import net.momirealms.customcrops.api.misc.water.FillMethod;
|
||||
import net.momirealms.customcrops.api.requirement.RequirementManager;
|
||||
import net.momirealms.customcrops.api.util.EventUtils;
|
||||
import net.momirealms.customcrops.api.util.LocationUtils;
|
||||
import net.momirealms.customcrops.common.helper.AdventureHelper;
|
||||
import net.momirealms.customcrops.common.item.Item;
|
||||
import net.momirealms.customcrops.common.util.Pair;
|
||||
@@ -112,6 +113,7 @@ public class WateringCanItem extends AbstractCustomCropsItem {
|
||||
|
||||
final Player player = event.player();;
|
||||
Context<Player> context = Context.player(player);
|
||||
context.arg(ContextKeys.SLOT, event.hand());
|
||||
// check requirements
|
||||
if (!RequirementManager.isSatisfied(context, config.requirements()))
|
||||
return;
|
||||
@@ -166,7 +168,10 @@ public class WateringCanItem extends AbstractCustomCropsItem {
|
||||
return InteractionResult.COMPLETE;
|
||||
|
||||
final Player player = event.player();
|
||||
Location targetLocation = LocationUtils.toBlockLocation(event.location());
|
||||
final Context<Player> context = Context.player(player);
|
||||
context.arg(ContextKeys.SLOT, event.hand());
|
||||
context.arg(ContextKeys.LOCATION, targetLocation);
|
||||
|
||||
// check watering can requirements
|
||||
if (!RequirementManager.isSatisfied(context, wateringCanConfig.requirements())) {
|
||||
@@ -176,7 +181,7 @@ public class WateringCanItem extends AbstractCustomCropsItem {
|
||||
final CustomCropsWorld<?> world = event.world();
|
||||
final ItemStack itemInHand = event.itemInHand();
|
||||
String targetBlockID = event.relatedID();
|
||||
Location targetLocation = event.location();
|
||||
|
||||
BlockFace blockFace = event.clickedBlockFace();
|
||||
|
||||
int waterInCan = getCurrentWater(itemInHand);
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
package net.momirealms.customcrops.api.event;
|
||||
|
||||
import net.momirealms.customcrops.api.core.block.PotConfig;
|
||||
import net.momirealms.customcrops.api.misc.water.WateringMethod;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
|
||||
import net.momirealms.customcrops.api.misc.water.WateringMethod;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
package net.momirealms.customcrops.api.event;
|
||||
|
||||
import net.momirealms.customcrops.api.core.block.SprinklerConfig;
|
||||
import net.momirealms.customcrops.api.misc.water.WateringMethod;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
|
||||
import net.momirealms.customcrops.api.misc.water.WateringMethod;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (C) <2024> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.api.misc;
|
||||
|
||||
import net.momirealms.customcrops.api.BukkitCustomCropsPlugin;
|
||||
import net.momirealms.customcrops.common.helper.VersionHelper;
|
||||
import net.momirealms.customcrops.common.plugin.feature.Reloadable;
|
||||
import net.momirealms.customcrops.common.plugin.scheduler.SchedulerTask;
|
||||
import net.momirealms.customcrops.common.util.Pair;
|
||||
import net.momirealms.sparrow.heart.SparrowHeart;
|
||||
import net.momirealms.sparrow.heart.feature.entity.FakeNamedEntity;
|
||||
import net.momirealms.sparrow.heart.feature.entity.armorstand.FakeArmorStand;
|
||||
import net.momirealms.sparrow.heart.feature.entity.display.FakeTextDisplay;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class HologramManager implements Listener, Reloadable {
|
||||
|
||||
private final ConcurrentHashMap<UUID, HologramCache> hologramMap = new ConcurrentHashMap<>();
|
||||
private final BukkitCustomCropsPlugin plugin;
|
||||
private SchedulerTask cacheCheckTask;
|
||||
private static HologramManager manager;
|
||||
|
||||
public static HologramManager getInstance() {
|
||||
return manager;
|
||||
}
|
||||
|
||||
public HologramManager(BukkitCustomCropsPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
manager = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin.getBoostrap());
|
||||
this.cacheCheckTask = plugin.getScheduler().asyncRepeating(() -> {
|
||||
ArrayList<UUID> removed = new ArrayList<>();
|
||||
long current = System.currentTimeMillis();
|
||||
for (Map.Entry<UUID, HologramCache> entry : hologramMap.entrySet()) {
|
||||
Player player = Bukkit.getPlayer(entry.getKey());
|
||||
if (player == null || !player.isOnline()) {
|
||||
removed.add(entry.getKey());
|
||||
} else {
|
||||
entry.getValue().removeOutDated(current, player);
|
||||
}
|
||||
}
|
||||
for (UUID uuid : removed) {
|
||||
hologramMap.remove(uuid);
|
||||
}
|
||||
}, 100, 100, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload() {
|
||||
HandlerList.unregisterAll(this);
|
||||
for (Map.Entry<UUID, HologramCache> entry : hologramMap.entrySet()) {
|
||||
Player player = Bukkit.getPlayer(entry.getKey());
|
||||
if (player != null && player.isOnline()) {
|
||||
entry.getValue().removeAll(player);
|
||||
}
|
||||
}
|
||||
if (cacheCheckTask != null) cacheCheckTask.cancel();
|
||||
this.hologramMap.clear();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerQuitEvent event) {
|
||||
this.hologramMap.remove(event.getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
public void showHologram(Player player, Location location, String json, int millis) {
|
||||
HologramCache hologramCache = hologramMap.get(player.getUniqueId());
|
||||
if (hologramCache != null) {
|
||||
hologramCache.showHologram(player, location, json, millis);
|
||||
} else {
|
||||
hologramCache = new HologramCache();
|
||||
hologramCache.showHologram(player, location, json, millis);
|
||||
hologramMap.put(player.getUniqueId(), hologramCache);
|
||||
}
|
||||
}
|
||||
|
||||
public static class HologramCache {
|
||||
|
||||
private final ConcurrentHashMap<Location, Pair<FakeNamedEntity, Long>> cache = new ConcurrentHashMap<>();
|
||||
|
||||
public void removeOutDated(long current, Player player) {
|
||||
ArrayList<Location> removed = new ArrayList<>();
|
||||
for (Map.Entry<Location, Pair<FakeNamedEntity, Long>> entry : cache.entrySet()) {
|
||||
if (entry.getValue().right() < current) {
|
||||
entry.getValue().left().destroy(player);
|
||||
removed.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
for (Location location : removed) {
|
||||
cache.remove(location);
|
||||
}
|
||||
}
|
||||
|
||||
public void showHologram(Player player, Location location, String json, int millis) {
|
||||
Pair<FakeNamedEntity, Long> pair = cache.get(location);
|
||||
if (pair != null) {
|
||||
pair.left().name(json);
|
||||
pair.left().updateMetaData(player);
|
||||
pair.right(System.currentTimeMillis() + millis);
|
||||
} else {
|
||||
long removeTime = System.currentTimeMillis() + millis;
|
||||
if (VersionHelper.isVersionNewerThan1_19_4()) {
|
||||
FakeTextDisplay fakeEntity = SparrowHeart.getInstance().createFakeTextDisplay(location.clone().add(0,1.25,0));
|
||||
fakeEntity.name(json);
|
||||
fakeEntity.rgba(0, 0, 0, 0);
|
||||
fakeEntity.spawn(player);
|
||||
this.cache.put(location, Pair.of(fakeEntity, removeTime));
|
||||
} else {
|
||||
FakeArmorStand fakeEntity = SparrowHeart.getInstance().createFakeArmorStand(location);
|
||||
fakeEntity.name(json);
|
||||
fakeEntity.small(true);
|
||||
fakeEntity.invisible(true);
|
||||
fakeEntity.spawn(player);
|
||||
this.cache.put(location, Pair.of(fakeEntity, removeTime));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAll(Player player) {
|
||||
for (Map.Entry<Location, Pair<FakeNamedEntity, Long>> entry : this.cache.entrySet()) {
|
||||
entry.getValue().left().destroy(player);
|
||||
}
|
||||
cache.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user