Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class ListenerManager implements Loadable {
private ItemRequirementListener lisReq;
private DynamicStatListener lisDynamic;
private ItemUpdaterListener updater;
private ItemAutoUpdateListener autoUpdater;
private VanillaWrapperListener lisQuantum;
private HookListener hookListener;
private GrindstoneListener grindstoneListener;
Expand Down Expand Up @@ -53,6 +54,9 @@ public void setup() {
this.updater = new ItemUpdaterListener(this.plugin);
this.updater.registerListeners();

this.autoUpdater = new ItemAutoUpdateListener(this.plugin);
this.autoUpdater.registerListeners();

this.hookListener = new HookListener(this.plugin);
this.hookListener.registerListeners();

Expand All @@ -76,6 +80,10 @@ public void shutdown() {
this.lisReq.unregisterListeners();
this.lisReq = null;
}
if (this.autoUpdater != null) {
this.autoUpdater.unregisterListeners();
this.autoUpdater = null;
}
if (this.lisQuantum != null) {
this.lisQuantum.unregisterListeners();
this.lisQuantum = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package studio.magemonkey.divinity.manager.listener.object;

import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import studio.magemonkey.codex.manager.IListener;
import studio.magemonkey.divinity.Divinity;
import studio.magemonkey.divinity.modules.LeveledItem;
import studio.magemonkey.divinity.modules.ModuleItem;
import studio.magemonkey.divinity.modules.api.QModuleDrop;
import studio.magemonkey.divinity.stats.items.ItemStats;

import java.util.HashSet;

public class ItemAutoUpdateListener extends IListener<Divinity> {

public ItemAutoUpdateListener(@NotNull Divinity plugin) {
super(plugin);
}

@EventHandler(priority = EventPriority.LOWEST)
public void onItemHeld(PlayerItemHeldEvent event) {
Player player = event.getPlayer();
ItemStack item = player.getInventory().getItem(event.getNewSlot());
ItemStack updated = updateItem(item);
if (updated != null) {
player.getInventory().setItem(event.getNewSlot(), updated);
}
}

@EventHandler(priority = EventPriority.HIGH)
public void onPlayerJoin(PlayerJoinEvent event) {
updateInventory(event.getPlayer());
}

private void updateInventory(@NotNull Player player) {
PlayerInventory inv = player.getInventory();
ItemStack[] contents = inv.getContents();
for (int i = 0; i < contents.length; i++) {
ItemStack updated = updateItem(contents[i]);
if (updated != null) {
inv.setItem(i, updated);
}
}
}

@Nullable
private ItemStack updateItem(@Nullable ItemStack item) {
if (item == null || item.getType() == Material.AIR) return null;

QModuleDrop<?> module = ItemStats.getModule(item);
if (module == null || !module.isAutoUpdate()) return null;

String itemId = ItemStats.getId(item);
if (itemId == null) return null;

ModuleItem moduleItem = module.getItemById(itemId);
if (moduleItem == null) return null;

ItemStack updated = moduleItem.update(item);
if (module.isAutoUpdateOverrideChanges()) {
return updated;
}

ItemStack template = createTemplate(moduleItem, item);
if (!hasPlayerItemChanges(item, template)) {
return updated;
}

return reapplyPlayerChanges(updated, item);
}

@NotNull
private ItemStack createTemplate(@NotNull ModuleItem moduleItem, @NotNull ItemStack sourceItem) {
if (moduleItem instanceof LeveledItem) {
return ((LeveledItem) moduleItem).create(ItemStats.getLevel(sourceItem));
}
return moduleItem.create();
}

/**
* Detects whether the source item differs from a clean module template in player-modifiable fields:
* display name, lore, enchantments, item flags, item damage and armor/potion color.
*/
private boolean hasPlayerItemChanges(@NotNull ItemStack source, @NotNull ItemStack template) {
if (!source.getEnchantments().equals(template.getEnchantments())) return true;

ItemMeta sourceMeta = source.getItemMeta();
ItemMeta templateMeta = template.getItemMeta();
if (sourceMeta == null || templateMeta == null) return sourceMeta != templateMeta;

if (sourceMeta.hasDisplayName() != templateMeta.hasDisplayName()) return true;
if (sourceMeta.hasDisplayName() && !sourceMeta.getDisplayName().equals(templateMeta.getDisplayName())) return true;

if (sourceMeta instanceof Damageable && templateMeta instanceof Damageable) {
if (((Damageable) sourceMeta).getDamage() != ((Damageable) templateMeta).getDamage()) return true;
}

if (sourceMeta instanceof LeatherArmorMeta && templateMeta instanceof LeatherArmorMeta) {
if (!((LeatherArmorMeta) sourceMeta).getColor().equals(((LeatherArmorMeta) templateMeta).getColor())) return true;
}

if (sourceMeta instanceof PotionMeta && templateMeta instanceof PotionMeta) {
Color sourceColor = ((PotionMeta) sourceMeta).getColor();
Color templateColor = ((PotionMeta) templateMeta).getColor();
if (sourceColor == null ? templateColor != null : !sourceColor.equals(templateColor)) return true;
}

return false;
}

@NotNull
private ItemStack reapplyPlayerChanges(@NotNull ItemStack updated, @NotNull ItemStack source) {
ItemMeta sourceMeta = source.getItemMeta();
ItemMeta updatedMeta = updated.getItemMeta();
if (sourceMeta == null || updatedMeta == null) return updated;

if (sourceMeta.hasDisplayName()) {
updatedMeta.setDisplayName(sourceMeta.getDisplayName());
}

if (sourceMeta instanceof Damageable && updatedMeta instanceof Damageable) {
((Damageable) updatedMeta).setDamage(((Damageable) sourceMeta).getDamage());
}

if (sourceMeta instanceof LeatherArmorMeta && updatedMeta instanceof LeatherArmorMeta) {
((LeatherArmorMeta) updatedMeta).setColor(((LeatherArmorMeta) sourceMeta).getColor());
}

if (sourceMeta instanceof PotionMeta && updatedMeta instanceof PotionMeta) {
((PotionMeta) updatedMeta).setColor(((PotionMeta) sourceMeta).getColor());
}

updated.setItemMeta(updatedMeta);
new HashSet<>(updated.getEnchantments().keySet()).forEach(updated::removeEnchantment);
source.getEnchantments().forEach((enchantment, level) -> updated.addUnsafeEnchantment(enchantment, level));

return updated;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,14 @@ public final ItemStack create() {
return this.create(-1);
}

@NotNull
@Override
public ItemStack update(@NotNull ItemStack item) {
ItemStack updated = this.build(item.clone(), ItemStats.getLevel(item));
updated.setAmount(item.getAmount());
return updated;
}

private void updateConfig(@NotNull JYML cfg) {
cfg.addMissing("tier", JStrings.DEFAULT);

Expand Down
14 changes: 14 additions & 0 deletions src/main/java/studio/magemonkey/divinity/modules/ModuleItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,13 @@ public ItemStack create() {
return this.build();
}

@NotNull
public ItemStack update(@NotNull ItemStack item) {
ItemStack updated = this.build(item.clone());
updated.setAmount(item.getAmount());
return updated;
}

@NotNull
protected ItemStack build() {
return build(this.getMaterial().create());
Expand Down Expand Up @@ -275,6 +282,13 @@ protected ItemStack build(@NotNull ItemStack item) {
meta.addEnchant(NamespaceResolver.getEnchantment("POWER", "ARROW_DAMAGE"), 1, true); // ARROW_DAMAGE/POWER
}

if (meta.hasAttributeModifiers()) {
Set<Attribute> existing = new HashSet<>(meta.getAttributeModifiers().keySet());
for (Attribute attr : existing) {
meta.removeAttributeModifier(attr);
}
}

for (Map.Entry<Attribute, AttributeModifier> attribute : this.attributes.entrySet()) {
if (attribute != null) {
meta.addAttributeModifier(attribute.getKey(), attribute.getValue());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ public abstract class QModuleDrop<I extends ModuleItem> extends QModule {

private String itemNameFormat;
private List<String> itemLoreFormat;
private boolean autoUpdate;
private boolean autoUpdateOverrideChanges;

public QModuleDrop(@NotNull Divinity plugin, @NotNull Class<I> clazz) {
super(plugin);
Expand All @@ -61,10 +63,14 @@ protected void loadSettings() {
String path = "item-format.";
cfg.addMissing(path + "name", ItemTags.PLACEHOLDER_ITEM_NAME);
cfg.addMissing(path + "lore", Arrays.asList(ItemTags.PLACEHOLDER_ITEM_LORE));
cfg.addMissing("auto-update", false);
cfg.addMissing("auto-update-override-changes", false);
cfg.saveChanges();

this.itemNameFormat = StringUT.color(cfg.getString(path + "name", ItemTags.PLACEHOLDER_ITEM_NAME));
this.itemLoreFormat = StringUT.color(cfg.getStringList(path + "lore"));
this.autoUpdate = cfg.getBoolean("auto-update");
this.autoUpdateOverrideChanges = cfg.getBoolean("auto-update-override-changes");
}

protected void loadItems() {
Expand Down Expand Up @@ -107,6 +113,14 @@ public List<String> getItemLoreFormat() {
return this.itemLoreFormat;
}

public boolean isAutoUpdate() {
return this.autoUpdate;
}

public boolean isAutoUpdateOverrideChanges() {
return this.autoUpdateOverrideChanges;
}

@Nullable
public I getItemById(@NotNull String id, @Nullable String sTier) {
if (this.items == null || this.items.isEmpty()) return null;
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/modules/active_items/settings.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
command-aliases: activeitems
auto-update: false
auto-update-override-changes: false

item-format:
name: '%TIER_COLOR%%ITEM_NAME% %ITEM_LEVEL_ROMAN%'
Expand All @@ -9,4 +11,4 @@ item-format:
- '%USER_LEVEL%'
- '%USER_CLASS%'
- ''
- '%ITEM_LORE%'
- '%ITEM_LORE%'
2 changes: 2 additions & 0 deletions src/main/resources/modules/arrows/settings.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
command-aliases: arrows
auto-update: false
auto-update-override-changes: false

settings:
allow-infinity-enchant: false
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/modules/consumables/settings.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
command-aliases: consumables,consumes
auto-update: false
auto-update-override-changes: false
consuming:
allow-on-full-health: true
allow-on-full-food: true
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/modules/custom_items/settings.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
command-aliases: customitems
auto-update: false
auto-update-override-changes: false
item-format:
name: '%ITEM_NAME%'
lore:
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/modules/dismantle/settings.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
command-aliases: dismantle
auto-update: false
auto-update-override-changes: false
general:
actions-complete:
default:
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/modules/essences/settings.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
cfg_version: 1.0
command-aliases: essence,essences
auto-update: false
auto-update-override-changes: false
socketing:
allow-duplicated-items: true
animated-bar:
Expand Down Expand Up @@ -100,4 +102,4 @@ gui:
name: '&c&l&nCancel'
lore: [ ]
slots: '0'
type: EXIT
type: EXIT
2 changes: 2 additions & 0 deletions src/main/resources/modules/extractor/settings.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
command-aliases: extractor
auto-update: false
auto-update-override-changes: false
extraction:
price:
GEM:
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/modules/fortify/settings.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
command-aliases: fortify
auto-update: false
auto-update-override-changes: false
format:
item-name:
as-prefix: false
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/modules/gems/settings.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
command-aliases: gems
auto-update: false
auto-update-override-changes: false

socketing:
allow-duplicated-items: true
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/modules/identify/settings.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
command-aliases: identify,identifying
auto-update: false
auto-update-override-changes: false
general:
actions-complete:
default:
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/modules/item_generator/settings.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
command-aliases: itemgenerator,itemgen
auto-update: false
auto-update-override-changes: false
item-format:
name: '%TIER_COLOR%%ITEM_NAME%'
lore:
- '%ITEM_LORE%'
- '%ITEM_LORE%'
2 changes: 2 additions & 0 deletions src/main/resources/modules/magic_dust/settings.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
command-aliases: magicdust
auto-update: false
auto-update-override-changes: false
general:
actions-apply:
default:
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/modules/money/settings.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
command-aliases: moneymodule
auto-update: false
auto-update-override-changes: false

item-format:
name: '%ITEM_NAME%'
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/modules/refine/settings.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
command-aliases: refine
auto-update: false
auto-update-override-changes: false
refine:
actions-on-success:
default:
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/modules/repair/settings.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
command-aliases: rpgrepair
auto-update: false
auto-update-override-changes: false
repair:
actions-complete:
default:
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/modules/runes/settings.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
command-aliases: runes
auto-update: false
auto-update-override-changes: false
general:
stack-levels: false
socketing:
Expand Down
Loading