Skip to content

Commit

Permalink
EliteMobs 9.2.2:
Browse files Browse the repository at this point in the history
- [New] Added elite scrolls! This allows integration of items from plugins such as ItemsAdder into EliteMobs in a smoother way. If you are using an items plugin and want better integration with EliteMobs, go to ~/plugins/EliteMobs/ItemSettings.yml and enable useEliteItemScrolls. This will make all elites and bosses have a 10% chance (configurable) of dropping elite item scrolls of about 1 level higher than the boss. Those scrolls can then be used in the adventurer's guild's Scroll Applier, next to the enchanter, or through the command /em scroll for those not using the recommended adventurer's guild. Giving the scroll applier your combat item and weapon will give that item a matching EliteMobs level, adding elite dps or elite defense stats to it. This does not change the original item's stats, it only adds elitemobs-specific stats to them. Balance should be good by default, but admins should check if this system will work for their specific servers and item plugins and configurations.
- [Fix] Fixed an incredibly specific problem that would cause elites to stop spawning, thanks to a very thorough report by the community
- [Fix] Fixed long-standing issue with detecting stats of items from other plugins in extremely specific conditions

Signed-off-by: MagmaGuy <tiagoarnaut@gmail.com>
  • Loading branch information
MagmaGuy committed Dec 27, 2024
1 parent ff0b448 commit 405017e
Show file tree
Hide file tree
Showing 16 changed files with 474 additions and 17 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ processResources {
}

group 'com.magmaguy'
version '9.2.1'
version '9.2.2'

repositories {
maven {
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/com/magmaguy/elitemobs/EventsRegistrer.java
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ public static void registerEvents() {
if (ItemSettingsConfig.isPreventEliteItemDiamondToNetheriteUpgrade())
register(new PreventUpgradeDiamondToNetherite());

if (ItemSettingsConfig.isUseEliteItemScrolls())
register(new EliteScrollMenu.EliteScrollMenuEvents());

register(new FixPlayerOnLoginOrRespawn());
register(new EnvironmentalDungeonDamage());
register(new PlayerQuitCleanup());
Expand Down Expand Up @@ -350,8 +353,8 @@ public static void registerEvents() {
register(new NPCProximitySensor());
register(new NPCEntity.NPCEntityEvents());
register(new FindNewWorlds());
register(new WorldGuardSpawnEventBypasser());
if (EliteMobs.worldGuardIsEnabled) {
register(new WorldGuardSpawnEventBypasser());
register(new WorldGuardEliteMobOnlySpawnFlag());
register(new WorldGuardDungeonFlag());
register(new WorldGuardExplosionBlockDamageFlag());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,9 @@ public static double getAttackSpeed(@Nullable ItemStack itemStack) {
//Ranged damage works differently. Bows take 1s to draw and crossbows take 1.25s to draw.
if (itemStack.getType() == Material.BOW) return 1.0;
else if (itemStack.getType() == Material.CROSSBOW) return 0.8;
//Check the default modifiers - these are usually the only modifiers
try {
for (AttributeModifier attributeModifier : itemStack.getType().getDefaultAttributeModifiers(EquipmentSlot.HAND).get(AttributeManager.getAttribute("generic_attack_speed")))
defaultAttackSpeed = attributeCrawler(defaultAttackSpeed, attributeModifier);
} catch (NoSuchMethodError e) {
//If you're on an ancient version you just get the default sword speed.
defaultAttackSpeed = 4.0;
}

//Check custom modifiers - this should only happen when third party plugins step in
//Also weirdly enough if they are present the defaults go out of the window, they're not stacking
if (itemStack.getItemMeta() != null &&
itemStack.getItemMeta().getAttributeModifiers() != null &&
itemStack.getItemMeta().getAttributeModifiers(EquipmentSlot.HAND).containsKey(AttributeManager.getAttribute("generic_attack_speed")))
Expand All @@ -110,6 +104,15 @@ public static double getAttackSpeed(@Nullable ItemStack itemStack) {
.getAttributeModifiers()
.get(AttributeManager.getAttribute("generic_attack_speed")))
defaultAttackSpeed = attributeCrawler(defaultAttackSpeed, attributeModifier);
else
//Check the default modifiers - these are usually the only modifiers
try {
for (AttributeModifier attributeModifier : itemStack.getType().getDefaultAttributeModifiers(EquipmentSlot.HAND).get(AttributeManager.getAttribute("generic_attack_speed")))
defaultAttackSpeed = attributeCrawler(defaultAttackSpeed, attributeModifier);
} catch (NoSuchMethodError e) {
//If you're on an ancient version you just get the default sword speed.
defaultAttackSpeed = 4.0;
}
return defaultAttackSpeed;
}

Expand Down Expand Up @@ -278,6 +281,27 @@ public static void setEliteLevel(@Nullable ItemStack itemStack, int level) {
new EliteItemLore(itemStack, false);
}

public static void setEliteLevel(@Nullable ItemStack itemStack, int level, boolean onlyArmorOrWeapons) {
if (itemStack == null) return;
if (isWeapon(itemStack)) {
double damage = calculateEliteBonus(itemStack, level);
if (damage > 0)
ItemTagger.setEliteDamageAttribute(itemStack, damage);
} else if (isArmor(itemStack)) {
double defense = calculateEliteBonus(itemStack, level);
if (defense > 0)
ItemTagger.setEliteDefenseAttribute(itemStack, defense);
} else if (onlyArmorOrWeapons) {
return;
}
if (!isEliteMobsItem(itemStack)) {
registerEliteItem(itemStack);
new EliteItemLore(itemStack, false,true);
} else {
new EliteItemLore(itemStack, false,false);
}
}

/**
* This returns how much elite damage an item would give, based on a level. This should be used when a level wants to
* be calculated instead of read, which should only be true when you're doing something tricky like temporarily limiting
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ public static void registerCommands() {
emCommand.registerCommand(new ShopCustomCommand());
emCommand.registerCommand(new RepairCommand());
emCommand.registerCommand(new EnchantCommand());
emCommand.registerCommand(new EliteScrollCommand());
emCommand.registerCommand(new ScrapCommand());
emCommand.registerCommand(new UnbindCommand());
emCommand.registerCommand(new MoneyCheckCommand());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.magmaguy.elitemobs.commands;

import com.magmaguy.elitemobs.commands.guild.AdventurersGuildCommand;
import com.magmaguy.elitemobs.config.ItemSettingsConfig;
import com.magmaguy.elitemobs.menus.EliteScrollMenu;
import com.magmaguy.magmacore.command.AdvancedCommand;
import com.magmaguy.magmacore.command.CommandData;
import com.magmaguy.magmacore.command.SenderType;
import com.magmaguy.magmacore.util.Logger;

import java.util.List;

public class EliteScrollCommand extends AdvancedCommand {
public EliteScrollCommand() {
super(List.of("scroll"));
setUsage("/em scroll");
setPermission("elitemobs.scroll.command");
setSenderType(SenderType.PLAYER);
setDescription("Opens the elite scroll menu or teleports the player to the Adventurer's Guild Hub");
}

@Override
public void execute(CommandData commandData) {
if (!ItemSettingsConfig.isUseEliteItemScrolls()) {
Logger.sendMessage(commandData.getCommandSender(), "Elite Scrolls are not currently enabled on this server! They should only be used if the server uses an item system other than EliteMobs' built in item system. To enable elite scrolls, an admin has to set them to true in the ~/plugins/EliteMobs/ItemSettings.yml and set useEliteItemScrolls to true.");
return;
}
if (!AdventurersGuildCommand.adventurersGuildTeleport(commandData.getPlayerSender()))
new EliteScrollMenu(commandData.getPlayerSender());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,14 @@ public class ItemSettingsConfig extends ConfigurationFile {
private static String armorEntry;
@Getter
private static String levelRangeTooDifferent;
@Getter
private static boolean useEliteItemScrolls;
@Getter
private static double eliteItemScrollChance;
@Getter
private static String eliteItemScrollName;
@Getter
private static List<String> eliteItemScrollLore;

public ItemSettingsConfig() {
super("ItemSettings.yml");
Expand Down Expand Up @@ -341,6 +349,25 @@ public void initializeValues() {
levelRangeTooDifferent = ConfigurationEngine.setString(
List.of("Sets the message sent when a played kills a boss but the gear level is too different from the boss level to get coins"),
file, fileConfiguration, "levelRangeTooDifferent", "&8EM] &4Your gear is level $playerLevel and the boss is level $bossLevel, level difference is too high to get coins!", true);

useEliteItemScrolls = ConfigurationEngine.setBoolean(List.of(
"Sets whether the plugin will use Elite Item Scrolls",
"Elite Item Scroll are recommended for servers that want to use other item plugins like ItemAdder",
"Elite item scrolls can be used at anvils to give non-elite items elite levels",
"Elite item scrolls drop from elites of the same level to guarantee that the loot is balanced",
"Note for item balance that elite damage does not affect damage outside of EliteMobs, so in most scenarios this should not result in broken (overpowered) items"),
fileConfiguration, "useEliteItemScrolls", false);
eliteItemScrollChance = ConfigurationEngine.setDouble(List.of(
"Sets the chance of an Elite Item Scroll dropping from a boss, where 0 is 0% and 1 is 100%, and 0.5 is 50%."),
fileConfiguration, "eliteItemScrollChance", 0.1);
eliteItemScrollName = ConfigurationEngine.setString(List.of(
"Sets the name of the elite item scroll item"),file,
fileConfiguration, "eliteItemScrollName", "&6Elite Item Scroll", true);
eliteItemScrollLore = ConfigurationEngine.setList(List.of(
"Sets the name of the elite item scroll item"),file,
fileConfiguration, "eliteItemScrollLore", List.of(
"&fUse at an anvil to enchant",
"&fa non-elite item into",
"&fa level $level elite item!"),
true);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package com.magmaguy.elitemobs.config.menus.premade;

import com.magmaguy.elitemobs.MetadataHandler;
import com.magmaguy.elitemobs.config.ConfigurationEngine;
import com.magmaguy.elitemobs.config.CustomModelsConfig;
import com.magmaguy.elitemobs.config.menus.MenusConfigFields;
import com.magmaguy.elitemobs.utils.CustomModelAdder;
import com.magmaguy.elitemobs.utils.ItemStackSerializer;
import com.magmaguy.magmacore.util.ItemStackGenerator;
import lombok.Getter;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;

import java.util.ArrayList;
import java.util.List;

public class EliteScrollMenuConfig extends MenusConfigFields {
@Getter
private static String menuName;
@Getter
private static int infoSlot;
@Getter
private static ItemStack infoButton;
@Getter
private static int cancelSlot;
@Getter
private static ItemStack cancelButton;
@Getter
private static int confirmSlot;
@Getter
private static ItemStack confirmButton;
@Getter
private static int nonEliteItemSlot;
@Getter
private static int nonEliteItemInfoSlot;
@Getter
private static ItemStack nonEliteItemInfoButton;
@Getter
private static int eliteScrollItemSlot;
@Getter
private static int eliteScrollItemInfoSlot;
@Getter
private static ItemStack eliteScrollItemInfoButton;
@Getter
private static ItemStack outputInfoButton;
@Getter
private static int outputInfoSlot;
@Getter
private static int outputSlot;


public EliteScrollMenuConfig() {
super("elite_scroll_menu", true);
}

@Override
public void processAdditionalFields() {
menuName = ConfigurationEngine.setString(
List.of("Sets the display name of the menu"),
file, fileConfiguration, "menuName", "&6Elite Scroll Menu", true);
infoSlot = ConfigurationEngine.setInt(
List.of("Sets the item slot number of the information button in the chest menu."),
fileConfiguration, "infoSlot", 4);
ItemStackSerializer.serialize(
"infoButton",
ItemStackGenerator.generateSkullItemStack("magmaguy",
"&2Elite Scroll info:",
new ArrayList<>(List.of(
"&2This menu converts non-elite items into elite items!",
"&2Elite items have elite dps or elite defense which applies",
"&2to elite mobs.",
"&2To convert a non-elite item into an elite item, place",
"&2your non-elite item below, as well as a Elite Scroll!"))),
fileConfiguration);
infoButton = ItemStackSerializer.deserialize("infoButton", fileConfiguration);
CustomModelAdder.addCustomModel(infoButton, CustomModelsConfig.goldenQuestionMark);
cancelSlot = ConfigurationEngine.setInt(
List.of("Sets the item slot number of the cancel button in the chest menu."),
fileConfiguration, "cancelSlot", 27);
ItemStackSerializer.serialize("cancelButton", ItemStackGenerator.generateItemStack(Material.BARRIER,
"&4Cancel", List.of("&cCancel!"), MetadataHandler.signatureID), fileConfiguration);
cancelButton = ItemStackSerializer.deserialize("cancelButton", fileConfiguration);
CustomModelAdder.addCustomModel(cancelButton, CustomModelsConfig.redCross);
confirmSlot = ConfigurationEngine.setInt(
List.of("Sets the item slot number of the confirm button in the chest menu."),
fileConfiguration, "confirmSlot", 35);
ItemStackSerializer.serialize("confirmButton", ItemStackGenerator.generateItemStack(Material.EMERALD,
"&2Apply!", new ArrayList<>(),
"elitemobs:ui/anvilhammer"), fileConfiguration);
confirmButton = ItemStackSerializer.deserialize("confirmButton", fileConfiguration);
CustomModelAdder.addCustomModel(confirmButton, CustomModelsConfig.anvilHammer);
nonEliteItemSlot = ConfigurationEngine.setInt(
List.of("Sets the item slot number of the non-elite item in the chest menu."),
fileConfiguration, "itemSlot", 29);
nonEliteItemInfoSlot = ConfigurationEngine.setInt(
List.of("Sets the item slot number of the non-elite item info button in the chest menu."),
fileConfiguration, "itemInfoSlot", 20);
ItemStackSerializer.serialize(
"itemInfoButton",
ItemStackGenerator.generateItemStack(Material.GREEN_BANNER,
"&2Non-Elite Item Input slot",
List.of("&aPut your non-elite item here!"), MetadataHandler.signatureID),
fileConfiguration);
nonEliteItemInfoButton = ItemStackSerializer.deserialize("itemInfoButton", fileConfiguration);
CustomModelAdder.addCustomModel(nonEliteItemInfoButton, CustomModelsConfig.boxInput);
eliteScrollItemInfoSlot = ConfigurationEngine.setInt(
List.of("Sets the item slot number of the elite scroll item info button in the chest menu."),
fileConfiguration, "eliteScrollItemInfoSlot", 22);
ItemStackSerializer.serialize(
"eliteScrollItemInfoButton",
ItemStackGenerator.generateItemStack(Material.GREEN_BANNER,
"&2Elite Scroll Input slot",
List.of("&aPut your elite scroll here!"), MetadataHandler.signatureID),
fileConfiguration);
eliteScrollItemInfoButton = ItemStackSerializer.deserialize("eliteScrollItemInfoButton", fileConfiguration);
eliteScrollItemSlot = ConfigurationEngine.setInt(
List.of("Sets the item slot number of elite scroll in the chest menu."),
fileConfiguration, "eliteScrollItemSlot", 31);

outputInfoButton = ConfigurationEngine.setItemStack(file, fileConfiguration, "outputInfoButton",
ItemStackGenerator.generateItemStack(Material.RED_BANNER, "&2Result"), true);
outputInfoSlot = ConfigurationEngine.setInt(fileConfiguration, "outputInfoSlot", 24);
outputSlot = ConfigurationEngine.setInt(fileConfiguration, "outputSlot", 33);
CustomModelAdder.addCustomModel(eliteScrollItemInfoButton, CustomModelsConfig.boxInput);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.magmaguy.elitemobs.config.npcs.premade;

import com.magmaguy.elitemobs.config.npcs.NPCsConfigFields;
import com.magmaguy.elitemobs.npcs.NPCInteractions;
import org.bukkit.entity.Villager;

import java.util.ArrayList;
import java.util.List;

public class ScrollApplier extends NPCsConfigFields {
public ScrollApplier() {
super("scroll_applier_config",
true,
"Scotty",
"<Scroll Applier>",
Villager.Profession.WEAPONSMITH,
"em_adventurers_guild,274.5,77,245.5,-20,0",
new ArrayList<>(List.of(
"Got elite scrolls?",
"Is it elite scroll time?",
"Good vanilla item you want converted?")),
new ArrayList<>(List.of(
"Need a vanilla item converted?",
"Want to hit elite mobs harder?",
"Good vanilla item you want converted?")),
new ArrayList<>(List.of(
"Come back when you have elite scrolls!")),
true,
3,
NPCInteractions.NPCInteractionType.SCROLL_APPLIER);
setDisguise("custom:ag_back_teleporter");
setCustomDisguiseData("player ag_back_teleporter setskin {\"id\":\"884501c8-4d93-46bc-85fb-2028723de920\",\"name\":\"Unknown\",\"properties\":[{\"name\":\"textures\",\"value\":\"ewogICJ0aW1lc3RhbXAiIDogMTYxNDQ3NTk0OTk1NiwKICAicHJvZmlsZUlkIiA6ICJkZTU3MWExMDJjYjg0ODgwOGZlN2M5ZjQ0OTZlY2RhZCIsCiAgInByb2ZpbGVOYW1lIiA6ICJNSEZfTWluZXNraW4iLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzE1YjRjNzk0NzJiMTVlZmRkOTRmZDQ2MmMxZGYzYTM2MjhhNjY2MDVkYjk5NjQ3ZTNhYzA5MzJiYTZlNzk0ZSIKICAgIH0KICB9Cn0=\",\"signature\":\"hAAiBL8a0UBXNdyYehx9AjWsz7EzhbnyldVEZPx2pd8N76TCgscu2ad8ypKj961D8iBl7u3GMmAtoAQtDSMIfaA8GteGu7nhBE4f9/+QXtzkFcudbk7C+Hq8LVLvWsbmVywrsNiqQ+6KFdT7/YnhPXO1xO1EjsnRbuynN/FhlJWdWwBLjuA9e/QA2LH8OgHHdAA73/gJfxH+5isc4sy0dVo+KwUjKaPGDem+eB2JlwSAfJECj9PiFNbdDKcjFNMVBQJOUZmrWH1eW4fYgk4I3mQ6uURmwp2Tp0zLu9Sgt0+wDNbYFb33x2XN4veDdEqTLoE55XqpSRmQAi9dAtyjiOc+3ATDV9pewcAjT+yk6IN5gR0qU36UM4E2uoZ+2tvgOlm9ZOoxx8nv0fWLUNEBnR16n8LCceisDh9KG8+MBtxvPLZnkghBNJmy6S6Fm1aPq4dZmCV/PlxMznN4ys/eG/QrmYguO8Wf9jNQiO47x745fBaD53W5A27GH7tChNgDFJ6pF3U/cfa0HdH5ddkGCYlfevWkOhEKdTxC//+R7+ryyaiBLsr1vTQvgTWYdvZKWIW8QLTTVktkhdZIApoTJMD8HxdvdxhulpyCIFBxkW+iXBkJLfBA93LrXvkNRmUoXl2OIyAxekhoL1Hj753l9PDkz4sqLx1nA18cb4TyQ0U=\"}],\"legacy\":false}");
}
}
17 changes: 15 additions & 2 deletions src/main/java/com/magmaguy/elitemobs/items/EliteItemLore.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,20 @@ public class EliteItemLore {
private List<String> customLore = new ArrayList<>();
private int prestigeLevel = 0;
private int enchantmentCount = 0;

private List<String> thirdPartyLore = null;

public EliteItemLore(ItemStack itemStack, boolean showItemWorth) {
initialize(itemStack, showItemWorth);
}

public EliteItemLore(ItemStack itemStack, boolean showItemWorth, boolean isNewItem) {
if (isNewItem && itemStack.getItemMeta().getLore() != null || !itemStack.getItemMeta().getLore().isEmpty()) {
thirdPartyLore = itemStack.getItemMeta().getLore();
}
initialize(itemStack, showItemWorth);
}

private void initialize(ItemStack itemStack, boolean showItemWorth){

if (!EliteItemManager.isEliteMobsItem(itemStack)) {
Logger.warn("Attempted to rewrite the lore of a non-elitemobs item! This is not supposed to happen.");
Expand Down Expand Up @@ -86,7 +97,6 @@ public EliteItemLore(ItemStack itemStack, boolean showItemWorth) {
this.itemMeta.setLore(lore);
ItemTagger.registerEnchantmentCount(itemMeta, enchantmentCount);
this.itemStack.setItemMeta(this.itemMeta);

}

private void constructVanillaEnchantments() {
Expand Down Expand Up @@ -214,6 +224,9 @@ private void constructPotionEffects() {
}

private void writeNewLore() {
if (thirdPartyLore != null)
lore.addAll(thirdPartyLore);

for (String string : ItemSettingsConfig.getLoreStructure()) {

if (string.contains("$weaponOrArmorStats")) {
Expand Down
Loading

0 comments on commit 405017e

Please sign in to comment.