9
0
mirror of https://github.com/Auxilor/Reforges.git synced 2025-12-20 15:39:30 +00:00

Compare commits

..

42 Commits

Author SHA1 Message Date
Auxilor
3743d06cb3 More improvements and fixes 2022-05-22 19:55:19 +01:00
Auxilor
c008a17a27 Various rewrites, refinements, and improvements 2022-05-22 19:21:31 +01:00
Auxilor
9e0c76b840 GUI Improvements 2022-05-22 18:44:27 +01:00
Auxilor
f0891d5cdd Updated to 5.0.0 2022-05-22 18:34:17 +01:00
Auxilor
f884fe24f6 Fixed suppression 2022-05-22 18:34:03 +01:00
Auxilor
cf9cbef409 Removed last traces of java 2022-05-22 18:33:35 +01:00
Auxilor
73abe51241 Rename .java to .kt 2022-05-22 18:33:34 +01:00
Auxilor
d74bd7a281 libreforge-updater 2022-05-22 15:27:50 +01:00
Auxilor
62722972de libreforge-updater 2022-05-21 17:34:43 +01:00
Auxilor
94200719c7 libreforge-updater 2022-05-20 18:37:38 +01:00
Auxilor
44313e9411 libreforge-updater 2022-05-20 18:36:36 +01:00
Auxilor
aab008df45 libreforge-updater 2022-05-20 18:28:12 +01:00
Auxilor
31e063e156 libreforge-updater 2022-05-20 14:21:11 +01:00
Auxilor
c607233958 libreforge-updater 2022-05-19 20:41:30 +01:00
Auxilor
c4552588fe libreforge-updater 2022-05-18 15:32:11 +01:00
Auxilor
7a2a8b5c56 libreforge-updater 2022-05-17 18:53:48 +01:00
Auxilor
eff67cf2e7 libreforge-updater 2022-05-16 21:45:45 +01:00
Auxilor
f81bf62d98 Fixed not met line display 2022-05-16 13:39:36 +01:00
Auxilor
dc7a095eb9 Updated libreforge 2022-05-16 13:11:33 +01:00
Auxilor
0df4338aa3 libreforge-updater 2022-05-15 14:27:17 +01:00
Auxilor
957ed47806 libreforge-updater 2022-05-15 13:57:35 +01:00
Auxilor
6502e6d861 libreforge-updater 2022-05-15 13:36:25 +01:00
Auxilor
39f9b29164 "libreforge-updater" 2022-05-15 13:33:17 +01:00
Auxilor
f098b1e460 Updated libreforge 2022-05-14 21:05:26 +01:00
Auxilor
4f7d0b2d5f Updated libreforge 2022-05-14 12:13:33 +01:00
Auxilor
951a80cb8e Updated libreforge 2022-05-13 16:01:16 +01:00
Auxilor
2fb64eee53 Updated libreforge 2022-05-12 17:22:26 +01:00
Auxilor
cde47a792f Updated libreforge 2022-05-11 15:19:28 +01:00
Auxilor
82193f3678 Updated libreforge 2022-05-08 16:20:21 +01:00
Auxilor
abba90580e Updated libreforge 2022-05-05 21:25:32 +01:00
Auxilor
06787017e5 Updated to 4.66.1 2022-05-04 13:08:29 +01:00
Auxilor
67108a9898 Added no-reforgable-in-gui 2022-05-04 13:08:19 +01:00
Auxilor
a359e9ce59 Updated libreforge 2022-05-03 18:37:02 +01:00
Auxilor
f65ec9ed4d Updated libreforge 2022-05-01 17:41:40 +01:00
Auxilor
65864b19e2 Updated libreforge 2022-04-30 11:38:41 +01:00
Auxilor
6934d29368 Updated to 4.64.3 2022-04-29 15:12:03 +01:00
Auxilor
6e80509416 Removed ItemMeta from display 2022-04-29 15:11:55 +01:00
Auxilor
c53da12086 Updated libreforge 2022-04-29 10:21:25 +01:00
Auxilor
d380e0e7be Updated libreforge 2022-04-27 19:13:53 +01:00
Auxilor
4f47e4ade4 Updated libreforge 2022-04-27 10:39:14 +01:00
Auxilor
77beb2f1f1 Updated libreforge 2022-04-24 19:07:03 +01:00
Auxilor
832c508f76 Bumped version 2022-04-20 18:22:34 +01:00
38 changed files with 968 additions and 1375 deletions

View File

@@ -40,19 +40,16 @@ allprojects {
shadowJar { shadowJar {
relocate('com.willfp.libreforge', 'com.willfp.reforges.libreforge') relocate('com.willfp.libreforge', 'com.willfp.reforges.libreforge')
relocate('org.joml', 'com.willfp.reforges.libreforge.joml')
} }
dependencies { dependencies {
compileOnly 'com.willfp:eco:6.34.0' compileOnly 'com.willfp:eco:6.35.1'
implementation 'com.willfp:libreforge:3.34.1' implementation 'com.willfp:libreforge:3.49.0'
implementation 'org.joml:joml:1.10.4'
compileOnly 'org.jetbrains:annotations:23.0.0' compileOnly 'org.jetbrains:annotations:23.0.0'
compileOnly 'com.github.ben-manes.caffeine:caffeine:3.0.6'
compileOnly 'org.projectlombok:lombok:1.18.20'
annotationProcessor 'org.projectlombok:lombok:1.18.20'
testCompileOnly 'org.projectlombok:lombok:1.18.20'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.20'
compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:1.6.21' compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:1.6.21'
} }
@@ -115,4 +112,4 @@ task buyThePlugins {
println 'Buying gives you access to support and the plugin auto-updater, and it allows me to keep developing plugins.' println 'Buying gives you access to support and the plugin auto-updater, and it allows me to keep developing plugins.'
} }
} }
build.finalizedBy buyThePlugins build.finalizedBy buyThePlugins

View File

@@ -1,2 +1,2 @@
group 'com.willfp' group 'com.willfp'
version rootProject.version version rootProject.version

View File

@@ -1,113 +0,0 @@
package com.willfp.reforges;
import com.willfp.eco.core.command.impl.PluginCommand;
import com.willfp.eco.core.display.DisplayModule;
import com.willfp.eco.core.integrations.IntegrationLoader;
import com.willfp.eco.core.items.Items;
import com.willfp.libreforge.LibReforgePlugin;
import com.willfp.reforges.commands.CommandReforge;
import com.willfp.reforges.commands.CommandReforges;
import com.willfp.reforges.config.ReforgesYml;
import com.willfp.reforges.config.TargetYml;
import com.willfp.reforges.display.ReforgesDisplay;
import com.willfp.reforges.integrations.talismans.TalismansIntegration;
import com.willfp.reforges.reforges.Reforges;
import com.willfp.reforges.reforges.util.ReforgeArgParser;
import com.willfp.reforges.reforges.util.ReforgeEnableListeners;
import com.willfp.reforges.reforges.util.ReforgeLookup;
import com.willfp.reforges.util.AntiPlaceListener;
import com.willfp.reforges.util.DiscoverRecipeListener;
import lombok.Getter;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
public class ReforgesPlugin extends LibReforgePlugin {
/**
* Instance of Reforges.
*/
private static ReforgesPlugin instance;
/**
* target.yml.
*/
@Getter
private final TargetYml targetYml;
/**
* reforges.yml.
*/
@Getter
private final ReforgesYml reforgesYml;
/**
* Internal constructor called by bukkit on plugin load.
*/
public ReforgesPlugin() {
super(1330, 12412, "&3", "");
this.targetYml = new TargetYml(this);
this.reforgesYml = new ReforgesYml(this);
instance = this;
registerHolderProvider(ReforgeLookup::provideReforges);
}
@Override
public void handleEnableAdditional() {
Items.registerArgParser(new ReforgeArgParser());
}
@Override
public void handleReloadAdditional() {
this.getLogger().info(Reforges.values().size() + " Reforges Loaded");
}
@Override
protected List<Listener> loadListeners() {
return Arrays.asList(
new DiscoverRecipeListener(this),
new AntiPlaceListener(),
new ReforgeEnableListeners(this)
);
}
@Override
protected List<PluginCommand> loadPluginCommands() {
return Arrays.asList(
new CommandReforge(this),
new CommandReforges(this)
);
}
@Override
protected @Nullable DisplayModule createDisplayModule() {
return new ReforgesDisplay(this);
}
@NotNull
@Override
public List<IntegrationLoader> loadAdditionalIntegrations() {
return Arrays.asList(
new IntegrationLoader("Talismans", TalismansIntegration::registerProvider)
);
}
@Override
@NotNull
public String getMinimumEcoVersion() {
return "6.33.0";
}
/**
* Get an instance of Reforges.
*
* @return The instance.
*/
public static ReforgesPlugin getInstance() {
return instance;
}
}

View File

@@ -1,17 +0,0 @@
package com.willfp.reforges.config;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.config.BaseConfig;
import com.willfp.eco.core.config.ConfigType;
import org.jetbrains.annotations.NotNull;
public class ReforgesYml extends BaseConfig {
/**
* Instantiate reforges.yml.
*
* @param plugin Instance of reforges.
*/
public ReforgesYml(@NotNull final EcoPlugin plugin) {
super("reforges", plugin, true, ConfigType.YAML);
}
}

View File

@@ -1,55 +0,0 @@
package com.willfp.reforges.config;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.StaticBaseConfig;
import com.willfp.eco.core.items.Items;
import com.willfp.eco.core.items.TestableItem;
import com.willfp.reforges.reforges.meta.ReforgeTarget;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class TargetYml extends StaticBaseConfig {
/**
* Instantiate target.yml.
*
* @param plugin Instance of EcoEnchants.
*/
public TargetYml(@NotNull final EcoPlugin plugin) {
super("target", plugin, ConfigType.YAML);
}
/**
* Get all target names.
*
* @return Set of all names.
*/
public List<String> getTargets() {
return this.getKeys(false);
}
/**
* Get all materials from a target name.
*
* @param target The name of the target.
* @return All materials.
*/
public Set<TestableItem> getTargetItems(@NotNull final String target) {
Set<TestableItem> items = new HashSet<>();
this.getStrings(target + ".items").forEach(s -> items.add(Items.lookup(s.toUpperCase())));
return items;
}
/**
* Get all materials from a target name.
*
* @param target The name of the target.
* @return All materials.
*/
public ReforgeTarget.Slot getSlot(@NotNull final String target) {
return ReforgeTarget.Slot.valueOf(this.getString(target + ".slot").toUpperCase());
}
}

View File

@@ -1,92 +0,0 @@
package com.willfp.reforges.reforges;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableSet;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.config.updating.ConfigUpdater;
import com.willfp.libreforge.chains.EffectChains;
import com.willfp.reforges.ReforgesPlugin;
import lombok.experimental.UtilityClass;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
@UtilityClass
@SuppressWarnings("unused")
public class Reforges {
private static final BiMap<String, Reforge> BY_KEY = HashBiMap.create();
/**
* Get all registered {@link Reforge}s.
*
* @return A list of all {@link Reforge}s.
*/
public static Set<Reforge> values() {
return ImmutableSet.copyOf(BY_KEY.values());
}
/**
* Get {@link String}s for all registered {@link Reforge}s.
*
* @return A list of all {@link Reforge}s.
*/
public static Set<String> keySet() {
return ImmutableSet.copyOf(BY_KEY.keySet());
}
/**
* Get {@link Reforge} matching key.
*
* @param key The key to search for.
* @return The matching {@link Reforge}, or null if not found.
*/
public static Reforge getByKey(@Nullable final String key) {
if (key == null) {
return null;
}
return BY_KEY.get(key);
}
/**
* Update all {@link Reforge}s.
*
* @param plugin Instance of Reforges.
*/
@ConfigUpdater
public static void update(@NotNull final ReforgesPlugin plugin) {
for (Config config : plugin.getReforgesYml().getSubsections("chains")) {
EffectChains.compile(config, "Chains");
}
for (Reforge reforge : values()) {
removeReforge(reforge);
}
for (Config config : plugin.getReforgesYml().getSubsections("reforges")) {
new Reforge(config, plugin);
}
}
/**
* Add new {@link Reforge} to Reforges.
* <p>
* Only for internal use, reforges are automatically added in the constructor.
*
* @param reforge The {@link Reforge} to add.
*/
public static void addNewReforge(@NotNull final Reforge reforge) {
BY_KEY.remove(reforge.getId());
BY_KEY.put(reforge.getId(), reforge);
}
/**
* Remove {@link Reforge} from Reforges.
*
* @param reforge The {@link Reforge} to remove.
*/
public static void removeReforge(@NotNull final Reforge reforge) {
BY_KEY.remove(reforge.getId());
}
}

View File

@@ -1,152 +0,0 @@
package com.willfp.reforges.reforges.meta;
import com.google.common.collect.ImmutableSet;
import com.willfp.eco.core.config.updating.ConfigUpdater;
import com.willfp.eco.core.items.TestableItem;
import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
import com.willfp.reforges.ReforgesPlugin;
import lombok.Getter;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class ReforgeTarget {
/**
* Target containing the materials from all other targets.
*/
public static final ReforgeTarget ALL = new ReforgeTarget("all", Slot.ANY, new HashSet<>());
/**
* All registered targets.
*/
private static final Map<String, ReforgeTarget> REGISTERED = new HashMap<>();
static {
REGISTERED.put("all", ALL);
update(ReforgesPlugin.getInstance());
}
/**
* The name of the target.
*/
@Getter
private final String name;
/**
* The materials of the target.
*/
@Getter
private final Set<TestableItem> items;
/**
* The slot for the target.
*/
@Getter
private final Slot slot;
/**
* Create new target.
*
* @param name The name of the target.
* @param items The items for the target.
*/
public ReforgeTarget(@NotNull final String name,
@NotNull final Slot slot,
@NotNull final Set<TestableItem> items) {
this.name = name;
items.removeIf(item -> item instanceof EmptyTestableItem);
this.items = items;
this.slot = slot;
}
/**
* If an item matches the target.
*
* @param itemStack The ItemStack.
* @return If matches.
*/
public boolean matches(@NotNull final ItemStack itemStack) {
for (TestableItem item : this.items) {
if (item.matches(itemStack)) {
return true;
}
}
return false;
}
/**
* Get ReforgeTarget matching name.
*
* @param name The name to search for.
* @return The matching ReforgeTarget, or null if not found.
*/
public static ReforgeTarget getByName(@NotNull final String name) {
return REGISTERED.get(name);
}
/**
* Get target from item.
*
* @param item The item.
* @return The target.
*/
public static List<ReforgeTarget> getForItem(@NotNull final ItemStack item) {
return REGISTERED.values().stream()
.filter(target -> !target.getName().equalsIgnoreCase("all"))
.filter(target -> target.matches(item))
.collect(Collectors.toList());
}
/**
* Update all targets.
*
* @param plugin Instance of Reforges.
*/
@ConfigUpdater
public static void update(@NotNull final ReforgesPlugin plugin) {
ALL.items.clear();
for (String id : new ArrayList<>(REGISTERED.keySet())) {
if (id.equalsIgnoreCase("all")) {
continue;
}
REGISTERED.remove(id);
}
for (String id : plugin.getTargetYml().getTargets()) {
ReforgeTarget target = new ReforgeTarget(
id,
plugin.getTargetYml().getSlot(id),
plugin.getTargetYml().getTargetItems(id)
);
REGISTERED.put(id, target);
ALL.items.addAll(target.items);
}
}
/**
* Get all targets.
*
* @return A set of all targets.
*/
public static Set<ReforgeTarget> values() {
return ImmutableSet.copyOf(REGISTERED.values());
}
/**
* Reforge slots.
*/
public enum Slot {
HANDS,
ARMOR,
ANY
}
}

View File

@@ -1,141 +0,0 @@
package com.willfp.reforges.reforges.util;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginDependent;
import com.willfp.eco.core.events.ArmorChangeEvent;
import com.willfp.libreforge.LibReforgeUtils;
import com.willfp.libreforge.effects.ConfiguredEffect;
import com.willfp.reforges.reforges.Reforge;
import com.willfp.reforges.reforges.Reforges;
import com.willfp.reforges.reforges.meta.ReforgeTarget;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.jetbrains.annotations.NotNull;
public class ReforgeEnableListeners extends PluginDependent<EcoPlugin> implements Listener {
/**
* Initialize new listeners and link them to a plugin.
*
* @param plugin The plugin to link to.
*/
public ReforgeEnableListeners(@NotNull final EcoPlugin plugin) {
super(plugin);
}
/**
* Called on item pickup.
*
* @param event The event to listen for.
*/
@EventHandler
public void onItemPickup(@NotNull final EntityPickupItemEvent event) {
if (!(event.getEntity() instanceof Player player)) {
return;
}
if (!ReforgeTarget.ALL.matches(event.getItem().getItemStack())) {
return;
}
refreshPlayer(player);
}
/**
* Called on player join.
*
* @param event The event to listen for.
*/
@EventHandler
public void onPlayerJoin(@NotNull final PlayerJoinEvent event) {
refresh();
}
/**
* Called on player leave.
*
* @param event The event to listen for.
*/
@EventHandler
public void onPlayerLeave(@NotNull final PlayerQuitEvent event) {
refresh();
Player player = event.getPlayer();
for (Reforge value : Reforges.values()) {
for (ConfiguredEffect effect : value.getEffects()) {
effect.getEffect().disableForPlayer(player);
}
}
}
/**
* Called on item drop.
*
* @param event The event to listen for.
*/
@EventHandler
public void onInventoryDrop(@NotNull final PlayerDropItemEvent event) {
if (!ReforgeTarget.ALL.matches(event.getItemDrop().getItemStack())) {
return;
}
refreshPlayer(event.getPlayer());
}
/**
* Called on slot change.
*
* @param event The event to listen for.
*/
@EventHandler
public void onChangeSlot(@NotNull final PlayerItemHeldEvent event) {
refreshPlayer(event.getPlayer());
this.getPlugin().getScheduler().run(() -> refreshPlayer(event.getPlayer()));
}
/**
* Called on armor change.
*
* @param event The event to listen for.
*/
@EventHandler
public void onArmorChange(@NotNull final ArmorChangeEvent event) {
refreshPlayer(event.getPlayer());
}
/**
* Called on inventory click.
*
* @param event The event to listen for.
*/
@EventHandler
public void onInventoryClick(@NotNull final InventoryClickEvent event) {
if (!(event.getWhoClicked() instanceof Player)) {
return;
}
refreshPlayer((Player) event.getWhoClicked());
}
/**
* Force refresh all online players.
* <p>
* This is a very expensive method.
*/
public void refresh() {
this.getPlugin().getServer().getOnlinePlayers().forEach(this::refreshPlayer);
}
private void refreshPlayer(@NotNull final Player player) {
ReforgeLookup.clearCache(player);
LibReforgeUtils.updateEffects(player);
}
}

View File

@@ -1,150 +0,0 @@
package com.willfp.reforges.reforges.util;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginDependent;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.gui.slot.Slot;
import com.willfp.eco.core.integrations.economy.EconomyManager;
import com.willfp.reforges.reforges.PriceMultipliers;
import com.willfp.reforges.reforges.Reforge;
import com.willfp.reforges.reforges.meta.ReforgeTarget;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class ReforgeHandler extends PluginDependent<EcoPlugin> {
/**
* Pass an {@link EcoPlugin} in order to interface with it.
*
* @param plugin The plugin to manage.
*/
public ReforgeHandler(@NotNull EcoPlugin plugin) {
super(plugin);
}
public void handleReforgeClick(@NotNull final InventoryClickEvent event,
@NotNull final Slot slot,
@NotNull final Menu menu) {
Player player = (Player) event.getWhoClicked();
ItemStack toReforge = menu.getCaptiveItems(player).isEmpty() ? null : menu.getCaptiveItems(player).get(0);
if (toReforge == null) {
return;
}
Reforge existingReforge = ReforgeUtils.getReforge(toReforge);
List<ReforgeTarget> target = ReforgeTarget.getForItem(toReforge);
Reforge reforge = null;
boolean usedStone = false;
if (menu.getCaptiveItems(player).size() == 2) {
Reforge stone = ReforgeUtils.getReforgeStone(menu.getCaptiveItems(player).get(1));
if (stone != null) {
if (stone.getTargets().stream().anyMatch(reforgeTarget -> reforgeTarget.matches(toReforge))) {
reforge = stone;
usedStone = true;
}
}
}
if (reforge == null) {
List<Reforge> existing = new ArrayList<>();
if (existingReforge != null) {
existing.add(existingReforge);
}
reforge = ReforgeUtils.getRandomReforge(target, existing);
}
if (reforge == null) {
return;
}
double cost = 0;
if (EconomyManager.hasRegistrations()) {
cost = this.getPlugin().getConfigYml().getDouble("reforge.cost");
int reforges = ReforgeUtils.getReforges(toReforge);
cost *= Math.pow(this.getPlugin().getConfigYml().getDouble("reforge.cost-exponent"), reforges);
if (reforge.getRequiresStone() && reforge.getStonePrice() != -1) {
cost = reforge.getStonePrice();
}
cost *= PriceMultipliers.getForPlayer(player).getMultiplier();
if (!EconomyManager.hasAmount(player, cost)) {
player.sendMessage(this.getPlugin().getLangYml().getMessage("insufficient-money"));
if (this.getPlugin().getConfigYml().getBool("gui.insufficient-money-sound.enabled")) {
player.playSound(
player.getLocation(),
Sound.valueOf(this.getPlugin().getConfigYml().getString("gui.insufficient-money-sound.id").toUpperCase()),
1f,
(float) this.getPlugin().getConfigYml().getDouble("gui.insufficient-money-sound.pitch")
);
}
return;
}
}
int xpCost = this.getPlugin().getConfigYml().getInt("reforge.xp-cost");
int reforges = ReforgeUtils.getReforges(toReforge);
xpCost *= Math.pow(this.getPlugin().getConfigYml().getDouble("reforge.cost-exponent"), reforges);
xpCost *= PriceMultipliers.getForPlayer(player).getMultiplier();
if (player.getLevel() < xpCost) {
player.sendMessage(this.getPlugin().getLangYml().getMessage("insufficient-xp"));
if (this.getPlugin().getConfigYml().getBool("gui.insufficient-money-sound.enabled")) {
player.playSound(
player.getLocation(),
Sound.valueOf(this.getPlugin().getConfigYml().getString("gui.insufficient-money-sound.id").toUpperCase()),
1f,
(float) this.getPlugin().getConfigYml().getDouble("gui.insufficient-money-sound.pitch")
);
}
return;
}
if (EconomyManager.hasRegistrations()) {
EconomyManager.removeMoney(player, cost);
}
player.setLevel(player.getLevel() - xpCost);
player.sendMessage(this.getPlugin().getLangYml().getMessage("applied-reforge").replace("%reforge%", reforge.getName()));
ReforgeUtils.incrementReforges(toReforge);
ReforgeUtils.setReforge(toReforge, reforge);
if (usedStone) {
ItemStack stone = menu.getCaptiveItems(player).get(1);
stone.setItemMeta(null);
stone.setAmount(0);
if (this.getPlugin().getConfigYml().getBool("gui.stone-sound.enabled")) {
player.playSound(
player.getLocation(),
Sound.valueOf(this.getPlugin().getConfigYml().getString("gui.stone-sound.id").toUpperCase()),
1f,
(float) this.getPlugin().getConfigYml().getDouble("gui.stone-sound.pitch")
);
}
}
if (this.getPlugin().getConfigYml().getBool("gui.sound.enabled")) {
player.playSound(
player.getLocation(),
Sound.valueOf(this.getPlugin().getConfigYml().getString("gui.sound.id").toUpperCase()),
1f,
(float) this.getPlugin().getConfigYml().getDouble("gui.sound.pitch")
);
}
}
}

View File

@@ -1,150 +0,0 @@
package com.willfp.reforges.reforges.util;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.reforges.ReforgesPlugin;
import com.willfp.reforges.reforges.Reforge;
import com.willfp.reforges.reforges.meta.ReforgeTarget;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.WeakHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;
public class ReforgeLookup {
/**
* All registered providers.
*/
private static final Set<Function<Player, Map<ItemStack, ReforgeTarget.Slot>>> PROVIDERS = new HashSet<>();
/**
* Cached items.
*/
private static final Map<UUID, Map<ItemStack, ReforgeTarget.Slot>> ITEM_CACHE = new WeakHashMap<>();
/**
* Cached reforges.
*/
private static final Map<UUID, Collection<Reforge>> REFORGE_CACHE = new WeakHashMap<>();
/**
* Instance of Reforges.
*/
private static final EcoPlugin PLUGIN = ReforgesPlugin.getInstance();
/**
* Register provider.
*
* @param provider The provider.
*/
public static void registerProvider(@NotNull final Function<Player, Map<ItemStack, ReforgeTarget.Slot>> provider) {
PROVIDERS.add(provider);
}
/**
* Provide ItemStacks.
*
* @param player The player.
* @return The ItemStacks.
*/
public static Map<ItemStack, ReforgeTarget.Slot> provide(@NotNull final Player player) {
if (ITEM_CACHE.containsKey(player.getUniqueId())) {
return new HashMap<>(ITEM_CACHE.get(player.getUniqueId()));
}
Map<ItemStack, ReforgeTarget.Slot> found = new HashMap<>();
for (Function<Player, Map<ItemStack, ReforgeTarget.Slot>> provider : PROVIDERS) {
found.putAll(provider.apply(player));
}
found.keySet().removeIf(Objects::isNull);
ITEM_CACHE.put(player.getUniqueId(), found);
PLUGIN.getScheduler().runLater(() -> ITEM_CACHE.remove(player.getUniqueId()), 40);
return found;
}
/**
* Provide Reforges.
*
* @param player The player.
* @return The Reforges.
*/
public static List<Reforge> provideReforges(@NotNull final Player player) {
if (REFORGE_CACHE.containsKey(player.getUniqueId())) {
return new ArrayList<>(REFORGE_CACHE.get(player.getUniqueId()));
}
List<Reforge> found = new ArrayList<>();
for (Map.Entry<ItemStack, ReforgeTarget.Slot> entry : provide(player).entrySet()) {
ItemStack itemStack = entry.getKey();
ReforgeTarget.Slot slot = entry.getValue();
if (itemStack == null) {
continue;
}
Reforge reforge = ReforgeUtils.getReforge(itemStack);
if (reforge == null) {
continue;
}
if (slot != ReforgeTarget.Slot.ANY) {
if (!reforge.getTargets().stream()
.map(ReforgeTarget::getSlot)
.collect(Collectors.toList())
.contains(slot)) {
continue;
}
}
found.add(reforge);
}
REFORGE_CACHE.put(player.getUniqueId(), found);
PLUGIN.getScheduler().runLater(() -> REFORGE_CACHE.remove(player.getUniqueId()), 40);
return found;
}
/**
* Clear cache.
*
* @param player The player.
*/
public static void clearCache(@NotNull final Player player) {
ITEM_CACHE.remove(player.getUniqueId());
REFORGE_CACHE.remove(player.getUniqueId());
}
static {
registerProvider(player -> Map.of(
player.getInventory().getItemInMainHand(),
ReforgeTarget.Slot.HANDS
));
if (!PLUGIN.getConfigYml().getBool("no-offhand")) {
registerProvider(player -> Map.of(
player.getInventory().getItemInOffHand(),
ReforgeTarget.Slot.HANDS
));
}
registerProvider(player -> {
Map<ItemStack, ReforgeTarget.Slot> items = new HashMap<>();
for (ItemStack stack : player.getInventory().getArmorContents()) {
items.put(stack, ReforgeTarget.Slot.ARMOR);
}
return items;
});
}
}

View File

@@ -1,23 +0,0 @@
package com.willfp.reforges.reforges.util;
public enum ReforgeStatus {
/**
* Allow the reforge.
*/
ALLOW,
/**
* Allow the reforge with a stone.
*/
ALLOW_STONE,
/**
* Invalid item to reforge.
*/
INVALID_ITEM,
/**
* No item at all.
*/
NO_ITEM
}

View File

@@ -1,300 +0,0 @@
package com.willfp.reforges.reforges.util;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.reforges.ReforgesPlugin;
import com.willfp.reforges.reforges.Reforge;
import com.willfp.reforges.reforges.Reforges;
import com.willfp.reforges.reforges.meta.ReforgeTarget;
import lombok.experimental.UtilityClass;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@UtilityClass
public class ReforgeUtils {
/**
* Instance of StatTrackers.
*/
private static final EcoPlugin PLUGIN = ReforgesPlugin.getInstance();
/**
* The key for storing reforges.
*/
private static final NamespacedKey REFORGE_KEY = PLUGIN.getNamespacedKeyFactory().create("reforge");
/**
* The key for storing reforge amounts.
*/
private static final NamespacedKey REFORGE_AMOUNT = PLUGIN.getNamespacedKeyFactory().create("reforge_amount");
/**
* The key for storing reforge stones.
*/
private static final NamespacedKey REFORGE_STONE_KEY = PLUGIN.getNamespacedKeyFactory().create("reforge_stone");
/**
* Get a random reforge for a target.
*
* @param targets The targets.
*/
@Nullable
public static Reforge getRandomReforge(@NotNull final Collection<ReforgeTarget> targets) {
return getRandomReforge(targets, Collections.emptyList());
}
/**
* Get a random reforge for a target.
*
* @param targets The targets.
* @param disallowed The disallowed reforges.
*/
@Nullable
public static Reforge getRandomReforge(@NotNull final Collection<ReforgeTarget> targets,
@NotNull final Collection<Reforge> disallowed) {
List<Reforge> applicable = new ArrayList<>();
for (Reforge reforge : Reforges.values()) {
for (ReforgeTarget target : targets) {
if (reforge.getTargets().contains(target) && !reforge.getRequiresStone()) {
applicable.add(reforge);
}
}
}
Collections.shuffle(applicable);
applicable.removeAll(disallowed);
if (applicable.isEmpty()) {
return null;
}
return applicable.get(0);
}
public static MetadatedReforgeStatus getStatus(@NotNull final List<ItemStack> captive) {
ItemStack toReforge = captive.isEmpty() ? null : captive.get(0);
ItemStack stone = captive.size() == 2 ? captive.get(1) : null;
ReforgeStatus status = null;
List<ReforgeTarget> target = new ArrayList<>();
if (toReforge == null || toReforge.getType() == Material.AIR) {
status = ReforgeStatus.NO_ITEM;
} else {
target.addAll(ReforgeTarget.getForItem(toReforge));
if (target.isEmpty()) {
status = ReforgeStatus.INVALID_ITEM;
}
}
if (!target.isEmpty()) {
status = ReforgeStatus.ALLOW;
}
double cost = 0;
if (status == ReforgeStatus.ALLOW) {
Reforge reforgeStone = getReforgeStone(stone);
if (reforgeStone != null && reforgeStone.getTargets().stream()
.anyMatch(reforgeTarget -> reforgeTarget.getItems().stream()
.anyMatch(item -> item.matches(toReforge)))) {
cost = reforgeStone.getStonePrice();
status = ReforgeStatus.ALLOW_STONE;
}
}
return new MetadatedReforgeStatus(status, cost);
}
/**
* Get reforge on an item.
*
* @param item The item to query.
* @return The found reforge, or null.
*/
public static Reforge getReforge(@Nullable final ItemStack item) {
if (item == null) {
return null;
}
ItemMeta meta = item.getItemMeta();
if (meta == null) {
return null;
}
return getReforge(meta);
}
/**
* Get reforge on an item.
*
* @param meta The item to query.
* @return The found reforge, or null.
*/
public static Reforge getReforge(@Nullable final ItemMeta meta) {
if (meta == null) {
return null;
}
PersistentDataContainer container = meta.getPersistentDataContainer();
if (!container.has(REFORGE_KEY, PersistentDataType.STRING)) {
return null;
}
String active = container.get(REFORGE_KEY, PersistentDataType.STRING);
return Reforges.getByKey(active);
}
/**
* Set reforge on an item.
*
* @param item The item.
* @param reforge The reforge.
*/
public static void setReforge(@NotNull final ItemStack item,
@NotNull final Reforge reforge) {
if (item.getItemMeta() == null) {
return;
}
ItemMeta meta = item.getItemMeta();
setReforge(meta, reforge);
item.setItemMeta(meta);
}
/**
* Set reforge on an item.
*
* @param meta The meta.
* @param reforge The reforge.
*/
public static void setReforge(@NotNull final ItemMeta meta,
@NotNull final Reforge reforge) {
PersistentDataContainer container = meta.getPersistentDataContainer();
container.set(REFORGE_KEY, PersistentDataType.STRING, reforge.getId());
}
/**
* Get reforge stone on an item.
*
* @param item The item to query.
* @return The found reforge, or null.
*/
public static Reforge getReforgeStone(@Nullable final ItemStack item) {
if (item == null) {
return null;
}
ItemMeta meta = item.getItemMeta();
if (meta == null) {
return null;
}
return getReforgeStone(meta);
}
/**
* Get reforge stone on an item.
*
* @param meta The item to query.
* @return The found reforge, or null.
*/
public static Reforge getReforgeStone(@Nullable final ItemMeta meta) {
if (meta == null) {
return null;
}
PersistentDataContainer container = meta.getPersistentDataContainer();
if (!container.has(REFORGE_STONE_KEY, PersistentDataType.STRING)) {
return null;
}
String active = container.get(REFORGE_STONE_KEY, PersistentDataType.STRING);
return Reforges.getByKey(active);
}
/**
* Set an item to be a reforge stone.
*
* @param item The item.
* @param reforge The reforge.
*/
public static void setReforgeStone(@NotNull final ItemStack item,
@NotNull final Reforge reforge) {
if (item.getItemMeta() == null) {
return;
}
ItemMeta meta = item.getItemMeta();
PersistentDataContainer container = meta.getPersistentDataContainer();
container.set(REFORGE_STONE_KEY, PersistentDataType.STRING, reforge.getId());
item.setItemMeta(meta);
}
/**
* Get the amount of reforges done to an item.
*
* @param item The item.
*/
public static int getReforges(@NotNull final ItemStack item) {
ItemMeta meta = item.getItemMeta();
if (meta == null) {
return 0;
}
PersistentDataContainer container = meta.getPersistentDataContainer();
if (!container.has(REFORGE_AMOUNT, PersistentDataType.INTEGER)) {
container.set(REFORGE_AMOUNT, PersistentDataType.INTEGER, 0);
item.setItemMeta(meta);
}
Integer amount = container.get(REFORGE_AMOUNT, PersistentDataType.INTEGER);
return amount == null ? 0 : amount;
}
/**
* Get the amount of reforges done to an item.
*
* @param item The item.
*/
public static void incrementReforges(@NotNull final ItemStack item) {
ItemMeta meta = item.getItemMeta();
if (meta == null) {
return;
}
int amount = getReforges(item);
amount++;
PersistentDataContainer container = meta.getPersistentDataContainer();
container.set(REFORGE_AMOUNT, PersistentDataType.INTEGER, amount);
item.setItemMeta(meta);
}
}

View File

@@ -0,0 +1,78 @@
package com.willfp.reforges
import com.willfp.eco.core.command.impl.PluginCommand
import com.willfp.eco.core.display.DisplayModule
import com.willfp.eco.core.integrations.IntegrationLoader
import com.willfp.eco.core.items.Items
import com.willfp.libreforge.LibReforgePlugin
import com.willfp.reforges.commands.CommandReforge
import com.willfp.reforges.commands.CommandReforges
import com.willfp.reforges.config.ReforgesYml
import com.willfp.reforges.config.TargetYml
import com.willfp.reforges.display.ReforgesDisplay
import com.willfp.reforges.integrations.talismans.TalismansIntegration
import com.willfp.reforges.reforges.Reforges
import com.willfp.reforges.reforges.util.ReforgeArgParser
import com.willfp.reforges.util.ReforgeEnableListeners
import com.willfp.reforges.util.ReforgeLookup
import com.willfp.reforges.util.AntiPlaceListener
import com.willfp.reforges.util.DiscoverRecipeListener
import org.bukkit.event.Listener
class ReforgesPlugin : LibReforgePlugin() {
val targetYml: TargetYml =
TargetYml(this)
val reforgesYml: ReforgesYml =
ReforgesYml(this)
init {
instance = this
}
override fun handleEnableAdditional() {
Items.registerArgParser(ReforgeArgParser())
registerHolderProvider { ReforgeLookup.provideReforges(it) }
}
override fun handleReloadAdditional() {
logger.info(Reforges.values().size.toString() + " Reforges Loaded")
}
override fun loadListeners(): List<Listener> {
return listOf(
DiscoverRecipeListener(this),
AntiPlaceListener(),
ReforgeEnableListeners(this)
)
}
override fun loadPluginCommands(): List<PluginCommand> {
return listOf(
CommandReforge(this),
CommandReforges(this)
)
}
override fun createDisplayModule(): DisplayModule {
return ReforgesDisplay(this)
}
override fun loadAdditionalIntegrations(): List<IntegrationLoader> {
return listOf(
IntegrationLoader("Talismans") { TalismansIntegration.registerProvider() }
)
}
override fun getMinimumEcoVersion(): String {
return "6.35.1"
}
companion object {
/**
* Instance of Reforges.
*/
@JvmStatic
lateinit var instance: ReforgesPlugin
private set
}
}

View File

@@ -3,7 +3,7 @@ package com.willfp.reforges.commands
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.command.impl.Subcommand import com.willfp.eco.core.command.impl.Subcommand
import com.willfp.reforges.reforges.Reforges import com.willfp.reforges.reforges.Reforges
import com.willfp.reforges.reforges.util.ReforgeUtils import com.willfp.reforges.util.reforge
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
import org.bukkit.entity.Player import org.bukkit.entity.Player
@@ -27,7 +27,7 @@ class CommandApply(
if (sender is Player) { if (sender is Player) {
val item = sender.inventory.itemInMainHand val item = sender.inventory.itemInMainHand
ReforgeUtils.setReforge(item, reforge) item.reforge = reforge
sender.sendMessage( sender.sendMessage(
plugin.langYml.getMessage("applied-reforge") plugin.langYml.getMessage("applied-reforge")
.replace("%reforge%", reforge.name) .replace("%reforge%", reforge.name)
@@ -45,7 +45,7 @@ class CommandApply(
return return
} }
ReforgeUtils.setReforge(player.inventory.itemInMainHand, reforge) player.inventory.itemInMainHand.reforge = reforge
sender.sendMessage( sender.sendMessage(
plugin.langYml.getMessage("applied-reforge") plugin.langYml.getMessage("applied-reforge")
.replace("%reforge%", reforge.name) .replace("%reforge%", reforge.name)

View File

@@ -2,7 +2,7 @@ package com.willfp.reforges.commands
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.command.impl.PluginCommand import com.willfp.eco.core.command.impl.PluginCommand
import com.willfp.reforges.gui.ReforgeGUI.menu import com.willfp.reforges.gui.ReforgeGUI
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.Sound import org.bukkit.Sound
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
@@ -29,7 +29,8 @@ class CommandOpen(
plugin.configYml.getDouble("gui.open-sound.pitch").toFloat() plugin.configYml.getDouble("gui.open-sound.pitch").toFloat()
) )
} }
menu.open(player)
ReforgeGUI.open(player)
} }
override fun tabComplete(sender: CommandSender, args: List<String>): List<String> { override fun tabComplete(sender: CommandSender, args: List<String>): List<String> {

View File

@@ -2,7 +2,7 @@ package com.willfp.reforges.commands
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.command.impl.PluginCommand import com.willfp.eco.core.command.impl.PluginCommand
import com.willfp.reforges.gui.ReforgeGUI.menu import com.willfp.reforges.gui.ReforgeGUI
import org.bukkit.Sound import org.bukkit.Sound
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
import org.bukkit.entity.Player import org.bukkit.entity.Player
@@ -20,6 +20,7 @@ class CommandReforge(
plugin.configYml.getDouble("gui.open-sound.pitch").toFloat() plugin.configYml.getDouble("gui.open-sound.pitch").toFloat()
) )
} }
menu.open(player)
ReforgeGUI.open(player)
} }
} }

View File

@@ -0,0 +1,7 @@
package com.willfp.reforges.config
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.config.BaseConfig
import com.willfp.eco.core.config.ConfigType
class ReforgesYml(plugin: EcoPlugin) : BaseConfig("reforges", plugin, true, ConfigType.YAML)

View File

@@ -0,0 +1,43 @@
package com.willfp.reforges.config
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.config.ConfigType
import com.willfp.eco.core.config.StaticBaseConfig
import com.willfp.eco.core.items.Items
import com.willfp.eco.core.items.TestableItem
import com.willfp.reforges.reforges.ReforgeTarget
import java.util.*
import java.util.function.Consumer
class TargetYml(plugin: EcoPlugin) : StaticBaseConfig("target", plugin, ConfigType.YAML) {
/**
* Get all target names.
*
* @return Set of all names.
*/
val targets: List<String>
get() = getKeys(false)
/**
* Get all materials from a target name.
*
* @param target The name of the target.
* @return All materials.
*/
fun getTargetItems(target: String): Set<TestableItem> {
val items: MutableSet<TestableItem> = HashSet()
this.getStrings("$target.items")
.forEach(Consumer { s: String -> items.add(Items.lookup(s.uppercase(Locale.getDefault()))) })
return items
}
/**
* Get all materials from a target name.
*
* @param target The name of the target.
* @return All materials.
*/
fun getSlot(target: String): ReforgeTarget.Slot {
return ReforgeTarget.Slot.valueOf(this.getString("$target.slot").uppercase(Locale.getDefault()))
}
}

View File

@@ -4,43 +4,35 @@ import com.willfp.eco.core.display.Display
import com.willfp.eco.core.display.DisplayModule import com.willfp.eco.core.display.DisplayModule
import com.willfp.eco.core.display.DisplayPriority import com.willfp.eco.core.display.DisplayPriority
import com.willfp.eco.core.fast.FastItemStack import com.willfp.eco.core.fast.FastItemStack
import com.willfp.eco.core.fast.fast
import com.willfp.eco.util.SkullUtils import com.willfp.eco.util.SkullUtils
import com.willfp.eco.util.StringUtils import com.willfp.eco.util.StringUtils
import com.willfp.eco.util.toJSON
import com.willfp.reforges.ReforgesPlugin import com.willfp.reforges.ReforgesPlugin
import com.willfp.reforges.reforges.meta.ReforgeTarget import com.willfp.reforges.reforges.ReforgeTargets
import com.willfp.reforges.reforges.util.ReforgeUtils import com.willfp.reforges.util.reforge
import net.kyori.adventure.text.TextReplacementConfig import com.willfp.reforges.util.reforgeStone
import net.kyori.adventure.text.format.TextDecoration import org.bukkit.entity.Player
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.SkullMeta import org.bukkit.inventory.meta.SkullMeta
import org.bukkit.persistence.PersistentDataType import org.bukkit.persistence.PersistentDataType
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
class ReforgesDisplay(private val plugin: ReforgesPlugin) : DisplayModule(plugin, DisplayPriority.HIGH) { class ReforgesDisplay(private val plugin: ReforgesPlugin) : DisplayModule(plugin, DisplayPriority.HIGH) {
/** private val tempKey = plugin.namespacedKeyFactory.create("temp")
* Deprecated
*/
@Deprecated("Use PDC components!")
private val replacement = TextReplacementConfig.builder()
.match("§w(.+)§w")
.replacement("")
.build()
private val originalComponentKey = plugin.namespacedKeyFactory.create("real_name")
private val serializer = GsonComponentSerializer.gson()
override fun display( override fun display(
itemStack: ItemStack, itemStack: ItemStack,
player: Player?,
vararg args: Any vararg args: Any
) { ) {
val target = ReforgeTarget.getForItem(itemStack) val targets = ReforgeTargets.getForItem(itemStack)
val meta = itemStack.itemMeta ?: return val fast = itemStack.fast()
val stone = ReforgeUtils.getReforgeStone(meta) val stone = fast.persistentDataContainer.reforgeStone
if (target.isEmpty() && stone == null) { if (targets.isEmpty() && stone == null) {
return return
} }
@@ -48,10 +40,17 @@ class ReforgesDisplay(private val plugin: ReforgesPlugin) : DisplayModule(plugin
val lore = fastItemStack.lore val lore = fastItemStack.lore
val reforge = ReforgeUtils.getReforge(meta) val reforge = fast.persistentDataContainer.reforge
if (reforge == null && stone == null && target != null) { if (reforge == null && stone == null) {
if (plugin.configYml.getBool("reforge.show-reforgable")) { if (plugin.configYml.getBool("reforge.show-reforgable")) {
if (player != null && plugin.configYml.getBool("reforge.no-reforgable-in-gui")) {
val inventory = player.openInventory.topInventory
if (inventory.contents.contains(itemStack) && inventory.holder == null) {
return
}
}
val addLore: MutableList<String> = ArrayList() val addLore: MutableList<String> = ArrayList()
for (string in plugin.configYml.getFormattedStrings("reforge.reforgable-suffix")) { for (string in plugin.configYml.getFormattedStrings("reforge.reforgable-suffix")) {
addLore.add(Display.PREFIX + string) addLore.add(Display.PREFIX + string)
@@ -61,6 +60,7 @@ class ReforgesDisplay(private val plugin: ReforgesPlugin) : DisplayModule(plugin
} }
if (stone != null) { if (stone != null) {
val meta = itemStack.itemMeta
meta.setDisplayName(stone.config.getFormattedString("stone.name")) meta.setDisplayName(stone.config.getFormattedString("stone.name"))
val stoneMeta = stone.stone.itemMeta val stoneMeta = stone.stone.itemMeta
if (stoneMeta is SkullMeta) { if (stoneMeta is SkullMeta) {
@@ -92,18 +92,29 @@ class ReforgesDisplay(private val plugin: ReforgesPlugin) : DisplayModule(plugin
lore.addAll(addLore) lore.addAll(addLore)
} }
if (plugin.configYml.getBool("reforge.display-in-name")) { if (plugin.configYml.getBool("reforge.display-in-name")) {
val displayName = fastItemStack.displayNameComponent.replaceText(replacement) val displayName = fastItemStack.displayNameComponent
val newName = StringUtils.toComponent("${reforge.name} ") if (!fastItemStack.displayName.contains(reforge.name)) {
.decoration(TextDecoration.ITALIC, false).append(displayName) fastItemStack.persistentDataContainer.set(
tempKey,
PersistentDataType.STRING,
displayName.toJSON()
)
fastItemStack.setDisplayName(newName) val newName = reforge.namePrefixComponent.append(displayName)
fastItemStack.persistentDataContainer.set( fastItemStack.setDisplayName(newName)
originalComponentKey, }
PersistentDataType.STRING, }
serializer.serialize(displayName)
)
if (player != null) {
val lines = reforge.getNotMetLines(player).map { Display.PREFIX + it }
if (lines.isNotEmpty()) {
lore.add(Display.PREFIX)
lore.addAll(lines)
}
} }
} }
@@ -111,15 +122,25 @@ class ReforgesDisplay(private val plugin: ReforgesPlugin) : DisplayModule(plugin
} }
override fun revert(itemStack: ItemStack) { override fun revert(itemStack: ItemStack) {
ReforgeTarget.getForItem(itemStack) ?: return itemStack.reforge ?: return
val fis = FastItemStack.wrap(itemStack) val fis = FastItemStack.wrap(itemStack)
if (plugin.configYml.getBool("reforge.display-in-name")) { if (!plugin.configYml.getBool("reforge.display-in-name")) {
val originalName = return
fis.persistentDataContainer.get(originalComponentKey, PersistentDataType.STRING) ?: return }
fis.persistentDataContainer.remove(originalComponentKey)
fis.setDisplayName(serializer.deserialize(originalName).replaceText(replacement)) if (fis.persistentDataContainer.has(tempKey, PersistentDataType.STRING)) {
fis.setDisplayName(
StringUtils.jsonToComponent(
fis.persistentDataContainer.get(
tempKey,
PersistentDataType.STRING
)
)
)
fis.persistentDataContainer.remove(tempKey)
} }
} }
} }

View File

@@ -3,48 +3,82 @@ package com.willfp.reforges.gui
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.config.updating.ConfigUpdater import com.willfp.eco.core.config.updating.ConfigUpdater
import com.willfp.eco.core.drops.DropQueue import com.willfp.eco.core.drops.DropQueue
import com.willfp.eco.core.fast.fast
import com.willfp.eco.core.gui.menu import com.willfp.eco.core.gui.menu
import com.willfp.eco.core.gui.menu.Menu import com.willfp.eco.core.gui.menu.Menu
import com.willfp.eco.core.gui.slot import com.willfp.eco.core.gui.slot
import com.willfp.eco.core.gui.slot.FillerMask import com.willfp.eco.core.gui.slot.FillerMask
import com.willfp.eco.core.gui.slot.MaskItems import com.willfp.eco.core.gui.slot.MaskItems
import com.willfp.eco.core.gui.slot.Slot import com.willfp.eco.core.gui.slot.Slot
import com.willfp.eco.core.integrations.economy.EconomyManager
import com.willfp.eco.core.items.Items import com.willfp.eco.core.items.Items
import com.willfp.eco.core.items.builder.ItemStackBuilder import com.willfp.eco.core.items.builder.ItemStackBuilder
import com.willfp.eco.util.NumberUtils import com.willfp.eco.util.NumberUtils
import com.willfp.reforges.ReforgesPlugin
import com.willfp.reforges.reforges.PriceMultipliers import com.willfp.reforges.reforges.PriceMultipliers
import com.willfp.reforges.reforges.util.ReforgeHandler import com.willfp.reforges.reforges.Reforge
import com.willfp.reforges.reforges.util.ReforgeStatus import com.willfp.reforges.reforges.ReforgeTarget
import com.willfp.reforges.reforges.util.ReforgeUtils import com.willfp.reforges.reforges.ReforgeTargets
import com.willfp.reforges.reforges.util.MetadatedReforgeStatus
import com.willfp.reforges.util.ReforgeStatus
import com.willfp.reforges.util.getRandomReforge
import com.willfp.reforges.util.reforge
import com.willfp.reforges.util.reforgeStone
import com.willfp.reforges.util.timesReforged
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.Sound
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import java.util.*
import kotlin.math.pow import kotlin.math.pow
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
object ReforgeGUI { object ReforgeGUI {
@JvmStatic private lateinit var menu: Menu
lateinit var menu: Menu
init { private fun Menu.getReforgeStatus(player: Player): MetadatedReforgeStatus {
update(ReforgesPlugin.getInstance()) val captive = this.getCaptiveItems(player)
val item = captive.getOrNull(0)
val stone = captive.getOrNull(1)
val targets = mutableListOf<ReforgeTarget>()
var cost = 0.0
val status = if (item == null || item.type == Material.AIR) {
ReforgeStatus.NO_ITEM
} else {
targets.addAll(ReforgeTargets.getForItem(item))
if (targets.isEmpty()) {
ReforgeStatus.INVALID_ITEM
} else {
val reforgeStone = stone.reforgeStone
if (reforgeStone != null && reforgeStone.canBeAppliedTo(item)) {
cost = reforgeStone.stonePrice.toDouble()
ReforgeStatus.ALLOW_STONE
} else {
ReforgeStatus.ALLOW
}
}
}
return MetadatedReforgeStatus(status, cost)
}
@JvmStatic
fun open(player: Player) {
menu.open(player)
} }
@JvmStatic @JvmStatic
@ConfigUpdater @ConfigUpdater
fun update(plugin: EcoPlugin) { fun update(plugin: EcoPlugin) {
val handler = ReforgeHandler(plugin)
val activatorSlot = slot(ItemStack(Material.ANVIL)) { val activatorSlot = slot(ItemStack(Material.ANVIL)) {
setModifier { player, menu, previous -> setUpdater { player, menu, _ ->
val meta = previous.itemMeta ?: return@setModifier val (status, specialCost) = menu.getReforgeStatus(player)
val (status, specialCost) = ReforgeUtils.getStatus(menu.getCaptiveItems(player)) val cost = when {
val cost: Double = when {
status == ReforgeStatus.ALLOW || (status == ReforgeStatus.ALLOW_STONE && specialCost < 0) -> { status == ReforgeStatus.ALLOW || (status == ReforgeStatus.ALLOW_STONE && specialCost < 0) -> {
val amountOfReforges = ReforgeUtils.getReforges(menu.getCaptiveItems(player)[0]) val amountOfReforges = menu.getCaptiveItems(player)[0].timesReforged
plugin.configYml.getDouble("reforge.cost") * plugin.configYml.getDouble("reforge.cost") *
plugin.configYml.getDouble("reforge.cost-exponent").pow(amountOfReforges) * plugin.configYml.getDouble("reforge.cost-exponent").pow(amountOfReforges) *
PriceMultipliers.getForPlayer(player).multiplier PriceMultipliers.getForPlayer(player).multiplier
@@ -58,58 +92,134 @@ object ReforgeGUI {
var xpCost = plugin.configYml.getInt("reforge.xp-cost") var xpCost = plugin.configYml.getInt("reforge.xp-cost")
if (status == ReforgeStatus.ALLOW) { if (status == ReforgeStatus.ALLOW) {
val item = menu.getCaptiveItems(player)[0] val item = menu.getCaptiveItems(player)[0]
val reforges = ReforgeUtils.getReforges(item) val reforges = item.timesReforged
xpCost *= PriceMultipliers.getForPlayer(player).multiplier.toInt() xpCost *= PriceMultipliers.getForPlayer(player).multiplier.toInt()
xpCost *= plugin.configYml.getDouble("reforge.cost-exponent").pow(reforges.toDouble()).toInt() xpCost *= plugin.configYml.getDouble("reforge.cost-exponent").pow(reforges.toDouble()).toInt()
} }
when (status) { val configKey = status.configKey
ReforgeStatus.INVALID_ITEM -> {
previous.type = Material.getMaterial( Items.lookup(plugin.configYml.getString("gui.$configKey.material")).item.apply {
plugin.configYml.getString("gui.invalid-item.material").uppercase() this.fast().displayName = plugin.configYml.getFormattedString("gui.$configKey.name")
)!! this.fast().lore = plugin.configYml.getFormattedStrings("gui.$configKey.lore").map {
meta.setDisplayName(plugin.configYml.getFormattedString("gui.invalid-item.name")) it.replace("%cost%", NumberUtils.format(cost))
meta.lore = plugin.configYml.getFormattedStrings("gui.invalid-item.lore").map { .replace("%xpcost%", NumberUtils.format(xpCost.toDouble()))
it.replace("%cost%", NumberUtils.format(cost)) .replace(
.replace("%xpcost%", NumberUtils.format(xpCost.toDouble())) "%stone%",
} menu.getCaptiveItems(player).getOrNull(1).reforgeStone?.name ?: ""
)
} }
ReforgeStatus.ALLOW -> { }
previous.type = Material.getMaterial( }
plugin.configYml.getString("gui.allow.material").uppercase()
)!! onLeftClick { event, _, menu ->
meta.setDisplayName(plugin.configYml.getFormattedString("gui.allow.name")) val player = event.whoClicked as Player
meta.lore = plugin.configYml.getFormattedStrings("gui.allow.lore").map { val captive = menu.getCaptiveItems(player)
it.replace("%cost%", NumberUtils.format(cost))
.replace("%xpcost%", NumberUtils.format(xpCost.toDouble())) val item = captive.getOrNull(0) ?: return@onLeftClick
} val currentReforge = item.reforge
val targets = ReforgeTargets.getForItem(item)
var usedStone = false
val stoneInMenu = menu.getCaptiveItems(player).getOrNull(1).reforgeStone
val reforge = if (stoneInMenu != null && stoneInMenu.canBeAppliedTo(item)) {
usedStone = true
stoneInMenu
} else {
val disallowed = mutableListOf<Reforge>()
if (currentReforge != null) {
disallowed.add(currentReforge)
} }
ReforgeStatus.ALLOW_STONE -> {
previous.type = Material.getMaterial( targets.getRandomReforge(disallowed = disallowed)
plugin.configYml.getString("gui.allow-stone.material").uppercase() }
)!!
meta.setDisplayName(plugin.configYml.getFormattedString("gui.allow-stone.name")) if (reforge == null) {
meta.lore = plugin.configYml.getFormattedStrings("gui.allow-stone.lore").map { return@onLeftClick
it.replace("%cost%", NumberUtils.format(cost)) }
.replace("%xpcost%", NumberUtils.format(xpCost.toDouble()))
.replace("%stone%", ReforgeUtils.getReforgeStone(menu.getCaptiveItems(player)[1]).name) var cost = 0.0
}
val reforges = item.timesReforged
if (EconomyManager.hasRegistrations()) {
cost = plugin.configYml.getDouble("reforge.cost")
cost *= plugin.configYml.getDouble("reforge.cost-exponent").pow(reforges.toDouble())
if (reforge.requiresStone && reforge.stonePrice != -1) {
cost = reforge.stonePrice.toDouble()
} }
ReforgeStatus.NO_ITEM -> { cost *= PriceMultipliers.getForPlayer(player).multiplier
previous.type = Material.getMaterial( if (!EconomyManager.hasAmount(player, cost)) {
plugin.configYml.getString("gui.no-item.material").uppercase() player.sendMessage(plugin.langYml.getMessage("insufficient-money"))
)!! if (plugin.configYml.getBool("gui.insufficient-money-sound.enabled")) {
meta.setDisplayName(plugin.configYml.getFormattedString("gui.no-item.name")) player.playSound(
meta.lore = plugin.configYml.getFormattedStrings("gui.no-item.lore").map { player.location,
it.replace("%cost%", NumberUtils.format(cost)) Sound.valueOf(
.replace("%xpcost%", NumberUtils.format(xpCost.toDouble())) plugin.configYml.getString("gui.insufficient-money-sound.id")
.uppercase(Locale.getDefault())
),
1f, plugin.configYml.getDouble("gui.insufficient-money-sound.pitch").toFloat()
)
} }
return@onLeftClick
} }
} }
previous.itemMeta = meta var xpCost = plugin.configYml.getInt("reforge.xp-cost")
xpCost *= plugin.configYml.getDouble("reforge.cost-exponent").pow(reforges.toDouble()).toInt()
xpCost *= PriceMultipliers.getForPlayer(player).multiplier.toInt()
if (player.level < xpCost) {
player.sendMessage(plugin.langYml.getMessage("insufficient-xp"))
if (plugin.configYml.getBool("gui.insufficient-money-sound.enabled")) {
player.playSound(
player.location,
Sound.valueOf(
plugin.configYml.getString("gui.insufficient-money-sound.id")
.uppercase(Locale.getDefault())
),
1f, plugin.configYml.getDouble("gui.insufficient-money-sound.pitch").toFloat()
)
}
return@onLeftClick
}
if (EconomyManager.hasRegistrations()) {
EconomyManager.removeMoney(player, cost)
}
player.level = player.level - xpCost
player.sendMessage(plugin.langYml.getMessage("applied-reforge").replace("%reforge%", reforge.name))
item.timesReforged++
item.reforge = reforge
if (usedStone) {
val stone = menu.getCaptiveItems(player)[1]
stone.itemMeta = null
stone.amount = 0
if (plugin.configYml.getBool("gui.stone-sound.enabled")) {
player.playSound(
player.location,
Sound.valueOf(
plugin.configYml.getString("gui.stone-sound.id").uppercase(Locale.getDefault())
),
1f, plugin.configYml.getDouble("gui.stone-sound.pitch").toFloat()
)
}
}
if (plugin.configYml.getBool("gui.sound.enabled")) {
player.playSound(
player.location,
Sound.valueOf(plugin.configYml.getString("gui.sound.id").uppercase(Locale.getDefault())),
1f, plugin.configYml.getDouble("gui.sound.pitch").toFloat()
)
}
} }
onLeftClick(handler::handleReforgeClick)
} }
val maskPattern = plugin.configYml.getStrings("gui.mask.pattern").toTypedArray() val maskPattern = plugin.configYml.getStrings("gui.mask.pattern").toTypedArray()
@@ -118,70 +228,66 @@ object ReforgeGUI {
.mapNotNull { Items.lookup(it) } .mapNotNull { Items.lookup(it) }
.toTypedArray() .toTypedArray()
val allowItem = Items.lookup(plugin.configYml.getString("gui.show-allowed.allow-material")).item
val denyItem = Items.lookup(plugin.configYml.getString("gui.show-allowed.deny-material")).item
val closeItem = Items.lookup(plugin.configYml.getString("gui.close.material")).item
menu = menu(plugin.configYml.getInt("gui.rows")) { menu = menu(plugin.configYml.getInt("gui.rows")) {
setTitle(plugin.langYml.getFormattedString("menu.title")) setTitle(plugin.langYml.getFormattedString("menu.title"))
setMask(FillerMask(MaskItems(*maskItems), *maskPattern)) setMask(FillerMask(MaskItems(*maskItems), *maskPattern))
modfiy { builder ->
val slot = Slot.builder(
ItemStackBuilder(Material.BLACK_STAINED_GLASS_PANE)
.setDisplayName("&r")
.build()
).apply {
setModifier { player, menu, previous ->
val status = ReforgeUtils.getStatus(
menu.getCaptiveItems(player)
).status
if (status == ReforgeStatus.ALLOW || status == ReforgeStatus.ALLOW_STONE) { val slot = slot(
previous.type = allowItem.type ItemStackBuilder(Material.BLACK_STAINED_GLASS_PANE)
previous.itemMeta = allowItem.itemMeta .setDisplayName("&r")
} else { .build()
previous.type = denyItem.type ) {
previous.itemMeta = denyItem.itemMeta setUpdater { player, menu, _ ->
} val status = menu.getReforgeStatus(player).status
}
}.build()
val allowedPattern = plugin.configYml.getStrings("gui.show-allowed.pattern") if (status == ReforgeStatus.ALLOW || status == ReforgeStatus.ALLOW_STONE) {
for (i in 1..allowedPattern.size) { Items.lookup(plugin.configYml.getString("gui.show-allowed.allow-material")).item
val row = allowedPattern[i - 1] } else {
for (j in 1..9) { Items.lookup(plugin.configYml.getString("gui.show-allowed.deny-material")).item
if (row[j - 1] != '0') {
builder.setSlot(i, j, slot)
}
} }
} }
} }
val allowedPattern = plugin.configYml.getStrings("gui.show-allowed.pattern")
for (i in 1..allowedPattern.size) {
val row = allowedPattern[i - 1]
for (j in 1..9) {
if (row[j - 1] != '0') {
setSlot(i, j, slot)
}
}
}
setSlot( setSlot(
plugin.configYml.getInt("gui.item-slot.row"), plugin.configYml.getInt("gui.item-slot.row"),
plugin.configYml.getInt("gui.item-slot.column"), plugin.configYml.getInt("gui.item-slot.column"),
Slot.builder().setCaptive().build() Slot.builder().setCaptive().build()
) )
setSlot( setSlot(
plugin.configYml.getInt("gui.stone-slot.row"), plugin.configYml.getInt("gui.stone-slot.row"),
plugin.configYml.getInt("gui.stone-slot.column"), plugin.configYml.getInt("gui.stone-slot.column"),
Slot.builder().setCaptive().build() Slot.builder().setCaptive().build()
) )
setSlot( setSlot(
plugin.configYml.getInt("gui.activator-slot.row"), plugin.configYml.getInt("gui.activator-slot.row"),
plugin.configYml.getInt("gui.activator-slot.column"), plugin.configYml.getInt("gui.activator-slot.column"),
activatorSlot activatorSlot
) )
setSlot( setSlot(
plugin.configYml.getInt("gui.close.location.row"), plugin.configYml.getInt("gui.close.location.row"),
plugin.configYml.getInt("gui.close.location.column"), plugin.configYml.getInt("gui.close.location.column"),
Slot.builder( slot(
ItemStackBuilder(closeItem) ItemStackBuilder(Items.lookup(plugin.configYml.getString("gui.close.material")))
.setDisplayName(plugin.langYml.getFormattedString("menu.close")) .setDisplayName(plugin.langYml.getFormattedString("menu.close"))
.build() .build()
).onLeftClick { event, _, _ -> ) {
event.whoClicked.closeInventory() onLeftClick { event, _, _ -> event.whoClicked.closeInventory() }
}.build() }
) )
onClose { event, menu -> onClose { event, menu ->
DropQueue(event.player as Player) DropQueue(event.player as Player)
.addItems(menu.getCaptiveItems(event.player as Player)) .addItems(menu.getCaptiveItems(event.player as Player))
@@ -191,4 +297,4 @@ object ReforgeGUI {
} }
} }
} }
} }

View File

@@ -1,8 +1,8 @@
package com.willfp.reforges.integrations.talismans package com.willfp.reforges.integrations.talismans
import com.willfp.eco.core.integrations.Integration import com.willfp.eco.core.integrations.Integration
import com.willfp.reforges.reforges.meta.ReforgeTarget import com.willfp.reforges.reforges.ReforgeTarget
import com.willfp.reforges.reforges.util.ReforgeLookup import com.willfp.reforges.util.ReforgeLookup
import com.willfp.talismans.talismans.util.TalismanChecks import com.willfp.talismans.talismans.util.TalismanChecks
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
@@ -10,7 +10,7 @@ object TalismansIntegration : Integration {
@JvmStatic @JvmStatic
fun registerProvider() { fun registerProvider() {
ReforgeLookup.registerProvider { player -> ReforgeLookup.registerProvider { player ->
val provided = mutableMapOf<ItemStack, ReforgeTarget.Slot>() val provided = mutableMapOf<ItemStack?, ReforgeTarget.Slot?>()
for (itemStack in TalismanChecks.getTalismanItemsOnPlayer(player)) { for (itemStack in TalismanChecks.getTalismanItemsOnPlayer(player)) {
provided[itemStack] = ReforgeTarget.Slot.ANY provided[itemStack] = ReforgeTarget.Slot.ANY
} }

View File

@@ -6,27 +6,30 @@ import com.willfp.eco.core.items.CustomItem
import com.willfp.eco.core.items.Items import com.willfp.eco.core.items.Items
import com.willfp.eco.core.items.builder.ItemStackBuilder import com.willfp.eco.core.items.builder.ItemStackBuilder
import com.willfp.eco.core.recipe.Recipes import com.willfp.eco.core.recipe.Recipes
import com.willfp.eco.util.StringUtils
import com.willfp.libreforge.Holder import com.willfp.libreforge.Holder
import com.willfp.libreforge.conditions.Conditions import com.willfp.libreforge.conditions.Conditions
import com.willfp.libreforge.effects.Effects import com.willfp.libreforge.effects.Effects
import com.willfp.reforges.ReforgesPlugin import com.willfp.reforges.ReforgesPlugin
import com.willfp.reforges.reforges.meta.ReforgeTarget import com.willfp.reforges.util.reforgeStone
import com.willfp.reforges.reforges.util.ReforgeUtils import net.kyori.adventure.text.format.TextDecoration
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import java.util.Objects import java.util.*
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
class Reforge( class Reforge(
internal val config: Config, internal val config: Config,
plugin: ReforgesPlugin plugin: ReforgesPlugin
) : Holder { ) : Holder {
val id = config.getString("id") override val id = config.getString("id")
val name = config.getFormattedString("name") val name = config.getFormattedString("name")
val namePrefixComponent = StringUtils.toComponent("$name ").decoration(TextDecoration.ITALIC, false)
val description: List<String> = config.getFormattedStrings("description") val description: List<String> = config.getFormattedStrings("description")
val targets = config.getStrings("targets").map { ReforgeTarget.getByName(it) }.toSet() val targets = config.getStrings("targets").mapNotNull { ReforgeTargets.getByName(it) }.toSet()
override val effects = config.getSubsections("effects").mapNotNull { override val effects = config.getSubsections("effects").mapNotNull {
Effects.compile(it, "Reforge ID $id") Effects.compile(it, "Reforge ID $id")
@@ -51,14 +54,13 @@ class Reforge(
init { init {
Reforges.addNewReforge(this) Reforges.addNewReforge(this)
ReforgeUtils.setReforgeStone(stone, this) stone.reforgeStone = this
Display.display(stone) Display.display(stone)
if (config.getBool("stone.enabled")) { if (config.getBool("stone.enabled")) {
CustomItem( CustomItem(
plugin.namespacedKeyFactory.create("stone_" + this.id), plugin.namespacedKeyFactory.create("stone_" + this.id),
{ test -> ReforgeUtils.getReforgeStone(test) == this }, { test -> test.reforgeStone == this },
stone stone
).register() ).register()
@@ -73,6 +75,10 @@ class Reforge(
} }
} }
fun canBeAppliedTo(item: ItemStack?): Boolean {
return targets.any { target -> target.items.any { it.matches(item) } }
}
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) { if (this === other) {
return true return true

View File

@@ -0,0 +1,43 @@
package com.willfp.reforges.reforges
import com.willfp.eco.core.items.TestableItem
import com.willfp.eco.core.recipe.parts.EmptyTestableItem
import org.bukkit.inventory.ItemStack
import java.util.*
class ReforgeTarget(
val id: String,
val slot: Slot,
val items: MutableSet<TestableItem>
) {
init {
items.removeIf { it is EmptyTestableItem }
}
fun matches(itemStack: ItemStack): Boolean {
for (item in items) {
if (item.matches(itemStack)) {
return true
}
}
return false
}
override fun equals(other: Any?): Boolean {
if (other !is ReforgeTarget) {
return false
}
return this.id == other.id
}
override fun hashCode(): Int {
return Objects.hash(this.id)
}
enum class Slot {
HANDS,
ARMOR,
ANY
}
}

View File

@@ -0,0 +1,77 @@
package com.willfp.reforges.reforges
import com.google.common.collect.ImmutableSet
import com.willfp.eco.core.config.updating.ConfigUpdater
import com.willfp.reforges.ReforgesPlugin
import org.bukkit.inventory.ItemStack
object ReforgeTargets {
private val registered = mutableMapOf<String, ReforgeTarget>()
val ALL = ReforgeTarget("all", ReforgeTarget.Slot.ANY, HashSet())
init {
registered["all"] = ALL
update(ReforgesPlugin.instance)
}
/**
* Get ReforgeTarget matching name.
*
* @param name The name to search for.
* @return The matching ReforgeTarget, or null if not found.
*/
@JvmStatic
fun getByName(name: String): ReforgeTarget? {
return registered[name]
}
/**
* Get target from item.
*
* @param item The item.
* @return The target.
*/
@JvmStatic
fun getForItem(item: ItemStack): List<ReforgeTarget> {
return registered.values
.filter { !it.id.equals("all", ignoreCase = true) }
.filter { it.matches(item) }
}
/**
* Update all targets.
*
* @param plugin Instance of Reforges.
*/
@ConfigUpdater
@JvmStatic
fun update(plugin: ReforgesPlugin) {
ALL.items.clear()
for (id in ArrayList(registered.keys)) {
if (id.equals("all", ignoreCase = true)) {
continue
}
registered.remove(id)
}
for (id in plugin.targetYml.targets) {
val target = ReforgeTarget(
id,
plugin.targetYml.getSlot(id),
plugin.targetYml.getTargetItems(id).toMutableSet()
)
registered[id] = target
ALL.items.addAll(target.items)
}
}
/**
* Get all targets.
*
* @return A set of all targets.
*/
@JvmStatic
fun values(): Set<ReforgeTarget> {
return ImmutableSet.copyOf(registered.values)
}
}

View File

@@ -0,0 +1,86 @@
package com.willfp.reforges.reforges
import com.google.common.collect.HashBiMap
import com.google.common.collect.ImmutableSet
import com.willfp.eco.core.config.updating.ConfigUpdater
import com.willfp.libreforge.chains.EffectChains
import com.willfp.reforges.ReforgesPlugin
@Suppress("UNUSED")
object Reforges {
private val BY_KEY = HashBiMap.create<String, Reforge>()
/**
* Get all registered [Reforge]s.
*
* @return A list of all [Reforge]s.
*/
@JvmStatic
fun values(): Set<Reforge> {
return ImmutableSet.copyOf(BY_KEY.values)
}
/**
* Get [String]s for all registered [Reforge]s.
*
* @return A list of all [Reforge]s.
*/
@JvmStatic
fun keySet(): Set<String> {
return ImmutableSet.copyOf(BY_KEY.keys)
}
/**
* Get [Reforge] matching key.
*
* @param key The key to search for.
* @return The matching [Reforge], or null if not found.
*/
@JvmStatic
fun getByKey(key: String?): Reforge? {
return if (key == null) {
null
} else BY_KEY[key]
}
/**
* Update all [Reforge]s.
*
* @param plugin Instance of Reforges.
*/
@ConfigUpdater
@JvmStatic
fun update(plugin: ReforgesPlugin) {
for (config in plugin.reforgesYml.getSubsections("chains")) {
EffectChains.compile(config, "Chains")
}
for (reforge in values()) {
removeReforge(reforge)
}
for (config in plugin.reforgesYml.getSubsections("reforges")) {
Reforge(config, plugin)
}
}
/**
* Remove [Reforge] from Reforges.
*
* @param reforge The [Reforge] to remove.
*/
@JvmStatic
fun removeReforge(reforge: Reforge) {
BY_KEY.remove(reforge.id)
}
/**
* Add new [Reforge] to Reforges.
*
* Only for internal use, reforges are automatically added in the constructor.
*
* @param reforge The [Reforge] to add.
*/
internal fun addNewReforge(reforge: Reforge) {
BY_KEY.remove(reforge.id)
BY_KEY[reforge.id] = reforge
}
}

View File

@@ -1,3 +1,5 @@
package com.willfp.reforges.reforges.util package com.willfp.reforges.reforges.util
import com.willfp.reforges.util.ReforgeStatus
data class MetadatedReforgeStatus(val status: ReforgeStatus, val cost: Double) data class MetadatedReforgeStatus(val status: ReforgeStatus, val cost: Double)

View File

@@ -3,6 +3,7 @@ package com.willfp.reforges.reforges.util
import com.willfp.eco.core.items.args.LookupArgParser import com.willfp.eco.core.items.args.LookupArgParser
import com.willfp.reforges.reforges.Reforge import com.willfp.reforges.reforges.Reforge
import com.willfp.reforges.reforges.Reforges import com.willfp.reforges.reforges.Reforges
import com.willfp.reforges.util.reforge
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.ItemMeta import org.bukkit.inventory.meta.ItemMeta
import java.util.function.Predicate import java.util.function.Predicate
@@ -26,16 +27,16 @@ class ReforgeArgParser : LookupArgParser {
reforge ?: return null reforge ?: return null
ReforgeUtils.setReforge(meta, reforge) meta.reforge = reforge
return Predicate { test -> return Predicate { test ->
val testMeta = test.itemMeta ?: return@Predicate false val testMeta = test.itemMeta ?: return@Predicate false
reforge == ReforgeUtils.getReforge(testMeta) reforge == testMeta.reforge
} }
} }
override fun serializeBack(meta: ItemMeta): String? { override fun serializeBack(meta: ItemMeta): String? {
val reforge = ReforgeUtils.getReforge(meta) ?: return null val reforge = meta.reforge ?: return null
return "reforge:${reforge.id}" return "reforge:${reforge.id}"
} }

View File

@@ -1,6 +1,5 @@
package com.willfp.reforges.util package com.willfp.reforges.util
import com.willfp.reforges.reforges.util.ReforgeUtils
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
import org.bukkit.event.Listener import org.bukkit.event.Listener
import org.bukkit.event.block.BlockPlaceEvent import org.bukkit.event.block.BlockPlaceEvent
@@ -8,7 +7,7 @@ import org.bukkit.event.block.BlockPlaceEvent
class AntiPlaceListener : Listener { class AntiPlaceListener : Listener {
@EventHandler @EventHandler
fun onBlockPlace(event: BlockPlaceEvent) { fun onBlockPlace(event: BlockPlaceEvent) {
if (ReforgeUtils.getReforgeStone(event.itemInHand) != null) { if (event.itemInHand.reforgeStone != null) {
event.isCancelled = true event.isCancelled = true
event.setBuild(false) event.setBuild(false)
} }

View File

@@ -2,29 +2,23 @@ package com.willfp.reforges.util
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.Keyed
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
import org.bukkit.event.Listener import org.bukkit.event.Listener
import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.event.player.PlayerJoinEvent
import org.bukkit.inventory.Recipe import org.bukkit.inventory.Recipe
import org.bukkit.inventory.ShapedRecipe
class DiscoverRecipeListener( class DiscoverRecipeListener(private val plugin: EcoPlugin) : Listener {
private val plugin: EcoPlugin
) : Listener {
@EventHandler @EventHandler
fun onJoin(event: PlayerJoinEvent) { fun onJoin(event: PlayerJoinEvent) {
val player = event.player if (!plugin.configYml.getBool("discover-recipes")) {
if (plugin.configYml.getBool("discover-recipes")) { return
Bukkit.getServer().recipeIterator().forEachRemaining { recipe: Recipe ->
if (recipe is ShapedRecipe) {
val key = recipe.key
if (key.namespace == "reforges") {
if (!key.key.contains("displayed")) {
player.discoverRecipe(key)
}
}
}
}
} }
mutableListOf<Recipe>()
.apply { Bukkit.getServer().recipeIterator().forEachRemaining(this::add) }
.filterIsInstance<Keyed>().map { it.key }
.filter { it.namespace == plugin.name.lowercase() }
.filter { !it.key.contains("displayed") }
.forEach { event.player.discoverRecipe(it) }
} }
} }

View File

@@ -0,0 +1,84 @@
package com.willfp.reforges.util
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.events.ArmorChangeEvent
import com.willfp.libreforge.updateEffects
import com.willfp.reforges.reforges.ReforgeTargets
import com.willfp.reforges.reforges.Reforges.values
import com.willfp.reforges.util.ReforgeLookup.clearCache
import org.bukkit.entity.Player
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.entity.EntityPickupItemEvent
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.player.PlayerDropItemEvent
import org.bukkit.event.player.PlayerItemHeldEvent
import org.bukkit.event.player.PlayerJoinEvent
import org.bukkit.event.player.PlayerQuitEvent
@Suppress("UNUSED", "UNUSED_PARAMETER")
class ReforgeEnableListeners(private val plugin: EcoPlugin) : Listener {
@EventHandler
fun onItemPickup(event: EntityPickupItemEvent) {
if (event.entity !is Player) {
return
}
val player = event.entity as Player
if (!ReforgeTargets.ALL.matches(event.item.itemStack)) {
return
}
refreshPlayer(player)
}
@EventHandler
fun onPlayerJoin(event: PlayerJoinEvent) {
refresh()
}
@EventHandler
fun onPlayerLeave(event: PlayerQuitEvent) {
refresh()
val player = event.player
for (value in values()) {
for ((effect) in value.effects) {
effect.disableForPlayer(player)
}
}
}
@EventHandler
fun onInventoryDrop(event: PlayerDropItemEvent) {
if (!ReforgeTargets.ALL.matches(event.itemDrop.itemStack)) {
return
}
refreshPlayer(event.player)
}
@EventHandler
fun onChangeSlot(event: PlayerItemHeldEvent) {
refreshPlayer(event.player)
plugin.scheduler.run { refreshPlayer(event.player) }
}
@EventHandler
fun onArmorChange(event: ArmorChangeEvent) {
refreshPlayer(event.player)
}
@EventHandler
fun onInventoryClick(event: InventoryClickEvent) {
if (event.whoClicked !is Player) {
return
}
refreshPlayer(event.whoClicked as Player)
}
private fun refresh() {
plugin.server.onlinePlayers.forEach { player: Player -> refreshPlayer(player) }
}
private fun refreshPlayer(player: Player) {
clearCache(player)
player.updateEffects()
}
}

View File

@@ -0,0 +1,106 @@
package com.willfp.reforges.util
import com.github.benmanes.caffeine.cache.Caffeine
import com.willfp.reforges.ReforgesPlugin
import com.willfp.reforges.reforges.Reforge
import com.willfp.reforges.reforges.ReforgeTarget
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack
import java.util.concurrent.TimeUnit
typealias SlotProvider = (Player) -> Map<ItemStack?, ReforgeTarget.Slot?>
object ReforgeLookup {
private val plugin = ReforgesPlugin.instance
private val slotProviders = mutableSetOf<(Player) -> Map<ItemStack, ReforgeTarget.Slot>>()
private val itemCache = Caffeine.newBuilder()
.expireAfterWrite(2, TimeUnit.SECONDS)
.build<Player, Map<ItemStack, ReforgeTarget.Slot>>()
private val reforgeCache = Caffeine.newBuilder()
.expireAfterWrite(2, TimeUnit.SECONDS)
.build<Player, Collection<Reforge>>()
@JvmStatic
fun registerProvider(provider: SlotProvider) {
slotProviders.add {
val found = mutableMapOf<ItemStack, ReforgeTarget.Slot>()
for ((item, slot) in provider(it)) {
if (item != null && slot != null) {
found[item] = slot
}
}
found
}
}
private fun provide(player: Player): Map<ItemStack, ReforgeTarget.Slot> {
return itemCache.get(player) {
val found = mutableMapOf<ItemStack, ReforgeTarget.Slot>()
for (provider in slotProviders) {
found.putAll(provider(player))
}
found
}
}
fun provideReforges(player: Player): List<Reforge> {
return reforgeCache.get(player) {
val found = mutableListOf<Reforge>()
for ((itemStack, slot) in provide(player)) {
val reforge = itemStack.reforge ?: continue
if (slot != ReforgeTarget.Slot.ANY) {
if (!reforge.targets.map { it.slot }.contains(slot)) {
continue
}
}
found.add(reforge)
}
found
}.toList()
}
/**
* Clear cache.
*
* @param player The player.
*/
@JvmStatic
fun clearCache(player: Player) {
itemCache.invalidate(player)
reforgeCache.invalidate(player)
}
init {
registerProvider {
mapOf(
Pair(
it.inventory.itemInMainHand,
ReforgeTarget.Slot.HANDS
)
)
}
if (!plugin.configYml.getBool("no-offhand")) {
registerProvider {
mapOf(
Pair(
it.inventory.itemInOffHand,
ReforgeTarget.Slot.HANDS
)
)
}
}
registerProvider {
val items = mutableMapOf<ItemStack?, ReforgeTarget.Slot?>()
for (stack in it.inventory.armorContents) {
items[stack] = ReforgeTarget.Slot.ARMOR
}
items
}
}
}

View File

@@ -0,0 +1,10 @@
package com.willfp.reforges.util
enum class ReforgeStatus(
val configKey: String
) {
ALLOW("allow"),
ALLOW_STONE("allow-stone"),
INVALID_ITEM("invalid-item"),
NO_ITEM("no-item")
}

View File

@@ -0,0 +1,115 @@
package com.willfp.reforges.util
import com.willfp.eco.core.fast.fast
import com.willfp.reforges.ReforgesPlugin
import com.willfp.reforges.reforges.Reforge
import com.willfp.reforges.reforges.ReforgeTarget
import com.willfp.reforges.reforges.Reforges
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.ItemMeta
import org.bukkit.persistence.PersistentDataContainer
import org.bukkit.persistence.PersistentDataType
private val plugin = ReforgesPlugin.instance
private val reforgeKey = plugin.namespacedKeyFactory.create("reforge")
private val reforgeAmountKey = plugin.namespacedKeyFactory.create("reforge_amount")
private val reforgeStoneKey = plugin.namespacedKeyFactory.create("reforge_stone")
var ItemStack?.reforge: Reforge?
get() {
this ?: return null
return this.fast().persistentDataContainer.reforge
}
set(value) {
this ?: return
this.fast().persistentDataContainer.reforge = value
}
var ItemMeta?.reforge: Reforge?
get() {
this ?: return null
return this.persistentDataContainer.reforge
}
set(value) {
this ?: return
this.persistentDataContainer.reforge = value
}
var PersistentDataContainer?.reforge: Reforge?
get() {
this ?: return null
if (!this.has(reforgeKey, PersistentDataType.STRING)) {
return null
}
val active = this.get(reforgeKey, PersistentDataType.STRING)
return Reforges.getByKey(active)
}
set(value) {
this ?: return
if (value == null) {
this.remove(reforgeKey)
} else {
this.set(reforgeKey, PersistentDataType.STRING, value.id)
}
}
var ItemStack?.reforgeStone: Reforge?
get() {
this ?: return null
return this.fast().persistentDataContainer.reforgeStone
}
set(value) {
this ?: return
this.fast().persistentDataContainer.reforgeStone = value
}
var ItemMeta?.reforgeStone: Reforge?
get() {
this ?: return null
return this.persistentDataContainer.reforgeStone
}
set(value) {
this ?: return
this.persistentDataContainer.reforgeStone = value
}
var PersistentDataContainer?.reforgeStone: Reforge?
get() {
this ?: return null
if (!this.has(reforgeStoneKey, PersistentDataType.STRING)) {
return null
}
val active = this.get(reforgeStoneKey, PersistentDataType.STRING)
return Reforges.getByKey(active)
}
set(value) {
this ?: return
if (value == null) {
this.remove(reforgeStoneKey)
} else {
this.set(reforgeStoneKey, PersistentDataType.STRING, value.id)
}
}
var ItemStack.timesReforged: Int
get() = this.fast().persistentDataContainer.get(reforgeAmountKey, PersistentDataType.INTEGER) ?: 0
set(value) = this.fast().persistentDataContainer.set(reforgeAmountKey, PersistentDataType.INTEGER, value)
fun Collection<ReforgeTarget>.getRandomReforge(
disallowed: Collection<Reforge> = emptyList()
): Reforge? {
val applicable = mutableListOf<Reforge>()
for (reforge in Reforges.values()) {
if (reforge.targets.intersect(this.toSet()).isNotEmpty() && !reforge.requiresStone) {
applicable.add(reforge)
}
}
applicable.removeAll(disallowed)
return applicable.randomOrNull()
}

View File

@@ -148,6 +148,8 @@ reforge:
reforgable-suffix: reforgable-suffix:
- "" - ""
- "&8This item can be reforged!" - "&8This item can be reforged!"
no-reforgable-in-gui: true # Not perfect, won't work 100% of the time
# due to how GUIs are handled differently in different plugins, but should help.
display-in-lore: true display-in-lore: true
display-in-name: true display-in-name: true

View File

@@ -0,0 +1,3 @@
resource-id: 1330
bstats-id: 12412
color: "&3"

View File

@@ -15,6 +15,8 @@ softdepend:
- AureliumSkills - AureliumSkills
- PlayerPoints - PlayerPoints
- Jobs - Jobs
- EcoArmor
- TMMobcoins
commands: commands:
reforges: reforges:

View File

@@ -1,2 +1,4 @@
version = 4.62.0 #libreforge-updater
plugin-name = Reforges #Sun May 22 15:27:50 BST 2022
version=5.0.0
plugin-name=Reforges

0
gradlew vendored Normal file → Executable file
View File