Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d081afbd8e | ||
|
|
46fd0439a5 | ||
|
|
ad58ce4a74 | ||
|
|
b5cd8f42e0 | ||
|
|
d0baf50709 | ||
|
|
2496f318fa | ||
|
|
048c200c95 | ||
|
|
17446acb2e | ||
|
|
7929113c91 | ||
|
|
6acc5864bd | ||
|
|
730c20dbc0 | ||
|
|
0c5ae54c3a | ||
|
|
b48e80837d | ||
|
|
17eb4cf5f8 | ||
|
|
890f85fa56 | ||
|
|
86b427c95e | ||
|
|
8c1fde57b0 | ||
|
|
2efc040a8e | ||
|
|
54b2b42512 | ||
|
|
e67d9d634c | ||
|
|
39fb676b9a | ||
|
|
ec8936b765 |
@@ -136,7 +136,6 @@ public interface Eco {
|
|||||||
*
|
*
|
||||||
* @param plugin The plugin.
|
* @param plugin The plugin.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
|
||||||
void createPAPIIntegration(@NotNull EcoPlugin plugin);
|
void createPAPIIntegration(@NotNull EcoPlugin plugin);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -169,6 +168,7 @@ public interface Eco {
|
|||||||
* @param requiresChangesToSave If the config must be changed in order to save the config.
|
* @param requiresChangesToSave If the config must be changed in order to save the config.
|
||||||
* @return The config implementation.
|
* @return The config implementation.
|
||||||
*/
|
*/
|
||||||
|
@NotNull
|
||||||
LoadableConfig createUpdatableConfig(@NotNull String configName,
|
LoadableConfig createUpdatableConfig(@NotNull String configName,
|
||||||
@NotNull PluginLike plugin,
|
@NotNull PluginLike plugin,
|
||||||
@NotNull String subDirectoryPath,
|
@NotNull String subDirectoryPath,
|
||||||
@@ -189,6 +189,7 @@ public interface Eco {
|
|||||||
* @param requiresChangesToSave If the config must be changed in order to save the config.
|
* @param requiresChangesToSave If the config must be changed in order to save the config.
|
||||||
* @return The config implementation.
|
* @return The config implementation.
|
||||||
*/
|
*/
|
||||||
|
@NotNull
|
||||||
LoadableConfig createLoadableConfig(@NotNull String configName,
|
LoadableConfig createLoadableConfig(@NotNull String configName,
|
||||||
@NotNull PluginLike plugin,
|
@NotNull PluginLike plugin,
|
||||||
@NotNull String subDirectoryPath,
|
@NotNull String subDirectoryPath,
|
||||||
@@ -202,6 +203,7 @@ public interface Eco {
|
|||||||
* @param config The handle.
|
* @param config The handle.
|
||||||
* @return The config implementation.
|
* @return The config implementation.
|
||||||
*/
|
*/
|
||||||
|
@NotNull
|
||||||
Config wrapConfigurationSection(@NotNull ConfigurationSection config);
|
Config wrapConfigurationSection(@NotNull ConfigurationSection config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -211,6 +213,7 @@ public interface Eco {
|
|||||||
* @param type The config type.
|
* @param type The config type.
|
||||||
* @return The config implementation.
|
* @return The config implementation.
|
||||||
*/
|
*/
|
||||||
|
@NotNull
|
||||||
Config createConfig(@NotNull Map<String, Object> values,
|
Config createConfig(@NotNull Map<String, Object> values,
|
||||||
@NotNull ConfigType type);
|
@NotNull ConfigType type);
|
||||||
|
|
||||||
@@ -221,6 +224,7 @@ public interface Eco {
|
|||||||
* @param type The type.
|
* @param type The type.
|
||||||
* @return The config implementation.
|
* @return The config implementation.
|
||||||
*/
|
*/
|
||||||
|
@NotNull
|
||||||
Config createConfig(@NotNull String contents,
|
Config createConfig(@NotNull String contents,
|
||||||
@NotNull ConfigType type);
|
@NotNull ConfigType type);
|
||||||
|
|
||||||
@@ -331,6 +335,7 @@ public interface Eco {
|
|||||||
*
|
*
|
||||||
* @return The keys.
|
* @return The keys.
|
||||||
*/
|
*/
|
||||||
|
@NotNull
|
||||||
Set<PersistentDataKey<?>> getRegisteredPersistentDataKeys();
|
Set<PersistentDataKey<?>> getRegisteredPersistentDataKeys();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -339,6 +344,7 @@ public interface Eco {
|
|||||||
* @param uuid The UUID.
|
* @param uuid The UUID.
|
||||||
* @return The profile.
|
* @return The profile.
|
||||||
*/
|
*/
|
||||||
|
@NotNull
|
||||||
PlayerProfile loadPlayerProfile(@NotNull UUID uuid);
|
PlayerProfile loadPlayerProfile(@NotNull UUID uuid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -346,6 +352,7 @@ public interface Eco {
|
|||||||
*
|
*
|
||||||
* @return The profile.
|
* @return The profile.
|
||||||
*/
|
*/
|
||||||
|
@NotNull
|
||||||
ServerProfile getServerProfile();
|
ServerProfile getServerProfile();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -498,6 +505,11 @@ public interface Eco {
|
|||||||
@Nullable
|
@Nullable
|
||||||
Menu getOpenMenu(@NotNull Player player);
|
Menu getOpenMenu(@NotNull Player player);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sync commands.
|
||||||
|
*/
|
||||||
|
void syncCommands();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the instance of eco; the bridge between the api frontend
|
* Get the instance of eco; the bridge between the api frontend
|
||||||
* and the implementation backend.
|
* and the implementation backend.
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package com.willfp.eco.core.command;
|
package com.willfp.eco.core.command;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
import com.willfp.eco.core.EcoPlugin;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -43,8 +45,6 @@ public interface CommandBase {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle command execution.
|
* Handle command execution.
|
||||||
* <p>
|
|
||||||
* Marked as default void with no implementation for backwards compatibility.
|
|
||||||
*
|
*
|
||||||
* @param sender The sender.
|
* @param sender The sender.
|
||||||
* @param args The args.
|
* @param args The args.
|
||||||
@@ -54,20 +54,43 @@ public interface CommandBase {
|
|||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle command execution from players.
|
||||||
|
*
|
||||||
|
* @param sender The sender.
|
||||||
|
* @param args The args.
|
||||||
|
*/
|
||||||
|
default void onExecute(@NotNull Player sender,
|
||||||
|
@NotNull List<String> args) {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle tab completion.
|
* Handle tab completion.
|
||||||
* <p>
|
|
||||||
* Marked as default void with no implementation for backwards compatibility.
|
|
||||||
*
|
*
|
||||||
* @param sender The sender.
|
* @param sender The sender.
|
||||||
* @param args The args.
|
* @param args The args.
|
||||||
* @return The results.
|
* @return The results.
|
||||||
*/
|
*/
|
||||||
|
@NotNull
|
||||||
default List<String> tabComplete(@NotNull CommandSender sender,
|
default List<String> tabComplete(@NotNull CommandSender sender,
|
||||||
@NotNull List<String> args) {
|
@NotNull List<String> args) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle tab completion.
|
||||||
|
*
|
||||||
|
* @param sender The sender.
|
||||||
|
* @param args The args.
|
||||||
|
* @return The results.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default List<String> tabComplete(@NotNull Player sender,
|
||||||
|
@NotNull List<String> args) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the plugin.
|
* Get the plugin.
|
||||||
*
|
*
|
||||||
@@ -83,7 +106,11 @@ public interface CommandBase {
|
|||||||
* @deprecated Use {@link CommandBase#onExecute(CommandSender, List)} instead.
|
* @deprecated Use {@link CommandBase#onExecute(CommandSender, List)} instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated(forRemoval = true)
|
@Deprecated(forRemoval = true)
|
||||||
CommandHandler getHandler();
|
default CommandHandler getHandler() {
|
||||||
|
return (a, b) -> {
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the handler.
|
* Set the handler.
|
||||||
@@ -93,7 +120,9 @@ public interface CommandBase {
|
|||||||
* @deprecated Handlers have been deprecated.
|
* @deprecated Handlers have been deprecated.
|
||||||
*/
|
*/
|
||||||
@Deprecated(forRemoval = true)
|
@Deprecated(forRemoval = true)
|
||||||
void setHandler(@NotNull CommandHandler handler);
|
default void setHandler(@NotNull final CommandHandler handler) {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the tab completer.
|
* Get the tab completer.
|
||||||
@@ -103,7 +132,9 @@ public interface CommandBase {
|
|||||||
* @deprecated Use {@link CommandBase#tabComplete(CommandSender, List)} instead.
|
* @deprecated Use {@link CommandBase#tabComplete(CommandSender, List)} instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated(forRemoval = true)
|
@Deprecated(forRemoval = true)
|
||||||
TabCompleteHandler getTabCompleter();
|
default TabCompleteHandler getTabCompleter() {
|
||||||
|
return (a, b) -> ImmutableList.of();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the tab completer.
|
* Set the tab completer.
|
||||||
@@ -113,5 +144,7 @@ public interface CommandBase {
|
|||||||
* @deprecated Handlers have been deprecated.
|
* @deprecated Handlers have been deprecated.
|
||||||
*/
|
*/
|
||||||
@Deprecated(forRemoval = true)
|
@Deprecated(forRemoval = true)
|
||||||
void setTabCompleter(@NotNull TabCompleteHandler handler);
|
default void setTabCompleter(@NotNull final TabCompleteHandler handler) {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package com.willfp.eco.core.command.impl;
|
||||||
|
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.command.PluginIdentifiableCommand;
|
||||||
|
import org.bukkit.command.TabCompleter;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegates a bukkit command to an eco command (for registrations).
|
||||||
|
*/
|
||||||
|
public final class DelegatedBukkitCommand extends Command implements TabCompleter, PluginIdentifiableCommand {
|
||||||
|
/**
|
||||||
|
* The delegate command.
|
||||||
|
*/
|
||||||
|
private final PluginCommand delegate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new delegated command.
|
||||||
|
*
|
||||||
|
* @param delegate The delegate.
|
||||||
|
*/
|
||||||
|
public DelegatedBukkitCommand(@NotNull final PluginCommand delegate) {
|
||||||
|
super(delegate.getName());
|
||||||
|
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(@NotNull final CommandSender commandSender,
|
||||||
|
@NotNull final String label,
|
||||||
|
@NotNull final String[] args) {
|
||||||
|
return delegate.onCommand(commandSender, this, label, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> onTabComplete(@NotNull final CommandSender commandSender,
|
||||||
|
@NotNull final Command command,
|
||||||
|
@NotNull final String label,
|
||||||
|
@NotNull final String[] args) {
|
||||||
|
return delegate.onTabComplete(commandSender, command, label, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Plugin getPlugin() {
|
||||||
|
return this.delegate.getPlugin();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public String getPermission() {
|
||||||
|
return this.delegate.getPermission();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return this.delegate.getDescription() == null ? "" : this.delegate.getDescription();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public List<String> getAliases() {
|
||||||
|
return this.delegate.getAliases();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -145,6 +145,9 @@ abstract class HandledCommand implements CommandBase {
|
|||||||
this.getHandler().onExecute(sender, Arrays.asList(args));
|
this.getHandler().onExecute(sender, Arrays.asList(args));
|
||||||
} else {
|
} else {
|
||||||
this.onExecute(sender, Arrays.asList(args));
|
this.onExecute(sender, Arrays.asList(args));
|
||||||
|
if (sender instanceof Player player) {
|
||||||
|
this.onExecute(player, Arrays.asList(args));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,7 +205,11 @@ abstract class HandledCommand implements CommandBase {
|
|||||||
if (this.getTabCompleter() != null) {
|
if (this.getTabCompleter() != null) {
|
||||||
return this.getTabCompleter().tabComplete(sender, Arrays.asList(args));
|
return this.getTabCompleter().tabComplete(sender, Arrays.asList(args));
|
||||||
} else {
|
} else {
|
||||||
return this.tabComplete(sender, Arrays.asList(args));
|
List<String> completions = this.tabComplete(sender, Arrays.asList(args));
|
||||||
|
if (sender instanceof Player player) {
|
||||||
|
completions.addAll(this.tabComplete(player, Arrays.asList(args)));
|
||||||
|
}
|
||||||
|
return completions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,18 @@
|
|||||||
package com.willfp.eco.core.command.impl;
|
package com.willfp.eco.core.command.impl;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.Eco;
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
import com.willfp.eco.core.EcoPlugin;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandExecutor;
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandMap;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.TabCompleter;
|
import org.bukkit.command.TabCompleter;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,14 +42,63 @@ public abstract class PluginCommand extends HandledCommand implements CommandExe
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers the command with the server,
|
* Registers the command with the server,
|
||||||
* <p>
|
|
||||||
* Requires the command name to exist, defined in plugin.yml.
|
|
||||||
*/
|
*/
|
||||||
public final void register() {
|
public final void register() {
|
||||||
org.bukkit.command.PluginCommand command = Bukkit.getPluginCommand(this.getName());
|
org.bukkit.command.PluginCommand command = Bukkit.getPluginCommand(this.getName());
|
||||||
assert command != null;
|
if (command != null) {
|
||||||
command.setExecutor(this);
|
command.setExecutor(this);
|
||||||
command.setTabCompleter(this);
|
command.setTabCompleter(this);
|
||||||
|
|
||||||
|
if (this.getDescription() != null) {
|
||||||
|
command.setDescription(this.getDescription());
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> aliases = new ArrayList<>(command.getAliases());
|
||||||
|
aliases.addAll(this.getAliases());
|
||||||
|
command.setAliases(aliases);
|
||||||
|
} else {
|
||||||
|
this.unregister();
|
||||||
|
|
||||||
|
CommandMap commandMap = getCommandMap();
|
||||||
|
|
||||||
|
commandMap.register(this.getPlugin().getName().toLowerCase(), new DelegatedBukkitCommand(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
Eco.get().syncCommands();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregisters the command from the server.
|
||||||
|
*/
|
||||||
|
public final void unregister() {
|
||||||
|
CommandMap commandMap = getCommandMap();
|
||||||
|
|
||||||
|
Command found = commandMap.getCommand(this.getName());
|
||||||
|
if (found != null) {
|
||||||
|
found.unregister(commandMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
Eco.get().syncCommands();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get aliases. Leave null if this command is from plugin.yml.
|
||||||
|
*
|
||||||
|
* @return The aliases.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public List<String> getAliases() {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get description.
|
||||||
|
*
|
||||||
|
* @return The description.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public String getDescription() {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -93,4 +146,19 @@ public abstract class PluginCommand extends HandledCommand implements CommandExe
|
|||||||
|
|
||||||
return this.handleTabCompletion(sender, args);
|
return this.handleTabCompletion(sender, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the internal server CommandMap.
|
||||||
|
*
|
||||||
|
* @return The CommandMap.
|
||||||
|
*/
|
||||||
|
public static CommandMap getCommandMap() {
|
||||||
|
try {
|
||||||
|
Field field = Bukkit.getServer().getClass().getDeclaredField("commandMap");
|
||||||
|
field.setAccessible(true);
|
||||||
|
return (CommandMap) field.get(Bukkit.getServer());
|
||||||
|
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
throw new NullPointerException("Command map wasn't found!");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public abstract class CustomSlot implements Slot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack getItemStack(@NotNull final Player player) {
|
public @NotNull ItemStack getItemStack(@NotNull final Player player) {
|
||||||
if (delegate == null) {
|
if (delegate == null) {
|
||||||
throw new IllegalStateException("Custom Slot was not initialized!");
|
throw new IllegalStateException("Custom Slot was not initialized!");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public abstract class ReactiveSlot implements Slot {
|
|||||||
@NotNull final Menu menu);
|
@NotNull final Menu menu);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack getItemStack(@NotNull final Player player) {
|
public @NotNull ItemStack getItemStack(@NotNull final Player player) {
|
||||||
return new ItemStack(Material.STONE);
|
return new ItemStack(Material.STONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ public interface Slot extends GUIComponent {
|
|||||||
* @param player The player.
|
* @param player The player.
|
||||||
* @return The ItemStack.
|
* @return The ItemStack.
|
||||||
*/
|
*/
|
||||||
|
@NotNull
|
||||||
ItemStack getItemStack(@NotNull Player player);
|
ItemStack getItemStack(@NotNull Player player);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -60,6 +61,7 @@ public interface Slot extends GUIComponent {
|
|||||||
* @param menu The menu.
|
* @param menu The menu.
|
||||||
* @return The slot.
|
* @return The slot.
|
||||||
*/
|
*/
|
||||||
|
@NotNull
|
||||||
default Slot getActionableSlot(@NotNull final Player player,
|
default Slot getActionableSlot(@NotNull final Player player,
|
||||||
@NotNull final Menu menu) {
|
@NotNull final Menu menu) {
|
||||||
return this;
|
return this;
|
||||||
@@ -125,7 +127,9 @@ public interface Slot extends GUIComponent {
|
|||||||
*
|
*
|
||||||
* @param provider The provider.
|
* @param provider The provider.
|
||||||
* @return The builder.
|
* @return The builder.
|
||||||
|
* @deprecated This method was written incorrectly, should have been a Player + Menu function.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since = "6.45.0", forRemoval = true)
|
||||||
static SlotBuilder builder(@NotNull final Function<Player, ItemStack> provider) {
|
static SlotBuilder builder(@NotNull final Function<Player, ItemStack> provider) {
|
||||||
return Eco.get().createSlotBuilder((player, menu) -> provider.apply(player));
|
return Eco.get().createSlotBuilder((player, menu) -> provider.apply(player));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,4 +44,20 @@ public record MathContext(
|
|||||||
Collections.emptyList()
|
Collections.emptyList()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy a MathContext with a player.
|
||||||
|
*
|
||||||
|
* @param context The context.
|
||||||
|
* @param player The player.
|
||||||
|
* @return The new MathContext.
|
||||||
|
*/
|
||||||
|
public static MathContext copyWithPlayer(@NotNull final MathContext context,
|
||||||
|
@Nullable final Player player) {
|
||||||
|
return new MathContext(
|
||||||
|
context.injectableContext(),
|
||||||
|
player,
|
||||||
|
context.additionalPlayers()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,156 @@
|
|||||||
|
package com.willfp.eco.core.price;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
|
import com.willfp.eco.core.math.MathContext;
|
||||||
|
import com.willfp.eco.core.price.impl.PriceFree;
|
||||||
|
import com.willfp.eco.core.serialization.ConfigDeserializer;
|
||||||
|
import com.willfp.eco.util.NumberUtils;
|
||||||
|
import com.willfp.eco.util.StringUtils;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A price that can be shown to a player.
|
||||||
|
*/
|
||||||
|
public final class ConfiguredPrice implements Price {
|
||||||
|
/**
|
||||||
|
* The deserializer.
|
||||||
|
*/
|
||||||
|
private static final ConfigDeserializer<ConfiguredPrice> DESERIALIZER = new Deserializer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free.
|
||||||
|
*/
|
||||||
|
private static final ConfiguredPrice FREE = new ConfiguredPrice(
|
||||||
|
new PriceFree(),
|
||||||
|
"Free"
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The price.
|
||||||
|
*/
|
||||||
|
private final Price price;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The format string.
|
||||||
|
*/
|
||||||
|
private final String formatString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new Configured Price.
|
||||||
|
*
|
||||||
|
* @param price The price.
|
||||||
|
* @param formatString The format string.
|
||||||
|
*/
|
||||||
|
public ConfiguredPrice(@NotNull final Price price,
|
||||||
|
@NotNull final String formatString) {
|
||||||
|
this.price = price;
|
||||||
|
this.formatString = formatString;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canAfford(@NotNull final Player player) {
|
||||||
|
return this.price.canAfford(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pay(@NotNull final Player player) {
|
||||||
|
this.price.pay(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void giveTo(@NotNull final Player player) {
|
||||||
|
this.price.giveTo(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getValue(@NotNull final Player player) {
|
||||||
|
return this.price.getValue(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getMultiplier(@NotNull final Player player) {
|
||||||
|
return this.price.getMultiplier(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMultiplier(@NotNull final Player player,
|
||||||
|
final double multiplier) {
|
||||||
|
this.price.setMultiplier(player, multiplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the price that this delegates to.
|
||||||
|
*
|
||||||
|
* @return The price.
|
||||||
|
*/
|
||||||
|
public Price getPrice() {
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the display string for a player.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @return The display string.
|
||||||
|
*/
|
||||||
|
public String getDisplay(@NotNull final Player player) {
|
||||||
|
return StringUtils.format(
|
||||||
|
formatString.replace("%value%", NumberUtils.format(this.getPrice().getValue(player))),
|
||||||
|
player,
|
||||||
|
StringUtils.FormatOption.WITH_PLACEHOLDERS
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a configured price from config.
|
||||||
|
*
|
||||||
|
* @param config The config.
|
||||||
|
* @return The price, or null if it's invalid.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static ConfiguredPrice create(@NotNull final Config config) {
|
||||||
|
return DESERIALIZER.deserialize(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a configured price from config.
|
||||||
|
*
|
||||||
|
* @param config The config.
|
||||||
|
* @return The price, or free if invalid.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static ConfiguredPrice createOrFree(@NotNull final Config config) {
|
||||||
|
return Objects.requireNonNullElse(create(config), FREE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The deserializer for {@link ConfiguredPrice}.
|
||||||
|
*/
|
||||||
|
private static final class Deserializer implements ConfigDeserializer<ConfiguredPrice> {
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public ConfiguredPrice deserialize(@NotNull final Config config) {
|
||||||
|
if (!(
|
||||||
|
config.has("value")
|
||||||
|
&& config.has("type")
|
||||||
|
&& config.has("display")
|
||||||
|
)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String formatString = config.getString("display");
|
||||||
|
|
||||||
|
Price price = Prices.create(
|
||||||
|
config.getString("value"),
|
||||||
|
config.getString("type"),
|
||||||
|
MathContext.of(config)
|
||||||
|
);
|
||||||
|
|
||||||
|
return new ConfiguredPrice(price, formatString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,11 +24,35 @@ public interface Price {
|
|||||||
*/
|
*/
|
||||||
void pay(@NotNull Player player);
|
void pay(@NotNull Player player);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Give the value of the price to the player.
|
||||||
|
* <p>
|
||||||
|
* You should override this method, it's only marked as default for
|
||||||
|
* backwards compatibility purposes.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
*/
|
||||||
|
default void giveTo(@NotNull Player player) {
|
||||||
|
// Override when needed.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the price is backed by a value, get it here.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @return The value.
|
||||||
|
*/
|
||||||
|
default double getValue(@NotNull final Player player) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the price is backed by a value, get it here.
|
* If the price is backed by a value, get it here.
|
||||||
*
|
*
|
||||||
* @return The value.
|
* @return The value.
|
||||||
|
* @deprecated Use getValue(Player) instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since = "6.45.0", forRemoval = true)
|
||||||
default double getValue() {
|
default double getValue() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -37,8 +61,31 @@ public interface Price {
|
|||||||
* If the price is backed by a value, set it here.
|
* If the price is backed by a value, set it here.
|
||||||
*
|
*
|
||||||
* @param value The value.
|
* @param value The value.
|
||||||
|
* @deprecated Values shouldn't be fixed.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since = "6.45.0", forRemoval = true)
|
||||||
default void setValue(final double value) {
|
default void setValue(final double value) {
|
||||||
// Override when needed.
|
// Override when needed.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the price multiplier for a player.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @return The value.
|
||||||
|
*/
|
||||||
|
default double getMultiplier(@NotNull final Player player) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the price multiplier for a player.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @param multiplier The multiplier.
|
||||||
|
*/
|
||||||
|
default void setMultiplier(@NotNull final Player player,
|
||||||
|
final double multiplier) {
|
||||||
|
// Override when needed.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
package com.willfp.eco.core.price;
|
package com.willfp.eco.core.price;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.math.MathContext;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create prices.
|
* Create prices.
|
||||||
|
* <p>
|
||||||
|
* You must override one of the create methods.
|
||||||
*/
|
*/
|
||||||
public interface PriceFactory {
|
public interface PriceFactory {
|
||||||
/**
|
/**
|
||||||
@@ -23,5 +28,19 @@ public interface PriceFactory {
|
|||||||
* @param value The value.
|
* @param value The value.
|
||||||
* @return The price.
|
* @return The price.
|
||||||
*/
|
*/
|
||||||
@NotNull Price create(double value);
|
default @NotNull Price create(final double value) {
|
||||||
|
return create(MathContext.EMPTY, (ctx) -> value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the price.
|
||||||
|
*
|
||||||
|
* @param baseContext The base MathContext.
|
||||||
|
* @param function The function to use. Should use {@link MathContext#copyWithPlayer(MathContext, Player)} on calls.
|
||||||
|
* @return The price.
|
||||||
|
*/
|
||||||
|
default @NotNull Price create(@NotNull final MathContext baseContext,
|
||||||
|
@NotNull final Function<MathContext, Double> function) {
|
||||||
|
return create(function.apply(baseContext));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to manage prices.
|
* Class to manage prices.
|
||||||
@@ -65,18 +66,18 @@ public final class Prices {
|
|||||||
public static Price create(@NotNull final String expression,
|
public static Price create(@NotNull final String expression,
|
||||||
@Nullable final String priceName,
|
@Nullable final String priceName,
|
||||||
@NotNull final MathContext context) {
|
@NotNull final MathContext context) {
|
||||||
double value = NumberUtils.evaluateExpression(
|
Function<MathContext, Double> function = (ctx) -> NumberUtils.evaluateExpression(
|
||||||
expression,
|
expression,
|
||||||
context
|
ctx
|
||||||
);
|
);
|
||||||
|
|
||||||
if (value <= 0) {
|
if (function.apply(context) <= 0) {
|
||||||
return new PriceFree();
|
return new PriceFree();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default to economy
|
// Default to economy
|
||||||
if (priceName == null) {
|
if (priceName == null) {
|
||||||
return new PriceEconomy(value);
|
return new PriceEconomy(context, function);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find price factory
|
// Find price factory
|
||||||
@@ -90,9 +91,9 @@ public final class Prices {
|
|||||||
return new PriceFree();
|
return new PriceFree();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new PriceItem((int) Math.round(value), item);
|
return new PriceItem(context, function, item);
|
||||||
} else {
|
} else {
|
||||||
return factory.create(value);
|
return factory.create(context, function);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
package com.willfp.eco.core.price.impl;
|
package com.willfp.eco.core.price.impl;
|
||||||
|
|
||||||
import com.willfp.eco.core.integrations.economy.EconomyManager;
|
import com.willfp.eco.core.integrations.economy.EconomyManager;
|
||||||
|
import com.willfp.eco.core.math.MathContext;
|
||||||
import com.willfp.eco.core.price.Price;
|
import com.willfp.eco.core.price.Price;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Economy-based price (for Vault, Treasury, etc.)
|
* Economy-based price (for Vault, Treasury, etc.)
|
||||||
*/
|
*/
|
||||||
@@ -12,7 +18,17 @@ public final class PriceEconomy implements Price {
|
|||||||
/**
|
/**
|
||||||
* The value of the price.
|
* The value of the price.
|
||||||
*/
|
*/
|
||||||
private double value;
|
private final Function<MathContext, Double> function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base math context.
|
||||||
|
*/
|
||||||
|
private final MathContext baseContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The multipliers.
|
||||||
|
*/
|
||||||
|
private final Map<UUID, Double> multipliers = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new economy-based price.
|
* Create a new economy-based price.
|
||||||
@@ -20,26 +36,49 @@ public final class PriceEconomy implements Price {
|
|||||||
* @param value The value.
|
* @param value The value.
|
||||||
*/
|
*/
|
||||||
public PriceEconomy(final double value) {
|
public PriceEconomy(final double value) {
|
||||||
this.value = value;
|
this(MathContext.EMPTY, ctx -> value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new economy-based price.
|
||||||
|
*
|
||||||
|
* @param baseContext The base context.
|
||||||
|
* @param function The function.
|
||||||
|
*/
|
||||||
|
public PriceEconomy(@NotNull final MathContext baseContext,
|
||||||
|
@NotNull final Function<MathContext, Double> function) {
|
||||||
|
this.baseContext = baseContext;
|
||||||
|
this.function = function;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canAfford(@NotNull Player player) {
|
public boolean canAfford(@NotNull final Player player) {
|
||||||
return EconomyManager.getBalance(player) >= value;
|
return EconomyManager.getBalance(player) >= getValue(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pay(@NotNull Player player) {
|
public void pay(@NotNull final Player player) {
|
||||||
EconomyManager.removeMoney(player, value);
|
EconomyManager.removeMoney(player, getValue(player));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getValue() {
|
public void giveTo(@NotNull final Player player) {
|
||||||
return value;
|
EconomyManager.giveMoney(player, getValue(player));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setValue(final double value) {
|
public double getValue(@NotNull final Player player) {
|
||||||
this.value = value;
|
return this.function.apply(MathContext.copyWithPlayer(baseContext, player)) * getMultiplier(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getMultiplier(@NotNull final Player player) {
|
||||||
|
return this.multipliers.getOrDefault(player.getUniqueId(), 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMultiplier(@NotNull final Player player,
|
||||||
|
final double multiplier) {
|
||||||
|
this.multipliers.put(player.getUniqueId(), multiplier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,12 @@ public final class PriceFree implements Price {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canAfford(@NotNull Player player) {
|
public boolean canAfford(@NotNull final Player player) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pay(@NotNull Player player) {
|
public void pay(@NotNull final Player player) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,32 @@
|
|||||||
package com.willfp.eco.core.price.impl;
|
package com.willfp.eco.core.price.impl;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.drops.DropQueue;
|
||||||
import com.willfp.eco.core.items.TestableItem;
|
import com.willfp.eco.core.items.TestableItem;
|
||||||
|
import com.willfp.eco.core.math.MathContext;
|
||||||
import com.willfp.eco.core.price.Price;
|
import com.willfp.eco.core.price.Price;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Item-based price.
|
* Item-based price.
|
||||||
*/
|
*/
|
||||||
public final class PriceItem implements Price {
|
public final class PriceItem implements Price {
|
||||||
|
/**
|
||||||
|
* The base MathContext.
|
||||||
|
*/
|
||||||
|
private final MathContext baseContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The amount of items.
|
* The amount of items.
|
||||||
*/
|
*/
|
||||||
private final int amountToRemove;
|
private final Function<MathContext, Double> function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The item.
|
* The item.
|
||||||
@@ -22,14 +34,33 @@ public final class PriceItem implements Price {
|
|||||||
private final TestableItem item;
|
private final TestableItem item;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new economy-based price.
|
* The multipliers.
|
||||||
|
*/
|
||||||
|
private final Map<UUID, Double> multipliers = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new item-based price.
|
||||||
*
|
*
|
||||||
* @param amount The amount.
|
* @param amount The amount.
|
||||||
* @param item The item.
|
* @param item The item.
|
||||||
*/
|
*/
|
||||||
public PriceItem(final int amount,
|
public PriceItem(final int amount,
|
||||||
@NotNull final TestableItem item) {
|
@NotNull final TestableItem item) {
|
||||||
this.amountToRemove = Math.max(0, amount);
|
this(MathContext.EMPTY, ctx -> (double) amount, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new item-based price.
|
||||||
|
*
|
||||||
|
* @param baseContext The base MathContext.
|
||||||
|
* @param function The function to get the amount of items to remove.
|
||||||
|
* @param item The item.
|
||||||
|
*/
|
||||||
|
public PriceItem(@NotNull final MathContext baseContext,
|
||||||
|
@NotNull final Function<MathContext, Double> function,
|
||||||
|
@NotNull final TestableItem item) {
|
||||||
|
this.baseContext = baseContext;
|
||||||
|
this.function = function;
|
||||||
this.item = item;
|
this.item = item;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,8 +74,9 @@ public final class PriceItem implements Price {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canAfford(@NotNull Player player) {
|
public boolean canAfford(@NotNull final Player player) {
|
||||||
if (amountToRemove == 0) {
|
int toRemove = (int) getValue(player);
|
||||||
|
if (toRemove <= 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,26 +88,27 @@ public final class PriceItem implements Price {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return count >= amountToRemove;
|
return count >= toRemove;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pay(@NotNull Player player) {
|
public void pay(@NotNull final Player player) {
|
||||||
|
int toRemove = (int) getValue(player);
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
for (ItemStack itemStack : player.getInventory().getContents()) {
|
for (ItemStack itemStack : player.getInventory().getContents()) {
|
||||||
if (count >= amountToRemove) {
|
if (count >= toRemove) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.matches(itemStack)) {
|
if (item.matches(itemStack)) {
|
||||||
int itemAmount = itemStack.getAmount();
|
int itemAmount = itemStack.getAmount();
|
||||||
|
|
||||||
if (itemAmount > amountToRemove) {
|
if (itemAmount > toRemove) {
|
||||||
itemStack.setAmount(itemAmount - amountToRemove);
|
itemStack.setAmount(itemAmount - toRemove);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itemAmount <= amountToRemove) {
|
if (itemAmount <= toRemove) {
|
||||||
itemStack.setAmount(0);
|
itemStack.setAmount(0);
|
||||||
itemStack.setType(Material.AIR);
|
itemStack.setType(Material.AIR);
|
||||||
}
|
}
|
||||||
@@ -84,4 +117,33 @@ public final class PriceItem implements Price {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void giveTo(@NotNull final Player player) {
|
||||||
|
ItemStack itemStack = item.getItem().clone();
|
||||||
|
itemStack.setAmount((int) getValue(player));
|
||||||
|
|
||||||
|
new DropQueue(player)
|
||||||
|
.addItem(itemStack)
|
||||||
|
.forceTelekinesis()
|
||||||
|
.push();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getValue(@NotNull final Player player) {
|
||||||
|
return Math.toIntExact(Math.round(
|
||||||
|
this.function.apply(MathContext.copyWithPlayer(baseContext, player)) * getMultiplier(player)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getMultiplier(@NotNull final Player player) {
|
||||||
|
return this.multipliers.getOrDefault(player.getUniqueId(), 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMultiplier(@NotNull final Player player,
|
||||||
|
final double multiplier) {
|
||||||
|
this.multipliers.put(player.getUniqueId(), multiplier);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
@file:JvmName("TestableExtensions")
|
||||||
|
|
||||||
|
package com.willfp.eco.core.lookup
|
||||||
|
|
||||||
|
/** @see Testable.matches */
|
||||||
|
fun <T> T?.matches(test: Testable<T>) =
|
||||||
|
test.matches(this)
|
||||||
@@ -31,9 +31,7 @@ class RenderedInventory(
|
|||||||
val state = mutableMapOf<String, Any?>()
|
val state = mutableMapOf<String, Any?>()
|
||||||
|
|
||||||
fun render() {
|
fun render() {
|
||||||
val previousCaptive = captiveItems.toMap()
|
val newCaptive = mutableMapOf<GUIPosition, ItemStack>()
|
||||||
|
|
||||||
captiveItems.clear()
|
|
||||||
|
|
||||||
for (row in (1..menu.rows)) {
|
for (row in (1..menu.rows)) {
|
||||||
for (column in (1..menu.columns)) {
|
for (column in (1..menu.columns)) {
|
||||||
@@ -48,11 +46,11 @@ class RenderedInventory(
|
|||||||
|
|
||||||
if (slot.isCaptiveFromEmpty) {
|
if (slot.isCaptiveFromEmpty) {
|
||||||
if (!actualItem.isEmpty) {
|
if (!actualItem.isEmpty) {
|
||||||
captiveItems[position] = actualItem
|
newCaptive[position] = actualItem
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (actualItem != renderedItem && !EmptyTestableItem().matches(actualItem)) {
|
if (actualItem != renderedItem && !EmptyTestableItem().matches(actualItem)) {
|
||||||
captiveItems[position] = actualItem
|
newCaptive[position] = actualItem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -61,6 +59,10 @@ class RenderedInventory(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val previousCaptive = captiveItems.toMap()
|
||||||
|
captiveItems.clear()
|
||||||
|
captiveItems.putAll(newCaptive)
|
||||||
|
|
||||||
menu.runOnRender(player)
|
menu.runOnRender(player)
|
||||||
|
|
||||||
// Run second render if captive items changed
|
// Run second render if captive items changed
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package com.willfp.eco.internal.price
|
package com.willfp.eco.internal.price
|
||||||
|
|
||||||
|
import com.willfp.eco.core.math.MathContext
|
||||||
import com.willfp.eco.core.price.Price
|
import com.willfp.eco.core.price.Price
|
||||||
import com.willfp.eco.core.price.PriceFactory
|
import com.willfp.eco.core.price.PriceFactory
|
||||||
import com.willfp.eco.core.price.impl.PriceEconomy
|
import com.willfp.eco.core.price.impl.PriceEconomy
|
||||||
|
import java.util.function.Function
|
||||||
|
|
||||||
object PriceFactoryEconomy : PriceFactory {
|
object PriceFactoryEconomy : PriceFactory {
|
||||||
override fun getNames() = listOf(
|
override fun getNames() = listOf(
|
||||||
@@ -10,5 +12,7 @@ object PriceFactoryEconomy : PriceFactory {
|
|||||||
"$"
|
"$"
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun create(value: Double): Price = PriceEconomy(value)
|
override fun create(baseContext: MathContext, function: Function<MathContext, Double>): Price {
|
||||||
|
return PriceEconomy(baseContext, function)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package com.willfp.eco.internal.price
|
package com.willfp.eco.internal.price
|
||||||
|
|
||||||
|
import com.willfp.eco.core.math.MathContext
|
||||||
import com.willfp.eco.core.price.Price
|
import com.willfp.eco.core.price.Price
|
||||||
import com.willfp.eco.core.price.PriceFactory
|
import com.willfp.eco.core.price.PriceFactory
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
import java.util.UUID
|
||||||
|
import java.util.function.Function
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
object PriceFactoryXP : PriceFactory {
|
object PriceFactoryXP : PriceFactory {
|
||||||
@@ -12,15 +15,36 @@ object PriceFactoryXP : PriceFactory {
|
|||||||
"experience"
|
"experience"
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun create(value: Double): Price = PriceXP(value.roundToInt())
|
override fun create(baseContext: MathContext, function: Function<MathContext, Double>): Price {
|
||||||
|
return PriceXP(baseContext) { function.apply(it).roundToInt() }
|
||||||
|
}
|
||||||
|
|
||||||
private class PriceXP(
|
private class PriceXP(
|
||||||
private val xp: Int
|
private val baseContext: MathContext,
|
||||||
|
private val xp: (MathContext) -> Int
|
||||||
) : Price {
|
) : Price {
|
||||||
override fun canAfford(player: Player) = player.totalExperience >= xp
|
private val multipliers = mutableMapOf<UUID, Double>()
|
||||||
|
|
||||||
|
override fun canAfford(player: Player) = player.totalExperience >= getValue(player)
|
||||||
|
|
||||||
override fun pay(player: Player) {
|
override fun pay(player: Player) {
|
||||||
player.totalExperience -= xp
|
player.totalExperience -= getValue(player).roundToInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun giveTo(player: Player) {
|
||||||
|
player.totalExperience += getValue(player).roundToInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getValue(player: Player): Double {
|
||||||
|
return xp(MathContext.copyWithPlayer(baseContext, player)) * getMultiplier(player)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getMultiplier(player: Player): Double {
|
||||||
|
return multipliers[player.uniqueId] ?: 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setMultiplier(player: Player, multiplier: Double) {
|
||||||
|
multipliers[player.uniqueId] = multiplier.roundToInt().toDouble()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package com.willfp.eco.internal.price
|
package com.willfp.eco.internal.price
|
||||||
|
|
||||||
|
import com.willfp.eco.core.math.MathContext
|
||||||
import com.willfp.eco.core.price.Price
|
import com.willfp.eco.core.price.Price
|
||||||
import com.willfp.eco.core.price.PriceFactory
|
import com.willfp.eco.core.price.PriceFactory
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
import java.util.UUID
|
||||||
|
import java.util.function.Function
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
object PriceFactoryXPLevels : PriceFactory {
|
object PriceFactoryXPLevels : PriceFactory {
|
||||||
@@ -13,15 +16,36 @@ object PriceFactoryXPLevels : PriceFactory {
|
|||||||
"explevels",
|
"explevels",
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun create(value: Double): Price = PriceXPLevel(value.roundToInt())
|
override fun create(baseContext: MathContext, function: Function<MathContext, Double>): Price {
|
||||||
|
return PriceXPLevel(baseContext) { function.apply(it).roundToInt() }
|
||||||
|
}
|
||||||
|
|
||||||
private class PriceXPLevel(
|
private class PriceXPLevel(
|
||||||
private val levels: Int
|
private val baseContext: MathContext,
|
||||||
|
private val level: (MathContext) -> Int
|
||||||
) : Price {
|
) : Price {
|
||||||
override fun canAfford(player: Player) = player.level >= levels
|
private val multipliers = mutableMapOf<UUID, Double>()
|
||||||
|
|
||||||
|
override fun canAfford(player: Player) = player.level >= getValue(player)
|
||||||
|
|
||||||
override fun pay(player: Player) {
|
override fun pay(player: Player) {
|
||||||
player.level -= levels
|
player.level -= getValue(player).roundToInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun giveTo(player: Player) {
|
||||||
|
player.level += getValue(player).roundToInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getValue(player: Player): Double {
|
||||||
|
return level(MathContext.copyWithPlayer(baseContext, player)) * getMultiplier(player)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getMultiplier(player: Player): Double {
|
||||||
|
return multipliers[player.uniqueId] ?: 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setMultiplier(player: Player, multiplier: Double) {
|
||||||
|
multipliers[player.uniqueId] = multiplier.roundToInt().toDouble()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,23 @@
|
|||||||
package com.willfp.eco.internal.spigot.proxy.common.ai.entity
|
package com.willfp.eco.internal.spigot.proxy.common.ai.entity
|
||||||
|
|
||||||
import com.willfp.eco.core.entities.ai.entity.EntityGoalLeapAtTarget
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalIllusionerBlindnessSpell
|
||||||
import com.willfp.eco.internal.spigot.proxy.common.ai.EntityGoalFactory
|
import com.willfp.eco.internal.spigot.proxy.common.ai.EntityGoalFactory
|
||||||
import com.willfp.eco.internal.spigot.proxy.common.ai.opengoals.IllusionerBlindnessSpellGoal
|
|
||||||
import net.minecraft.world.entity.PathfinderMob
|
import net.minecraft.world.entity.PathfinderMob
|
||||||
import net.minecraft.world.entity.ai.goal.Goal
|
import net.minecraft.world.entity.ai.goal.Goal
|
||||||
import net.minecraft.world.entity.monster.Illusioner
|
import net.minecraft.world.entity.monster.Illusioner
|
||||||
|
|
||||||
object IllusionerBlindnessSpellGoalFactory : EntityGoalFactory<EntityGoalLeapAtTarget> {
|
object IllusionerBlindnessSpellGoalFactory : EntityGoalFactory<EntityGoalIllusionerBlindnessSpell> {
|
||||||
override fun create(apiGoal: EntityGoalLeapAtTarget, entity: PathfinderMob): Goal? {
|
override fun create(apiGoal: EntityGoalIllusionerBlindnessSpell, entity: PathfinderMob): Goal? {
|
||||||
if (entity !is Illusioner) return null
|
if (entity !is Illusioner) return null
|
||||||
|
|
||||||
return IllusionerBlindnessSpellGoal(
|
// Have to use reflection for it to work
|
||||||
entity
|
return Illusioner::class.java.declaredClasses[1]
|
||||||
)
|
.getDeclaredConstructor(Illusioner::class.java)
|
||||||
|
.apply { isAccessible = true }
|
||||||
|
.newInstance(entity) as Goal
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isGoalOfType(goal: Goal) = goal is IllusionerBlindnessSpellGoal
|
override fun isGoalOfType(goal: Goal): Boolean {
|
||||||
|| goal::class.java.name.contains("IllusionerBlindnessSpellGoal")
|
return Illusioner::class.java.declaredClasses[1].isInstance(goal)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,23 @@
|
|||||||
package com.willfp.eco.internal.spigot.proxy.common.ai.entity
|
package com.willfp.eco.internal.spigot.proxy.common.ai.entity
|
||||||
|
|
||||||
import com.willfp.eco.core.entities.ai.entity.EntityGoalLeapAtTarget
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalIllusionerMirrorSpell
|
||||||
import com.willfp.eco.internal.spigot.proxy.common.ai.EntityGoalFactory
|
import com.willfp.eco.internal.spigot.proxy.common.ai.EntityGoalFactory
|
||||||
import com.willfp.eco.internal.spigot.proxy.common.ai.opengoals.IllusionerMirrorSpellGoal
|
|
||||||
import net.minecraft.world.entity.PathfinderMob
|
import net.minecraft.world.entity.PathfinderMob
|
||||||
import net.minecraft.world.entity.ai.goal.Goal
|
import net.minecraft.world.entity.ai.goal.Goal
|
||||||
import net.minecraft.world.entity.monster.Illusioner
|
import net.minecraft.world.entity.monster.Illusioner
|
||||||
|
|
||||||
object IllusionerMirrorSpellGoalFactory : EntityGoalFactory<EntityGoalLeapAtTarget> {
|
object IllusionerMirrorSpellGoalFactory : EntityGoalFactory<EntityGoalIllusionerMirrorSpell> {
|
||||||
override fun create(apiGoal: EntityGoalLeapAtTarget, entity: PathfinderMob): Goal? {
|
override fun create(apiGoal: EntityGoalIllusionerMirrorSpell, entity: PathfinderMob): Goal? {
|
||||||
if (entity !is Illusioner) return null
|
if (entity !is Illusioner) return null
|
||||||
|
|
||||||
return IllusionerMirrorSpellGoal(
|
// Have to use reflection for it to work
|
||||||
entity
|
return Illusioner::class.java.declaredClasses[0]
|
||||||
)
|
.getDeclaredConstructor(Illusioner::class.java)
|
||||||
|
.apply { isAccessible = true }
|
||||||
|
.newInstance(entity) as Goal
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isGoalOfType(goal: Goal) = goal is IllusionerMirrorSpellGoal
|
override fun isGoalOfType(goal: Goal): Boolean {
|
||||||
|| goal::class.java.name.contains("IllusionerMirrorSpellGoal")
|
return Illusioner::class.java.declaredClasses[0].isInstance(goal)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
package com.willfp.eco.internal.spigot.proxy.common.ai.opengoals
|
|
||||||
|
|
||||||
import net.minecraft.sounds.SoundEvent
|
|
||||||
import net.minecraft.sounds.SoundEvents
|
|
||||||
import net.minecraft.world.Difficulty
|
|
||||||
import net.minecraft.world.effect.MobEffectInstance
|
|
||||||
import net.minecraft.world.effect.MobEffects
|
|
||||||
import net.minecraft.world.entity.monster.Illusioner
|
|
||||||
import net.minecraft.world.entity.monster.SpellcasterIllager
|
|
||||||
import org.bukkit.event.entity.EntityPotionEffectEvent
|
|
||||||
|
|
||||||
class IllusionerBlindnessSpellGoal(
|
|
||||||
private val illusioner: Illusioner
|
|
||||||
) : OpenUseSpellGoal(illusioner) {
|
|
||||||
override val castingInterval = 180
|
|
||||||
override val castingTime = 20
|
|
||||||
override val spellPrepareSound: SoundEvent = SoundEvents.ILLUSIONER_PREPARE_BLINDNESS
|
|
||||||
override val spell: SpellcasterIllager.IllagerSpell = SpellcasterIllager.IllagerSpell.BLINDNESS
|
|
||||||
|
|
||||||
private var lastTargetId = 0
|
|
||||||
|
|
||||||
override fun canUse(): Boolean {
|
|
||||||
return if (super.canUse()) {
|
|
||||||
false
|
|
||||||
} else if (illusioner.target == null) {
|
|
||||||
false
|
|
||||||
} else if (illusioner.target!!.id == lastTargetId) {
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
illusioner.level.getCurrentDifficultyAt(illusioner.blockPosition()).isHarderThan(
|
|
||||||
Difficulty.NORMAL.ordinal.toFloat()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun start() {
|
|
||||||
super.start()
|
|
||||||
if (illusioner.target != null) {
|
|
||||||
lastTargetId = illusioner.target!!.id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun performSpellCasting() {
|
|
||||||
illusioner.target?.addEffect(
|
|
||||||
MobEffectInstance(MobEffects.BLINDNESS, 400),
|
|
||||||
illusioner,
|
|
||||||
EntityPotionEffectEvent.Cause.ATTACK
|
|
||||||
) // CraftBukkit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
package com.willfp.eco.internal.spigot.proxy.common.ai.opengoals
|
|
||||||
|
|
||||||
import net.minecraft.sounds.SoundEvent
|
|
||||||
import net.minecraft.sounds.SoundEvents
|
|
||||||
import net.minecraft.world.effect.MobEffectInstance
|
|
||||||
import net.minecraft.world.effect.MobEffects
|
|
||||||
import net.minecraft.world.entity.monster.Illusioner
|
|
||||||
import net.minecraft.world.entity.monster.SpellcasterIllager
|
|
||||||
import org.bukkit.event.entity.EntityPotionEffectEvent
|
|
||||||
|
|
||||||
class IllusionerMirrorSpellGoal(
|
|
||||||
private val illusioner: Illusioner
|
|
||||||
) : OpenUseSpellGoal(illusioner) {
|
|
||||||
override val castingInterval = 340
|
|
||||||
override val castingTime = 20
|
|
||||||
override val spellPrepareSound: SoundEvent = SoundEvents.ILLUSIONER_PREPARE_MIRROR
|
|
||||||
override val spell: SpellcasterIllager.IllagerSpell = SpellcasterIllager.IllagerSpell.DISAPPEAR
|
|
||||||
|
|
||||||
override fun canUse(): Boolean {
|
|
||||||
return if (!super.canUse()) false else !illusioner.hasEffect(MobEffects.INVISIBILITY)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun performSpellCasting() {
|
|
||||||
illusioner.addEffect(
|
|
||||||
MobEffectInstance(MobEffects.INVISIBILITY, 1200),
|
|
||||||
EntityPotionEffectEvent.Cause.ILLUSION
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
package com.willfp.eco.internal.spigot.proxy.common.ai.opengoals
|
|
||||||
|
|
||||||
import net.minecraft.sounds.SoundEvent
|
|
||||||
import net.minecraft.world.entity.EntityType
|
|
||||||
import net.minecraft.world.entity.LivingEntity
|
|
||||||
import net.minecraft.world.entity.ai.goal.Goal
|
|
||||||
import net.minecraft.world.entity.monster.SpellcasterIllager
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
class DelegatedSpellcaster(private val handle: SpellcasterIllager) : SpellcasterIllager(
|
|
||||||
handle.type as EntityType<out SpellcasterIllager>,
|
|
||||||
handle.level
|
|
||||||
) {
|
|
||||||
var openSpellCastingTickCount
|
|
||||||
get() = this.spellCastingTickCount
|
|
||||||
set(value) {
|
|
||||||
this.spellCastingTickCount = value
|
|
||||||
}
|
|
||||||
|
|
||||||
val openCastingSoundEvent = this.castingSoundEvent
|
|
||||||
|
|
||||||
override fun applyRaidBuffs(wave: Int, unused: Boolean) {
|
|
||||||
handle.applyRaidBuffs(wave, unused)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getCelebrateSound(): SoundEvent {
|
|
||||||
return handle.celebrateSound
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getCastingSoundEvent(): SoundEvent {
|
|
||||||
return this.openCastingSoundEvent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
|
|
||||||
abstract class OpenUseSpellGoal(
|
|
||||||
private val handle: SpellcasterIllager
|
|
||||||
) : Goal() {
|
|
||||||
private var attackWarmupDelay = 0
|
|
||||||
private var nextAttackTickCount = 0
|
|
||||||
|
|
||||||
private val openHandle = DelegatedSpellcaster(handle)
|
|
||||||
|
|
||||||
override fun canUse(): Boolean {
|
|
||||||
val entityliving: LivingEntity = handle.target ?: return false
|
|
||||||
return if (entityliving.isAlive) if (handle.isCastingSpell) false else handle.tickCount >= nextAttackTickCount else false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun canContinueToUse(): Boolean {
|
|
||||||
val entityliving: LivingEntity = handle.target ?: return false
|
|
||||||
return entityliving.isAlive && attackWarmupDelay > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun start() {
|
|
||||||
attackWarmupDelay = castWarmupTime
|
|
||||||
openHandle.openSpellCastingTickCount = castingTime
|
|
||||||
nextAttackTickCount = handle.tickCount + castingInterval
|
|
||||||
val soundeffect = spellPrepareSound
|
|
||||||
if (soundeffect != null) {
|
|
||||||
handle.playSound(soundeffect, 1.0f, 1.0f)
|
|
||||||
}
|
|
||||||
handle.setIsCastingSpell(spell)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun tick() {
|
|
||||||
--attackWarmupDelay
|
|
||||||
if (attackWarmupDelay == 0) {
|
|
||||||
performSpellCasting()
|
|
||||||
handle.playSound(openHandle.openCastingSoundEvent, 1.0f, 1.0f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract fun performSpellCasting()
|
|
||||||
protected abstract val castingTime: Int
|
|
||||||
protected abstract val castingInterval: Int
|
|
||||||
protected abstract val spellPrepareSound: SoundEvent?
|
|
||||||
protected abstract val spell: SpellcasterIllager.IllagerSpell?
|
|
||||||
protected open val castWarmupTime: Int = 60
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_17_R1
|
||||||
|
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.SyncCommandsProxy
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.craftbukkit.v1_17_R1.CraftServer
|
||||||
|
|
||||||
|
class SyncCommands : SyncCommandsProxy {
|
||||||
|
override fun syncCommands() {
|
||||||
|
(Bukkit.getServer() as CraftServer).syncCommands()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
|
||||||
|
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.SyncCommandsProxy
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.CraftServer
|
||||||
|
|
||||||
|
class SyncCommands : SyncCommandsProxy {
|
||||||
|
override fun syncCommands() {
|
||||||
|
(Bukkit.getServer() as CraftServer).syncCommands()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R2
|
||||||
|
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.SyncCommandsProxy
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R2.CraftServer
|
||||||
|
|
||||||
|
class SyncCommands : SyncCommandsProxy {
|
||||||
|
override fun syncCommands() {
|
||||||
|
(Bukkit.getServer() as CraftServer).syncCommands()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_19_R1
|
||||||
|
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.SyncCommandsProxy
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R1.CraftServer
|
||||||
|
|
||||||
|
class SyncCommands : SyncCommandsProxy {
|
||||||
|
override fun syncCommands() {
|
||||||
|
(Bukkit.getServer() as CraftServer).syncCommands()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -50,6 +50,7 @@ import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
|
|||||||
import com.willfp.eco.internal.spigot.proxy.MiniMessageTranslatorProxy
|
import com.willfp.eco.internal.spigot.proxy.MiniMessageTranslatorProxy
|
||||||
import com.willfp.eco.internal.spigot.proxy.SNBTConverterProxy
|
import com.willfp.eco.internal.spigot.proxy.SNBTConverterProxy
|
||||||
import com.willfp.eco.internal.spigot.proxy.SkullProxy
|
import com.willfp.eco.internal.spigot.proxy.SkullProxy
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.SyncCommandsProxy
|
||||||
import com.willfp.eco.internal.spigot.proxy.TPSProxy
|
import com.willfp.eco.internal.spigot.proxy.TPSProxy
|
||||||
import org.bukkit.Location
|
import org.bukkit.Location
|
||||||
import org.bukkit.NamespacedKey
|
import org.bukkit.NamespacedKey
|
||||||
@@ -282,4 +283,7 @@ class EcoImpl : EcoSpigotPlugin(), Eco {
|
|||||||
|
|
||||||
override fun getOpenMenu(player: Player) =
|
override fun getOpenMenu(player: Player) =
|
||||||
player.renderedInventory?.menu
|
player.renderedInventory?.menu
|
||||||
|
|
||||||
|
override fun syncCommands() =
|
||||||
|
this.getProxy(SyncCommandsProxy::class.java).syncCommands()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,7 +118,6 @@ import com.willfp.eco.internal.spigot.integrations.shop.ShopDeluxeSellwands
|
|||||||
import com.willfp.eco.internal.spigot.integrations.shop.ShopEconomyShopGUI
|
import com.willfp.eco.internal.spigot.integrations.shop.ShopEconomyShopGUI
|
||||||
import com.willfp.eco.internal.spigot.integrations.shop.ShopShopGuiPlus
|
import com.willfp.eco.internal.spigot.integrations.shop.ShopShopGuiPlus
|
||||||
import com.willfp.eco.internal.spigot.integrations.shop.ShopZShop
|
import com.willfp.eco.internal.spigot.integrations.shop.ShopZShop
|
||||||
import com.willfp.eco.internal.spigot.player.PlayerHealthFixer
|
|
||||||
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
|
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
|
||||||
import com.willfp.eco.internal.spigot.recipes.CraftingRecipeListener
|
import com.willfp.eco.internal.spigot.recipes.CraftingRecipeListener
|
||||||
import com.willfp.eco.internal.spigot.recipes.StackedRecipeListener
|
import com.willfp.eco.internal.spigot.recipes.StackedRecipeListener
|
||||||
@@ -369,7 +368,6 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
|
|||||||
ArmorChangeEventListeners(this),
|
ArmorChangeEventListeners(this),
|
||||||
DataListener(this),
|
DataListener(this),
|
||||||
PlayerBlockListener(this),
|
PlayerBlockListener(this),
|
||||||
PlayerHealthFixer(this),
|
|
||||||
ServerLocking
|
ServerLocking
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
package com.willfp.eco.internal.spigot.player
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin
|
|
||||||
import com.willfp.eco.core.data.keys.PersistentDataKey
|
|
||||||
import com.willfp.eco.core.data.keys.PersistentDataKeyType
|
|
||||||
import com.willfp.eco.core.data.profile
|
|
||||||
import org.bukkit.event.EventHandler
|
|
||||||
import org.bukkit.event.Listener
|
|
||||||
import org.bukkit.event.player.PlayerJoinEvent
|
|
||||||
import org.bukkit.event.player.PlayerQuitEvent
|
|
||||||
|
|
||||||
class PlayerHealthFixer(
|
|
||||||
private val plugin: EcoPlugin
|
|
||||||
): Listener {
|
|
||||||
private val lastHealthKey = PersistentDataKey(
|
|
||||||
plugin.createNamespacedKey("last_health"),
|
|
||||||
PersistentDataKeyType.DOUBLE,
|
|
||||||
0.0
|
|
||||||
)
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
fun onLeave(event: PlayerQuitEvent) {
|
|
||||||
if (!plugin.configYml.getBool("health-fixer")) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val player = event.player
|
|
||||||
player.profile.write(lastHealthKey, player.health)
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
fun onJoin(event: PlayerJoinEvent) {
|
|
||||||
if (!plugin.configYml.getBool("health-fixer")) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val player = event.player
|
|
||||||
plugin.scheduler.runLater(2) {
|
|
||||||
player.health = player.profile.read(lastHealthKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -73,9 +73,6 @@ log-full-extension-errors: false
|
|||||||
# a custom crafting table, though, this won't affect anything, and you should disable the option.
|
# a custom crafting table, though, this won't affect anything, and you should disable the option.
|
||||||
displayed-recipes: true
|
displayed-recipes: true
|
||||||
|
|
||||||
# Save health on leave and set it back on join - works around attribute modifiers.
|
|
||||||
health-fixer: false
|
|
||||||
|
|
||||||
# If eco plugins should not check for updates; only enable this if you know what you're doing
|
# If eco plugins should not check for updates; only enable this if you know what you're doing
|
||||||
# as there can be urgent hotfixes that you are then not notified about. If you're confident
|
# as there can be urgent hotfixes that you are then not notified about. If you're confident
|
||||||
# that you can manage updates on your own, turn this on.
|
# that you can manage updates on your own, turn this on.
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy
|
||||||
|
|
||||||
|
interface SyncCommandsProxy {
|
||||||
|
fun syncCommands()
|
||||||
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
version = 6.44.1
|
version = 6.45.0
|
||||||
plugin-name = eco
|
plugin-name = eco
|
||||||
kotlin.code.style = official
|
kotlin.code.style = official
|
||||||
Reference in New Issue
Block a user