diff --git a/build.gradle b/build.gradle index 3125b88b..5c6608af 100644 --- a/build.gradle +++ b/build.gradle @@ -22,11 +22,11 @@ plugins { id "com.github.johnrengelman.shadow" version "7.1.2" } -version '1.15.2-1.19.2-1.21.1' +version '1.15.3-1.19.2-1.21.3' def apiVersion = '1.19' def name = getRootProject().getName() // Defined in settings.gradle def main = 'com.volmit.adapt.Adapt' -def manifoldVersion = '2024.1.30' +def manifoldVersion = '2024.1.37' // ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED // ======================== WINDOWS ============================= @@ -44,6 +44,7 @@ registerCustomOutputTaskUnix('the456gamer', '/home/the456gamer/projects/minecraf // ============================================================== def VERSIONS = Map.of( + "v1_21_2", "1.21.2-R0.1-SNAPSHOT", "v1_21", "1.21-R0.1-SNAPSHOT", "v1_20_5", "1.20.5-R0.1-SNAPSHOT", "v1_20_4", "1.20.4-R0.1-SNAPSHOT", @@ -51,8 +52,8 @@ def VERSIONS = Map.of( ) VERSIONS.each { - def key = it.key; - def value = it.value; + def key = it.key + def value = it.value project(":version:${key}") { apply plugin: 'java' apply plugin: 'java-library' @@ -93,6 +94,7 @@ allprojects { content { includeGroup("org.bukkit") includeGroup("org.spigotmc") + includeGroup("com.frengor") } } mavenCentral() @@ -100,12 +102,11 @@ allprojects { maven { url "https://repo.codemc.org/repository/maven-public" } maven { url "https://mvn.lumine.io/repository/maven-public/" } maven { url "https://nexus.frengor.com/repository/public/"} - maven { url "https://jitpack.io"} - maven { url = 'https://repo.extendedclip.com/content/repositories/placeholderapi/' } - maven { url 'https://jitpack.io' } - maven { url 'https://ci.ender.zone/plugin/repository/everything/' } - maven { url "https://arcanearts.jfrog.io/artifactory/archives" } + maven { url 'https://repo.extendedclip.com/content/repositories/placeholderapi/' } maven { url "https://repo.glaremasters.me/repository/bloodshot/" } + maven { url "https://maven.enginehub.org/repo/" } + maven { url "https://repo.oraxen.com/releases" } + maven { url 'https://jitpack.io' } mavenLocal() } @@ -123,10 +124,15 @@ allprojects { annotationProcessor 'org.projectlombok:lombok:1.18.24' // Cancer - implementation 'art.arcane:Amulet:22.7.18' - implementation 'art.arcane:Fukkit:22.7.5' - implementation 'art.arcane:Curse:23.5.2' + implementation 'com.github.VolmitDev:Fukkit:23.6.1' + implementation 'com.github.VolmitDev:Amulet:23.5.1' + implementation 'com.github.VolmitDev:Chrono:22.9.10' + implementation 'com.github.VolmitDev:Curse:23.4.3' + implementation 'com.github.VolmitDev:MultiBurst:22.9.2' + implementation 'com.github.VolmitDev:Spatial:22.11.1' + implementation "io.papermc:paperlib:1.0.7" + implementation 'com.github.ben-manes.caffeine:caffeine:3.0.6' annotationProcessor 'systems.manifold:manifold-ext:' + manifoldVersion testAnnotationProcessor 'systems.manifold:manifold-ext:' + manifoldVersion implementation 'systems.manifold:manifold-rt:' + manifoldVersion @@ -134,15 +140,15 @@ allprojects { //Random Api's implementation 'com.github.DeadSilenceIV:AdvancedChestsAPI:2.9-BETA' implementation 'com.sk89q.worldguard:worldguard-bukkit:7.0.8' - implementation "com.github.FrancoBM12:API-MagicCosmetics:2.2.2" + implementation "com.github.FrancoBM12:API-MagicCosmetics:2.2.8" implementation 'me.clip:placeholderapi:2.11.2' implementation 'com.github.LoneDev6:api-itemsadder:3.2.5' - implementation 'io.th0rgal:oraxen:1.94.0' + implementation 'io.th0rgal:oraxen:1.182.0' implementation 'com.massivecraft:Factions:1.6.9.5-U0.6.21' implementation "com.github.angeschossen:ChestProtectAPI:3.9.1" implementation "com.github.TechFortress:GriefPrevention:16.18.1" implementation 'xyz.xenondevs:particle:1.8.1' - implementation "com.frengor:ultimateadvancementapi-shadeable:2.4.1" + implementation "com.frengor:ultimateadvancementapi-shadeable:2.4.2" compileOnly 'com.griefdefender:api:2.1.0-SNAPSHOT' compileOnly 'io.netty:netty-all:4.1.68.Final' @@ -155,6 +161,7 @@ allprojects { compileOnly 'net.kyori:adventure-platform-bukkit:4.3.0' compileOnly 'net.kyori:adventure-api:4.13.1' compileOnly 'it.unimi.dsi:fastutil:8.5.13' + compileOnly "fr.skytasul:glowingentities:1.4" implementation 'com.google.guava:guava:30.1-jre' compileOnly fileTree(dir: 'libs', include: ['*.jar']) } @@ -179,64 +186,18 @@ shadowJar { dependencies { include(dependency('systems.manifold:')) include(dependency('xyz.xenondevs:')) - include(dependency('art.arcane:')) + include(dependency('com.github.VolmitDev:')) include(dependency('com.frengor:ultimateadvancementapi-shadeable:')) } } -configurations.all { +configurations.configureEach { resolutionStrategy.cacheChangingModulesFor 60, 'minutes' resolutionStrategy.cacheDynamicVersionsFor 60, 'minutes' } dependencies { - // Provided or Classpath - compileOnly 'org.projectlombok:lombok:1.18.24' - annotationProcessor 'org.projectlombok:lombok:1.18.24' implementation 'org.spigotmc:spigot-api:1.20.1-R0.1-SNAPSHOT' - - // Vomit - implementation 'art.arcane:Curse:23.5.2' - implementation 'art.arcane:MultiBurst:22.9.2' - implementation 'art.arcane:Chrono:22.9.10' - implementation 'art.arcane:Spatial:22.11.1' - implementation 'com.github.ben-manes.caffeine:caffeine:3.0.6' - - // Cancer - implementation 'art.arcane:Amulet:22.7.18' - implementation 'art.arcane:Fukkit:22.7.5' - implementation 'art.arcane:Curse:23.5.2' - implementation "io.papermc:paperlib:1.0.7" - annotationProcessor 'systems.manifold:manifold-ext:' + manifoldVersion - testAnnotationProcessor 'systems.manifold:manifold-ext:' + manifoldVersion - implementation 'systems.manifold:manifold-rt:' + manifoldVersion - - //Random Api's - implementation 'com.github.DeadSilenceIV:AdvancedChestsAPI:2.9-BETA' - implementation 'com.sk89q.worldguard:worldguard-bukkit:7.0.8' - implementation "com.github.FrancoBM12:API-MagicCosmetics:2.2.2" - implementation 'me.clip:placeholderapi:2.11.2' - implementation 'com.github.LoneDev6:api-itemsadder:3.2.5' - implementation 'io.th0rgal:oraxen:1.94.0' - implementation 'com.massivecraft:Factions:1.6.9.5-U0.6.21' - implementation "com.github.angeschossen:ChestProtectAPI:3.9.1" - implementation "com.github.TechFortress:GriefPrevention:16.18.1" - implementation 'xyz.xenondevs:particle:1.8.1' - implementation "com.frengor:ultimateadvancementapi-shadeable:2.4.1" - compileOnly 'com.griefdefender:api:2.1.0-SNAPSHOT' - compileOnly 'io.netty:netty-all:4.1.68.Final' - - // Dynamically Loaded - compileOnly 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2' - compileOnly 'org.apache.commons:commons-lang3:3.12.0' - compileOnly 'com.google.code.gson:gson:2.10' - compileOnly 'com.elmakers.mine.bukkit:EffectLib:9.4' - compileOnly 'net.kyori:adventure-text-minimessage:4.13.1' - compileOnly 'net.kyori:adventure-platform-bukkit:4.3.0' - compileOnly 'net.kyori:adventure-api:4.13.1' - compileOnly 'it.unimi.dsi:fastutil:8.5.13' - implementation 'com.google.guava:guava:30.1-jre' - compileOnly fileTree(dir: 'libs', include: ['*.jar']) } if (JavaVersion.current().toString() != "17") { @@ -257,7 +218,7 @@ if (JavaVersion.current().toString() != "17") { System.exit(69) } -def buildDir = layout.buildDirectory.asFile.get(); +def buildDir = layout.buildDirectory.asFile.get() def outputJar = new File(buildDir, "libs/Adapt-" + version + "-all.jar") java { diff --git a/settings.gradle b/settings.gradle index 143aac9f..7e396aa7 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,7 @@ rootProject.name = 'Adapt' include( + ':version:v1_21_2', ':version:v1_21', ':version:v1_20_5', ':version:v1_20_4', diff --git a/src/main/java/com/volmit/adapt/Adapt.java b/src/main/java/com/volmit/adapt/Adapt.java index 7442ba0a..3bba0068 100644 --- a/src/main/java/com/volmit/adapt/Adapt.java +++ b/src/main/java/com/volmit/adapt/Adapt.java @@ -29,7 +29,7 @@ import com.volmit.adapt.api.world.AdaptServer; import com.volmit.adapt.content.gui.SkillsGui; import com.volmit.adapt.content.protector.*; -import com.volmit.adapt.nms.GlowingEntities; +import fr.skytasul.glowingentities.GlowingEntities; import com.volmit.adapt.util.*; import com.volmit.adapt.util.collection.KList; import com.volmit.adapt.util.collection.KMap; @@ -169,6 +169,7 @@ public void stopSim() { manager.disable(); MaterialValue.save(); WorldData.stop(); + CustomModel.clear(); } diff --git a/src/main/java/com/volmit/adapt/AdaptConfig.java b/src/main/java/com/volmit/adapt/AdaptConfig.java index 6fea3eb2..ac0c27c3 100644 --- a/src/main/java/com/volmit/adapt/AdaptConfig.java +++ b/src/main/java/com/volmit/adapt/AdaptConfig.java @@ -59,12 +59,14 @@ public class AdaptConfig { private boolean hardcoreResetOnPlayerDeath = false; private boolean hardcoreNoRefunds = false; private boolean loginBonus = true; + private boolean welcomeMessage = true; private boolean advancements = true; private boolean useSql = false; private int sqlSecondsCheckverify = 30; private boolean useEnchantmentTableParticleForActiveEffects = true; private boolean escClosesAllGuis = false; private boolean guiBackButton = false; + private boolean customModels = true; private int learnUnlearnButtonDelayTicks = 14; private int maxRecipeListPrecaution = 25; private boolean actionbarNotifyXp = true; diff --git a/src/main/java/com/volmit/adapt/api/adaptation/Adaptation.java b/src/main/java/com/volmit/adapt/api/adaptation/Adaptation.java index ccdc7e3b..c2820dd4 100644 --- a/src/main/java/com/volmit/adapt/api/adaptation/Adaptation.java +++ b/src/main/java/com/volmit/adapt/api/adaptation/Adaptation.java @@ -374,6 +374,19 @@ default BlockFace getBlockFace(Player player, int maxrange) { return targetBlock.getFace(adjacentBlock); } + default CustomModel getModel() { + return CustomModel.get(getIcon(), "adaptation", getName(), "icon"); + } + + default CustomModel getModel(int level) { + var model = CustomModel.get(getIcon(), "adaptation", getName(), "level-" + level); + if (model.material() == getIcon() && model.model() == 0) + model = CustomModel.get(Material.PAPER, "snippets", "gui", "level", String.valueOf(level)); + if (model.material() == Material.PAPER && model.model() == 0) + model = getModel(); + return model; + } + default boolean openGui(Player player, boolean checkPermissions) { if (hasBlacklistPermission(player, this)) { return false; @@ -395,7 +408,10 @@ default void openGui(Player player) { spw.play(player.getLocation(), Sound.ITEM_BOOK_PAGE_TURN, 0.3f, 0.855f); Window w = new UIWindow(player); w.setTag("skill/" + getSkill().getName() + "/" + getName()); - w.setDecorator((window, position, row) -> new UIElement("bg").setName(" ").setMaterial(new MaterialBlock(Material.BLACK_STAINED_GLASS_PANE))); + w.setDecorator((window, position, row) -> new UIElement("bg") + .setName(" ") + .setMaterial(new MaterialBlock(Material.BLACK_STAINED_GLASS_PANE)) + .setModel(CustomModel.get(Material.BLACK_STAINED_GLASS_PANE, "snippets", "gui", "background"))); w.setResolution(WindowResolution.W9_H6); int o = 0; @@ -427,6 +443,7 @@ default void openGui(Player player) { int lvl = i; Element de = new UIElement("lp-" + i + "g") .setMaterial(new MaterialBlock(getIcon())) + .setModel(getModel(i)) .setName(getDisplayName(i)) .setEnchanted(mylevel >= lvl) .setProgress(1D) @@ -486,11 +503,9 @@ default void openGui(Player player) { int backRow = w.getViewportHeight() - 1; w.setElement(backPos, backRow, new UIElement("back") .setMaterial(new MaterialBlock(Material.RED_BED)) + .setModel(CustomModel.get(Material.RED_BED, "snippets", "gui", "back")) .setName("" + C.RESET + C.GRAY + Localizer.dLocalize("snippets", "gui", "back")) - .onLeftClick((e) -> { - w.close(); - onGuiClose(player, true); - })); + .onLeftClick((e) -> onGuiClose(player, true))); } AdaptPlayer a = Adapt.instance.getAdaptServer().getPlayer(player); @@ -507,6 +522,8 @@ private void onGuiClose(Player player, boolean openPrevGui) { spw.play(player.getLocation(), Sound.ITEM_BOOK_PAGE_TURN, 0.3f, 0.855f); if (openPrevGui) { getSkill().openGui(player); + } else { + Adapt.instance.getGuiLeftovers().remove(player.getUniqueId().toString()); } } diff --git a/src/main/java/com/volmit/adapt/api/advancement/AdaptAdvancement.java b/src/main/java/com/volmit/adapt/api/advancement/AdaptAdvancement.java index 29d3439c..4af84319 100644 --- a/src/main/java/com/volmit/adapt/api/advancement/AdaptAdvancement.java +++ b/src/main/java/com/volmit/adapt/api/advancement/AdaptAdvancement.java @@ -20,7 +20,6 @@ import com.fren_gor.ultimateAdvancementAPI.AdvancementTab; -import com.fren_gor.ultimateAdvancementAPI.UltimateAdvancementAPI; import com.fren_gor.ultimateAdvancementAPI.advancement.Advancement; import com.fren_gor.ultimateAdvancementAPI.advancement.BaseAdvancement; import com.fren_gor.ultimateAdvancementAPI.advancement.RootAdvancement; @@ -28,9 +27,11 @@ import com.fren_gor.ultimateAdvancementAPI.advancement.display.AdvancementFrameType; import com.fren_gor.ultimateAdvancementAPI.database.TeamProgression; import com.volmit.adapt.Adapt; +import com.volmit.adapt.util.CustomModel; import lombok.*; import org.bukkit.Material; import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -42,6 +43,8 @@ public class AdaptAdvancement { @Builder.Default private Material icon = Material.EMERALD; @Builder.Default + private CustomModel model = null; + @Builder.Default private String title = "MISSING TITLE"; @Builder.Default private String description = "MISSING DESCRIPTION"; @@ -63,7 +66,10 @@ private Advancement toAdvancement(Advancement parent, int index, int depth) { children = new ArrayList<>(); } - AdvancementDisplay d = new AdvancementDisplay.Builder(getIcon(), getTitle()) + var icon = getModel() != null ? + getModel().toItemStack() : + new ItemStack(getIcon()); + AdvancementDisplay d = new AdvancementDisplay.Builder(icon, getTitle()) .description(getDescription()) .frame(getFrame()) .showToast(toast) diff --git a/src/main/java/com/volmit/adapt/api/notification/AdvancementNotification.java b/src/main/java/com/volmit/adapt/api/notification/AdvancementNotification.java index d1342fc9..0a014f17 100644 --- a/src/main/java/com/volmit/adapt/api/notification/AdvancementNotification.java +++ b/src/main/java/com/volmit/adapt/api/notification/AdvancementNotification.java @@ -22,6 +22,7 @@ import com.volmit.adapt.util.AdvancementUtils; import com.volmit.adapt.api.world.AdaptPlayer; +import com.volmit.adapt.util.CustomModel; import lombok.Builder; import lombok.Data; import org.bukkit.Material; @@ -33,6 +34,8 @@ public class AdvancementNotification implements Notification { @Builder.Default private final Material icon = Material.DIAMOND; @Builder.Default + private final CustomModel model = null; + @Builder.Default private final String title = " "; @Builder.Default private final String description = " "; @@ -54,7 +57,8 @@ public String getGroup() { @Override public void play(AdaptPlayer p) { if (p.getPlayer() != null) { - AdvancementUtils.displayToast(p.getPlayer(), new ItemStack(icon), title, description, frameType); + var icon = getModel() != null ? getModel().toItemStack() : new ItemStack(getIcon()); + AdvancementUtils.displayToast(p.getPlayer(), icon, title, description, frameType); } } diff --git a/src/main/java/com/volmit/adapt/api/skill/SimpleSkill.java b/src/main/java/com/volmit/adapt/api/skill/SimpleSkill.java index 99aee971..4a3a3ec2 100644 --- a/src/main/java/com/volmit/adapt/api/skill/SimpleSkill.java +++ b/src/main/java/com/volmit/adapt/api/skill/SimpleSkill.java @@ -169,7 +169,7 @@ protected boolean shouldReturnForPlayer(Player p) { return true; } Adapt.verbose("Checking " + p.getName() + " for " + getName()); - return !this.isEnabled() || hasBlacklistPermission(p, this) || isWorldBlacklisted(p) || isInCreativeOrSpectator(p); + return !this.isEnabled() || hasBlacklistPermission(p, this) || isWorldBlacklisted(p) || isInCreativeOrSpectator(p) || getPlayer(p) == null; } catch (Exception ignored) { return true; } @@ -197,7 +197,7 @@ protected void shouldReturnForPlayer(Player p, Cancellable c, Runnable r) { } } - protected boolean shouldReturnForWorld(World world, Skill skill) { + protected boolean shouldReturnForWorld(World world, Skill skill) { try { return !skill.isEnabled() || AdaptConfig.get().blacklistedWorlds.contains(world.getName()); } catch (Exception ignored) { @@ -237,6 +237,7 @@ public AdaptAdvancement buildAdvancements() { .title(displayName) .description(getDescription()) .icon(getIcon()) + .model(getModel()) .children(a) .visibility(AdvancementVisibility.HIDDEN) .build(); diff --git a/src/main/java/com/volmit/adapt/api/skill/Skill.java b/src/main/java/com/volmit/adapt/api/skill/Skill.java index 6bcb7bdd..757eff9e 100644 --- a/src/main/java/com/volmit/adapt/api/skill/Skill.java +++ b/src/main/java/com/volmit/adapt/api/skill/Skill.java @@ -94,7 +94,7 @@ default void checkStatTrackers(AdaptPlayer player) { void onRegisterAdvancements(List advancements); - default boolean hasBlacklistPermission(Player p, Skill s) { + default boolean hasBlacklistPermission(Player p, Skill s) { if (p.isOp()) { // If the player is an operator, bypass the permission check return false; } @@ -124,6 +124,10 @@ default String getDisplayName(int level) { return getDisplayName() + C.RESET + " " + C.UNDERLINE + C.WHITE + level + C.RESET; } + default CustomModel getModel() { + return CustomModel.get(getIcon(), "skill", getName()); + } + default void xp(Player p, double xp) { if (!p.getClass().getSimpleName().equals("CraftPlayer")) { return; @@ -211,11 +215,14 @@ default void openGui(Player player) { spw.play(player.getLocation(), Sound.ITEM_BOOK_PAGE_TURN, 0.3f, 1.855f); Window w = new UIWindow(player); w.setTag("skill/" + getName()); - w.setDecorator((window, position, row) -> new UIElement("bg").setName(" ").setMaterial(new MaterialBlock(Material.BLACK_STAINED_GLASS_PANE))); + w.setDecorator((window, position, row) -> new UIElement("bg") + .setName(" ") + .setMaterial(new MaterialBlock(Material.BLACK_STAINED_GLASS_PANE)) + .setModel(CustomModel.get(Material.BLACK_STAINED_GLASS_PANE, "snippets", "gui", "background"))); int ind = 0; - for (Adaptation i : getAdaptations()) { + for (Adaptation i : getAdaptations()) { if (i.hasBlacklistPermission(player, i)) { continue; } @@ -224,14 +231,12 @@ default void openGui(Player player) { int lvl = getPlayer(player).getData().getSkillLine(getName()).getAdaptationLevel(i.getName()); w.setElement(pos, row, new UIElement("ada-" + i.getName()) .setMaterial(new MaterialBlock(i.getIcon())) + .setModel(i.getModel()) .setName(i.getDisplayName(lvl)) .addLore(Form.wrapWordsPrefixed(i.getDescription(), "" + C.GRAY, 45)) // Set to the actual Description .addLore(lvl == 0 ? (C.DARK_GRAY + Localizer.dLocalize("snippets", "gui", "notlearned")) : (C.GRAY + Localizer.dLocalize("snippets", "gui", "level") + " " + C.WHITE + Form.toRoman(lvl))) .setProgress(1D) - .onLeftClick((e) -> { - w.close(); - i.openGui(player); - })); + .onLeftClick((e) -> i.openGui(player))); ind++; } @@ -241,11 +246,9 @@ default void openGui(Player player) { if (w.getElement(backPos, backRow) != null) backRow++; w.setElement(backPos, backRow, new UIElement("back") .setMaterial(new MaterialBlock(Material.RED_BED)) + .setModel(CustomModel.get(Material.RED_BED, "snippets", "gui", "back")) .setName("" + C.RESET + C.GRAY + Localizer.dLocalize("snippets", "gui", "back")) - .onLeftClick((e) -> { - w.close(); - onGuiClose(player, true); - })); + .onLeftClick((e) -> onGuiClose(player, true))); } AdaptPlayer a = Adapt.instance.getAdaptServer().getPlayer(player); @@ -262,6 +265,8 @@ private void onGuiClose(Player player, boolean openPrevGui) { spw.play(player.getLocation(), Sound.ITEM_BOOK_PAGE_TURN, 0.3f, 1.855f); if (openPrevGui) { SkillsGui.open(player); + } else { + Adapt.instance.getGuiLeftovers().remove(player.getUniqueId().toString()); } } } diff --git a/src/main/java/com/volmit/adapt/api/version/IAttribute.java b/src/main/java/com/volmit/adapt/api/version/IAttribute.java index e1c2d50f..669f42d5 100644 --- a/src/main/java/com/volmit/adapt/api/version/IAttribute.java +++ b/src/main/java/com/volmit/adapt/api/version/IAttribute.java @@ -1,20 +1,53 @@ package com.volmit.adapt.api.version; +import com.volmit.adapt.util.collection.KList; +import lombok.*; import org.bukkit.NamespacedKey; import org.bukkit.attribute.AttributeModifier; +import java.util.Optional; import java.util.UUID; public interface IAttribute { - default void setAttributeModifier(UUID uuid, NamespacedKey key, double amount, AttributeModifier.Operation operation) { - removeAttributeModifier(uuid, key); - addAttributeModifier(uuid, key, amount, operation); + double getValue(); + + double getDefaultValue(); + + double getBaseValue(); + + void setBaseValue(double baseValue); + + default void setModifier(UUID uuid, NamespacedKey key, double amount, AttributeModifier.Operation operation) { + removeModifier(uuid, key); + addModifier(uuid, key, amount, operation); } - void addAttributeModifier(UUID uuid, NamespacedKey key, double amount, AttributeModifier.Operation operation); + void addModifier(UUID uuid, NamespacedKey key, double amount, AttributeModifier.Operation operation); + + boolean hasModifier(UUID uuid, NamespacedKey key); - boolean hasAttributeModifier(UUID uuid, NamespacedKey key); + void removeModifier(UUID uuid, NamespacedKey key); - void removeAttributeModifier(UUID uuid, NamespacedKey key); + KList getModifier(UUID uuid, NamespacedKey key); + + @ToString + @EqualsAndHashCode + @AllArgsConstructor + class Modifier { + private final UUID uuid; + private final NamespacedKey key; + @Getter + private final double amount; + @Getter + private final AttributeModifier.Operation operation; + + public Optional getUUID() { + return Optional.ofNullable(uuid); + } + + public Optional getKey() { + return Optional.ofNullable(key); + } + } } diff --git a/src/main/java/com/volmit/adapt/api/version/IBindings.java b/src/main/java/com/volmit/adapt/api/version/IBindings.java index 4827fd5f..d147cae6 100644 --- a/src/main/java/com/volmit/adapt/api/version/IBindings.java +++ b/src/main/java/com/volmit/adapt/api/version/IBindings.java @@ -1,17 +1,21 @@ package com.volmit.adapt.api.version; import com.volmit.adapt.api.potion.PotionBuilder; +import org.bukkit.attribute.Attributable; import org.bukkit.attribute.Attribute; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.Listener; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.PotionMeta; +import org.jetbrains.annotations.Unmodifiable; +import java.util.List; import java.util.function.Consumer; public interface IBindings extends Listener { - IAttribute getAttribute(Player player, Attribute modifier); + IAttribute getAttribute(Attributable attributable, Attribute modifier); void addEntityMountListener(Consumer consumer); @@ -29,4 +33,7 @@ default ItemStack buildPotion(PotionBuilder builder) { stack.setItemMeta(meta); return stack; } + + @Unmodifiable + List getInvalidDamageableEntities(); } diff --git a/src/main/java/com/volmit/adapt/api/version/Version.java b/src/main/java/com/volmit/adapt/api/version/Version.java index 7c32bb77..5706ed47 100644 --- a/src/main/java/com/volmit/adapt/api/version/Version.java +++ b/src/main/java/com/volmit/adapt/api/version/Version.java @@ -1,23 +1,35 @@ package com.volmit.adapt.api.version; import org.bukkit.Bukkit; +import org.bukkit.inventory.InventoryView; import org.jetbrains.annotations.NotNull; import java.util.List; public class Version { private static final List BINDINGS = List.of( + of("1.21.2"), of("1.21"), of("1.20.5"), of("1.20.4"), of("1.19.2") ); private static final IBindings bindings = bind(); + public static final boolean SET_TITLE; public static IBindings get() { return bindings; } + static { + boolean titleMethod = false; + try { + InventoryView.class.getDeclaredMethod("setTitle", String.class); + titleMethod = true; + } catch (Throwable ignored) {} + SET_TITLE = titleMethod; + } + private static IBindings bind() { Entry entry = of(Bukkit.getServer().getBukkitVersion().split("-")[0]); Entry version = BINDINGS.stream() diff --git a/src/main/java/com/volmit/adapt/api/world/AdaptPlayer.java b/src/main/java/com/volmit/adapt/api/world/AdaptPlayer.java index a3bc4a19..22f6fa9f 100644 --- a/src/main/java/com/volmit/adapt/api/world/AdaptPlayer.java +++ b/src/main/java/com/volmit/adapt/api/world/AdaptPlayer.java @@ -30,6 +30,7 @@ import lombok.EqualsAndHashCode; import lombok.SneakyThrows; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.util.Vector; @@ -286,9 +287,12 @@ public void loggedIn() { } double boostAmount = M.lerp(0.1, 0.25, (double) boostTime / (double) TimeUnit.HOURS.toMillis(1)); getData().globalXPMultiplier(boostAmount, (int) boostTime); + if (!AdaptConfig.get().isWelcomeMessage()) + return; getNot().queue(AdvancementNotification.builder() .title(first ? Localizer.dLocalize("snippets", "gui", "welcome") : Localizer.dLocalize("snippets", "gui", "welcomeback")) .description("+" + C.GREEN + Form.pc(boostAmount, 0) + C.GRAY + " " + Localizer.dLocalize("snippets", "gui", "xpbonusfortime") + " " + C.AQUA + Form.duration(boostTime, 0)) + .model(CustomModel.get(Material.DIAMOND, "snippets", "gui", first ? "welcome" : "welcomeback")) .build()); } } diff --git a/src/main/java/com/volmit/adapt/api/world/AdaptServer.java b/src/main/java/com/volmit/adapt/api/world/AdaptServer.java index 3f1b50cb..5382a669 100644 --- a/src/main/java/com/volmit/adapt/api/world/AdaptServer.java +++ b/src/main/java/com/volmit/adapt/api/world/AdaptServer.java @@ -50,22 +50,22 @@ import java.io.File; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.ReentrantLock; public class AdaptServer extends TickedObject { - private final Map players; + private final ReentrantLock clearLock = new ReentrantLock(); + private final Map players = new ConcurrentHashMap<>(); @Getter - private final List spatialTickets; + private final List spatialTickets = new ArrayList<>(); @Getter - private SkillRegistry skillRegistry; + private final SkillRegistry skillRegistry = new SkillRegistry(); @Getter private AdaptServerData data = new AdaptServerData(); public AdaptServer() { super("core", UUID.randomUUID().toString(), 1000); - spatialTickets = new ArrayList<>(); - players = new HashMap<>(); load(); - skillRegistry = new SkillRegistry(); Bukkit.getOnlinePlayers().forEach(this::join); } @@ -145,6 +145,7 @@ public void on(ProjectileLaunchEvent e) { .build().play(getPlayer(p)); getPlayer(p).getNot().queue(AdvancementNotification.builder() .icon(Material.BOOK) + .model(CustomModel.get(Material.BOOK, "snippets", "gui", "knowledge")) .title(C.GRAY + "+ " + C.WHITE + data.getKnowledge() + " " + skill.getDisplayName() + " Knowledge") .build()); e.setCancelled(false); @@ -200,12 +201,19 @@ public void on(CraftItemEvent e) { @Override public void onTick() { synchronized (spatialTickets) { - for (int i = 0; i < spatialTickets.size(); i++) { - if (M.ms() > spatialTickets.get(i).getMs()) { - spatialTickets.remove(i); - } - } + spatialTickets.removeIf(ticket -> M.ms() > ticket.getMs()); } + + J.a(() -> { + if (!clearLock.tryLock()) + return; + + try { + players.keySet().removeIf(player -> !player.isOnline()); + } finally { + clearLock.unlock(); + } + }); } public PlayerData peekData(UUID player) { @@ -233,7 +241,11 @@ public PlayerData peekData(UUID player) { } public AdaptPlayer getPlayer(Player p) { - return players.get(p); + return players.computeIfAbsent(p, player -> { + Adapt.warn("Failed to find AdaptPlayer for " + p.getName() + " (" + p.getUniqueId() + ")"); + Adapt.warn("Loading new AdaptPlayer..."); + return new AdaptPlayer(player); + }); } public void openSkillGUI(Skill skill, Player p) { diff --git a/src/main/java/com/volmit/adapt/api/world/PlayerData.java b/src/main/java/com/volmit/adapt/api/world/PlayerData.java index 33ee2e40..37dcc600 100644 --- a/src/main/java/com/volmit/adapt/api/world/PlayerData.java +++ b/src/main/java/com/volmit/adapt/api/world/PlayerData.java @@ -33,7 +33,6 @@ import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.World; -import org.bukkit.block.Biome; import org.bukkit.entity.EntityType; import java.util.*; @@ -45,7 +44,7 @@ public class PlayerData { private Map stats = new HashMap<>(); private String last = "none"; private Set advancements = new HashSet<>(); - private Discovery seenBiomes = new Discovery<>(); + private Discovery seenBiomes = new Discovery<>(); private Discovery seenMobs = new Discovery<>(); private Discovery seenFoods = new Discovery<>(); private Discovery seenItems = new Discovery<>(); diff --git a/src/main/java/com/volmit/adapt/api/world/PlayerSkillLine.java b/src/main/java/com/volmit/adapt/api/world/PlayerSkillLine.java index e19d5ad7..47038dfc 100644 --- a/src/main/java/com/volmit/adapt/api/world/PlayerSkillLine.java +++ b/src/main/java/com/volmit/adapt/api/world/PlayerSkillLine.java @@ -182,7 +182,7 @@ public void setAdaptation(Adaptation a, int level) { adaptations.put(a.getName(), v); } - public Skill getRawSkill(AdaptPlayer p) { + public Skill getRawSkill(AdaptPlayer p) { return p.getServer().getSkillRegistry().getSkill(line); } diff --git a/src/main/java/com/volmit/adapt/command/CommandAdapt.java b/src/main/java/com/volmit/adapt/command/CommandAdapt.java index 1397b52c..6d97b62c 100644 --- a/src/main/java/com/volmit/adapt/command/CommandAdapt.java +++ b/src/main/java/com/volmit/adapt/command/CommandAdapt.java @@ -35,7 +35,7 @@ public void boost( ) { if (!sender().hasPermission("adapt.boost")) { - sender().sendMessage("You lack the Permission 'adapt.boost'"); + FConst.error("You lack the Permission 'adapt.boost'").send(sender()); return; } @@ -59,7 +59,7 @@ public void gui( boolean force ) { if (!sender().hasPermission("adapt.gui")) { - sender().sendMessage("You lack the Permission 'adapt.gui'"); + FConst.error("You lack the Permission 'adapt.gui'").send(sender()); return; } @@ -115,7 +115,7 @@ public void experience( ) { if (!sender().hasPermission("adapt.cheatitem")) { - sender().sendMessage("You lack the Permission 'adapt.cheatitem'"); + FConst.error("You lack the Permission 'adapt.cheatitem'").send(sender()); return; } @@ -163,7 +163,7 @@ public void knowledge( Player player ) { if (!sender().hasPermission("adapt.cheatitem")) { - sender().sendMessage("You lack the Permission 'adapt.cheatitem'"); + FConst.error("You lack the Permission 'adapt.cheatitem'").send(sender()); return; } Player targetPlayer = player; @@ -215,7 +215,7 @@ public void determine( ) { if (!sender().hasPermission("adapt.determine")) { - sender().sendMessage("You lack the Permission 'adapt.determine'"); + FConst.error("You lack the Permission 'adapt.determine'").send(sender()); return; } diff --git a/src/main/java/com/volmit/adapt/command/CommandDebug.java b/src/main/java/com/volmit/adapt/command/CommandDebug.java index c788da0d..0d3720ba 100644 --- a/src/main/java/com/volmit/adapt/command/CommandDebug.java +++ b/src/main/java/com/volmit/adapt/command/CommandDebug.java @@ -19,7 +19,7 @@ public class CommandDebug implements DecreeExecutor { @Decree(description = "Toggle verbose mode") public void verbose() { if (!sender().hasPermission("adapt.idontknowwhatimdoingiswear")) { - sender().sendMessage("You lack the Permission 'adapt.idontknowwhatimdoingiswear'"); + FConst.error("You lack the Permission 'adapt.idontknowwhatimdoingiswear'").send(sender()); return; } @@ -30,7 +30,7 @@ public void verbose() { @Decree(name = "pap", description = "Generate Perms for Adaptations!") public void pap() { if (!sender().hasPermission("adapt.idontknowwhatimdoingiswear")) { - sender().sendMessage("You lack the Permission 'adapt.idontknowwhatimdoingiswear'"); + FConst.error("You lack the Permission 'adapt.idontknowwhatimdoingiswear'").send(sender()); return; } @@ -47,7 +47,7 @@ public void pap() { @Decree(name = "psp", description = "Generate Perms for Skills!") public void psp() { if (!sender().hasPermission("adapt.idontknowwhatimdoingiswear")) { - sender().sendMessage("You lack the Permission 'adapt.idontknowwhatimdoingiswear'"); + FConst.error("You lack the Permission 'adapt.idontknowwhatimdoingiswear'").send(sender()); return; } @@ -64,7 +64,7 @@ public void psp() { @Decree(name = "particle", origin = DecreeOrigin.PLAYER, description = "Summon a particle in front of you for testing!") public void particle(@Param Particle particle) { if (!sender().hasPermission("adapt.idontknowwhatimdoingiswear")) { - sender().sendMessage("You lack the Permission 'adapt.idontknowwhatimdoingiswear'"); + FConst.error("You lack the Permission 'adapt.idontknowwhatimdoingiswear'").send(sender()); return; } @@ -75,7 +75,7 @@ public void particle(@Param Particle particle) { @Decree(name = "particle", origin = DecreeOrigin.PLAYER, description = "Summon a particle in front of you for testing!") public void particle(@Param Sound sound) { if (!sender().hasPermission("adapt.idontknowwhatimdoingiswear")) { - sender().sendMessage("You lack the Permission 'adapt.idontknowwhatimdoingiswear'"); + FConst.error("You lack the Permission 'adapt.idontknowwhatimdoingiswear'").send(sender()); return; } diff --git a/src/main/java/com/volmit/adapt/content/adaptation/agility/AgilityArmorUp.java b/src/main/java/com/volmit/adapt/content/adaptation/agility/AgilityArmorUp.java index 4d2d93d6..9a56ec4c 100644 --- a/src/main/java/com/volmit/adapt/content/adaptation/agility/AgilityArmorUp.java +++ b/src/main/java/com/volmit/adapt/content/adaptation/agility/AgilityArmorUp.java @@ -22,12 +22,12 @@ import com.volmit.adapt.api.adaptation.SimpleAdaptation; import com.volmit.adapt.api.version.Version; import com.volmit.adapt.util.*; +import com.volmit.adapt.util.reflect.enums.Attributes; import lombok.NoArgsConstructor; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.Particle; -import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeModifier; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -79,11 +79,11 @@ private double getWindupArmor(double factor) { @Override public void onTick() { for (Player p : Bukkit.getOnlinePlayers()) { - var attribute = Version.get().getAttribute(p, Attribute.GENERIC_ARMOR); + var attribute = Version.get().getAttribute(p, Attributes.GENERIC_ARMOR); if (attribute == null) continue; try { - attribute.removeAttributeModifier(MODIFIER, MODIFIER_KEY); + attribute.removeModifier(MODIFIER, MODIFIER_KEY); } catch (Exception e) { Adapt.verbose("Failed to remove windup modifier: " + e.getMessage()); } @@ -121,7 +121,7 @@ public void onTick() { p.getWorld().spawnParticle(Particle.WAX_ON, p.getLocation(), 1, 0, 0, 0, 0); } } - attribute.setAttributeModifier(MODIFIER, MODIFIER_KEY, armorInc * 10, AttributeModifier.Operation.MULTIPLY_SCALAR_1); + attribute.setModifier(MODIFIER, MODIFIER_KEY, armorInc * 10, AttributeModifier.Operation.MULTIPLY_SCALAR_1); } else { ticksRunning.remove(p); } diff --git a/src/main/java/com/volmit/adapt/content/adaptation/agility/AgilityWindUp.java b/src/main/java/com/volmit/adapt/content/adaptation/agility/AgilityWindUp.java index aa8b9665..b109bc0b 100644 --- a/src/main/java/com/volmit/adapt/content/adaptation/agility/AgilityWindUp.java +++ b/src/main/java/com/volmit/adapt/content/adaptation/agility/AgilityWindUp.java @@ -22,12 +22,12 @@ import com.volmit.adapt.api.adaptation.SimpleAdaptation; import com.volmit.adapt.api.version.Version; import com.volmit.adapt.util.*; +import com.volmit.adapt.util.reflect.enums.Attributes; import lombok.NoArgsConstructor; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.Particle; -import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeModifier; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -81,11 +81,11 @@ private double getWindupSpeed(double factor) { @Override public void onTick() { for (Player p : Bukkit.getOnlinePlayers()) { - var attribute = Version.get().getAttribute(p, Attribute.GENERIC_MOVEMENT_SPEED); + var attribute = Version.get().getAttribute(p, Attributes.GENERIC_MOVEMENT_SPEED); if (attribute == null) continue; try { - attribute.removeAttributeModifier(MODIFIER, MODIFIER_KEY); + attribute.removeModifier(MODIFIER, MODIFIER_KEY); } catch (Exception e) { Adapt.verbose("Failed to remove windup modifier: " + e.getMessage()); } @@ -119,7 +119,7 @@ public void onTick() { p.getWorld().spawnParticle(Particle.FLAME, p.getLocation(), 1, 0, 0, 0, 0); } } - attribute.setAttributeModifier(MODIFIER, MODIFIER_KEY, speedIncrease, AttributeModifier.Operation.MULTIPLY_SCALAR_1); + attribute.setModifier(MODIFIER, MODIFIER_KEY, speedIncrease, AttributeModifier.Operation.MULTIPLY_SCALAR_1); } else { ticksRunning.remove(p); } diff --git a/src/main/java/com/volmit/adapt/content/adaptation/discovery/DiscoveryArmor.java b/src/main/java/com/volmit/adapt/content/adaptation/discovery/DiscoveryArmor.java index 62513ca5..369153ae 100644 --- a/src/main/java/com/volmit/adapt/content/adaptation/discovery/DiscoveryArmor.java +++ b/src/main/java/com/volmit/adapt/content/adaptation/discovery/DiscoveryArmor.java @@ -19,30 +19,42 @@ package com.volmit.adapt.content.adaptation.discovery; import com.volmit.adapt.api.adaptation.SimpleAdaptation; +import com.volmit.adapt.api.version.IAttribute; +import com.volmit.adapt.api.version.Version; import com.volmit.adapt.util.*; +import com.volmit.adapt.util.collection.KMap; +import com.volmit.adapt.util.reflect.enums.Attributes; import com.volmit.adapt.util.reflect.enums.Particles; import lombok.NoArgsConstructor; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; -import org.bukkit.attribute.Attribute; -import org.bukkit.attribute.AttributeInstance; +import org.bukkit.NamespacedKey; import org.bukkit.attribute.AttributeModifier; import org.bukkit.block.Block; import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.util.Vector; -import java.util.ArrayList; -import java.util.Collection; +import java.util.UUID; +import java.util.concurrent.TimeUnit; public class DiscoveryArmor extends SimpleAdaptation { + private static final UUID MODIFIER = UUID.nameUUIDFromBytes("adapt-discovery-armor".getBytes()); + private static final NamespacedKey MODIFIER_KEY = NamespacedKey.fromString( "adapt:discovery-armor"); + private static final long UPDATE_COOLDOWN = TimeUnit.SECONDS.toMillis(3); + private static final Sphere SPHERE = new Sphere(5); + + private final KMap playerData = new KMap<>(); + public DiscoveryArmor() { super("discovery-world-armor"); registerConfiguration(Config.class); setDescription(Localizer.dLocalize("discovery", "armor", "description")); setDisplayName(Localizer.dLocalize("discovery", "armor", "name")); setIcon(Material.TURTLE_HELMET); - setInterval(1305); + setInterval(305); setBaseCost(getConfig().baseCost); setInitialCost(getConfig().initialCost); setCostFactor(getConfig().costFactor); @@ -63,34 +75,30 @@ public double getArmor(Location l, int level) { Block center = l.getBlock(); double armorValue = 0.0; double count = 0; - int r = 5; - - for (int x = -r; x <= r; x++) { - for (int y = -r; y <= r; y++) { - for (int z = -r; z <= r; z++) { - Block b = center.getRelative(x, y, z); - if (center.getLocation().distanceSquared(b.getLocation()) <= r * r) { - if (b.getType() != Material.AIR && !b.isLiquid()) { - count++; - double a = getArmorPoints(b.getType()); - if (Double.isNaN(a) || a < 0) { - a = 0; - } - armorValue += a; - - if (a > 2 && M.r(0.005 * a)) { - Vector v = VectorMath.directionNoNormal(l, b.getLocation().add(0.5, 0.5, 0.5)); - if (getConfig().showParticles) { - l.getWorld().spawnParticle(Particles.ENCHANTMENT_TABLE, l.clone().add(0, 1, 0), 0, v.getX(), v.getY(), v.getZ()); - } - } - } - } + + var sphere = SPHERE.clone(); + + while (sphere.hasNext()) { + var r = sphere.next(); + Block b = center.getRelative(r.getX(), r.getY(), r.getZ()); + if (b.isEmpty() || b.isLiquid()) + continue; + + count++; + double a = getArmorPoints(b.getType()); + if (Double.isNaN(a) || a < 0) { + a = 0; + } + armorValue += a; + + if (a > 2 && M.r(0.005 * a)) { + Vector v = VectorMath.directionNoNormal(l, b.getLocation().add(0.5, 0.5, 0.5)); + if (getConfig().showParticles) { + l.getWorld().spawnParticle(Particles.ENCHANTMENT_TABLE, l.clone().add(0, 1, 0), 0, v.getX(), v.getY(), v.getZ()); } } } - return Math.min((armorValue / count) * (level / 2D) * 0.65, 10); } @@ -106,44 +114,46 @@ private double getStrength(double factor) { @Override public void onTick() { - for (Player p : Bukkit.getOnlinePlayers()) { - if (p == null || !p.isOnline()) { - continue; - } - AttributeInstance armorAttribute = p.getAttribute(Attribute.GENERIC_ARMOR); - if (armorAttribute == null) { - continue; - } - Collection c = armorAttribute.getModifiers(); - if (c == null || c.isEmpty()) { - continue; - } - - if (!hasAdaptation(p)) { - for (AttributeModifier i : new ArrayList<>(c)) { - if (i.getName().equals("adapt-discovery-armor")) { - armorAttribute.removeModifier(i); - } - } - } else { - double oldArmor = 0; - double armor = getArmor(p.getLocation(), getLevel(p)); - armor = Double.isNaN(armor) ? 0 : armor; - - for (AttributeModifier i : new ArrayList<>(c)) { - if (i.getName().equals("adapt-discovery-armor")) { - oldArmor = i.getAmount(); - oldArmor = Double.isNaN(oldArmor) ? 0 : oldArmor; - armorAttribute.removeModifier(i); - } + var players = Bukkit.getOnlinePlayers(); + var executor = MultiBurst.burst.burst(players.size()); + + for (Player p : players) { + executor.queue(() -> { + if (p == null || !p.isOnline()) return; + + long now = M.ms(); + var nextUpdate = playerData.getOrDefault(p.getUniqueId(), now); + if (nextUpdate > now) return; + playerData.put(p.getUniqueId(), now + UPDATE_COOLDOWN); + + var attribute = Version.get().getAttribute(p, Attributes.GENERIC_ARMOR); + if (attribute == null) return; + + if (!hasAdaptation(p)) { + attribute.removeModifier(MODIFIER, MODIFIER_KEY); + } else { + double oldArmor = attribute.getModifier(MODIFIER, MODIFIER_KEY) + .stream() + .mapToDouble(IAttribute.Modifier::getAmount) + .max() + .orElse(0); + + double armor = getArmor(p.getLocation(), getLevel(p)); + armor = Double.isNaN(armor) ? 0 : armor; + + double lArmor = M.lerp(oldArmor, armor, 0.3); + lArmor = Double.isNaN(lArmor) ? 0 : lArmor; + attribute.setModifier(MODIFIER, MODIFIER_KEY, lArmor, AttributeModifier.Operation.ADD_NUMBER); } - double lArmor = M.lerp(oldArmor, armor, 0.3); - lArmor = Double.isNaN(lArmor) ? 0 : lArmor; - armorAttribute.addModifier(new AttributeModifier("adapt-discovery-armor", lArmor, AttributeModifier.Operation.ADD_NUMBER)); - } + }); } + executor.complete(); } + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + playerData.remove(event.getPlayer().getUniqueId()); + } @Override public boolean isEnabled() { diff --git a/src/main/java/com/volmit/adapt/content/adaptation/excavation/ExcavationSpelunker.java b/src/main/java/com/volmit/adapt/content/adaptation/excavation/ExcavationSpelunker.java index c787f991..44a282eb 100644 --- a/src/main/java/com/volmit/adapt/content/adaptation/excavation/ExcavationSpelunker.java +++ b/src/main/java/com/volmit/adapt/content/adaptation/excavation/ExcavationSpelunker.java @@ -21,9 +21,9 @@ import com.volmit.adapt.Adapt; import com.volmit.adapt.api.adaptation.SimpleAdaptation; import com.volmit.adapt.content.item.ItemListings; -import com.volmit.adapt.nms.GlowingEntities; import com.volmit.adapt.util.*; import com.volmit.adapt.util.reflect.enums.Particles; +import fr.skytasul.glowingentities.GlowingEntities; import lombok.NoArgsConstructor; import org.bukkit.*; import org.bukkit.block.Block; diff --git a/src/main/java/com/volmit/adapt/content/adaptation/pickaxe/PickaxeSilkSpawner.java b/src/main/java/com/volmit/adapt/content/adaptation/pickaxe/PickaxeSilkSpawner.java new file mode 100644 index 00000000..ac8441b4 --- /dev/null +++ b/src/main/java/com/volmit/adapt/content/adaptation/pickaxe/PickaxeSilkSpawner.java @@ -0,0 +1,87 @@ +package com.volmit.adapt.content.adaptation.pickaxe; + +import com.volmit.adapt.api.adaptation.SimpleAdaptation; +import com.volmit.adapt.util.C; +import com.volmit.adapt.util.Element; +import com.volmit.adapt.util.Localizer; +import com.volmit.adapt.util.collection.KList; +import lombok.NoArgsConstructor; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Item; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockDropItemEvent; +import org.bukkit.inventory.ItemStack; + +public class PickaxeSilkSpawner extends SimpleAdaptation { + + public PickaxeSilkSpawner() { + super("pickaxe-silk-spawner"); + registerConfiguration(PickaxeSilkSpawner.Config.class); + setDescription(Localizer.dLocalize("pickaxe", "silkspawner", "description")); + setDisplayName(Localizer.dLocalize("pickaxe", "silkspawner", "name")); + setIcon(Material.SPAWNER); + setBaseCost(getConfig().baseCost); + setMaxLevel(getConfig().maxLevel); + setInitialCost(getConfig().initialCost); + setCostFactor(getConfig().costFactor); + setInterval(8444); + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onBlockBreak(BlockBreakEvent event) { + var player = event.getPlayer(); + var block = event.getBlock(); + if (!event.isDropItems() || !hasAdaptation(player) || block.getType() != Material.SPAWNER || !canBlockBreak(player, event.getBlock().getLocation())) + return; + var level = getLevel(player); + if (level == 1 && !player.getInventory().getItemInMainHand().getEnchantments().containsKey(Enchantment.SILK_TOUCH)) { + return; + } else if (level > 1 && !player.isSneaking()) { + return; + } + + event.setDropItems(false); + var items = new KList(); + block.getWorld().dropItemNaturally(block.getLocation(), new ItemStack(Material.SPAWNER), items::add); + + var dropEvent = new BlockDropItemEvent(block, block.getState(), player, items); + Bukkit.getPluginManager().callEvent(dropEvent); + if (dropEvent.isCancelled() && !items.isEmpty()) { + items.forEach(Item::remove); + items.clear(); + } + } + + @Override + public boolean isEnabled() { + return getConfig().enabled; + } + + @Override + public void addStats(int level, Element v) { + v.addLore(C.GREEN + Localizer.dLocalize("pickaxe", "silkspawner", "lore" + (level < 2 ? 1 : 2))); + } + + @Override + public void onTick() { + } + + @Override + public boolean isPermanent() { + return getConfig().permanent; + } + + @NoArgsConstructor + protected static class Config { + boolean permanent = false; + boolean enabled = true; + int baseCost = 6; + int maxLevel = 2; + int initialCost = 4; + double costFactor = 2.325; + } +} diff --git a/src/main/java/com/volmit/adapt/content/adaptation/stealth/StealthGhostArmor.java b/src/main/java/com/volmit/adapt/content/adaptation/stealth/StealthGhostArmor.java index d16ee71f..0ea94dd6 100644 --- a/src/main/java/com/volmit/adapt/content/adaptation/stealth/StealthGhostArmor.java +++ b/src/main/java/com/volmit/adapt/content/adaptation/stealth/StealthGhostArmor.java @@ -19,21 +19,26 @@ package com.volmit.adapt.content.adaptation.stealth; import com.volmit.adapt.api.adaptation.SimpleAdaptation; +import com.volmit.adapt.api.version.IAttribute; +import com.volmit.adapt.api.version.Version; import com.volmit.adapt.util.*; +import com.volmit.adapt.util.reflect.enums.Attributes; import lombok.NoArgsConstructor; import org.bukkit.Bukkit; import org.bukkit.Material; -import org.bukkit.attribute.Attribute; +import org.bukkit.NamespacedKey; import org.bukkit.attribute.AttributeModifier; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityDamageEvent; -import java.util.ArrayList; -import java.util.Collection; +import java.util.UUID; public class StealthGhostArmor extends SimpleAdaptation { + private static final UUID MODIFIER = UUID.nameUUIDFromBytes("adapt-ghost-armor".getBytes()); + private static final NamespacedKey MODIFIER_KEY = NamespacedKey.fromString( "adapt:ghost-armor"); + public StealthGhostArmor() { super("stealth-ghost-armor"); registerConfiguration(Config.class); @@ -64,42 +69,25 @@ public double getMaxArmorPerTick(double factor) { @Override public void onTick() { for (Player p : Bukkit.getOnlinePlayers()) { + var attribute = Version.get().getAttribute(p, Attributes.GENERIC_ARMOR); + if (!hasAdaptation(p)) { - Collection c = p.getAttribute(Attribute.GENERIC_ARMOR).getModifiers(); - for (AttributeModifier i : new ArrayList<>(c)) { - if (i.getName().equals("adapt-ghost-armor")) { - p.getAttribute(Attribute.GENERIC_ARMOR).removeModifier(i); - } - } + attribute.removeModifier(MODIFIER, MODIFIER_KEY); continue; } - double oldArmor = 0; + double oldArmor = attribute.getModifier(MODIFIER, MODIFIER_KEY) + .stream() + .mapToDouble(IAttribute.Modifier::getAmount) + .filter(d -> !Double.isNaN(d)) + .max() + .orElse(0);; double armor = getMaxArmorPoints(getLevelPercent(p)); armor = Double.isNaN(armor) ? 0 : armor; - if (oldArmor < armor) { - Collection c = p.getAttribute(Attribute.GENERIC_ARMOR).getModifiers(); - for (AttributeModifier i : new ArrayList<>(c)) { - if (i.getName().equals("adapt-ghost-armor")) { - oldArmor = i.getAmount(); - oldArmor = Double.isNaN(oldArmor) ? 0 : oldArmor; - p.getAttribute(Attribute.GENERIC_ARMOR).removeModifier(i); - } - } - p.getAttribute(Attribute.GENERIC_ARMOR) - .addModifier(new AttributeModifier("adapt-ghost-armor", Math.min(armor, oldArmor + getMaxArmorPerTick(getLevelPercent(p))), AttributeModifier.Operation.ADD_NUMBER)); + attribute.setModifier(MODIFIER, MODIFIER_KEY, Math.min(armor, oldArmor + getMaxArmorPerTick(getLevelPercent(p))), AttributeModifier.Operation.ADD_NUMBER); } else if (oldArmor > armor) { - Collection c = p.getAttribute(Attribute.GENERIC_ARMOR).getModifiers(); - for (AttributeModifier i : new ArrayList<>(c)) { - if (i.getName().equals("adapt-ghost-armor")) { - oldArmor = i.getAmount(); - oldArmor = Double.isNaN(oldArmor) ? 0 : oldArmor; - p.getAttribute(Attribute.GENERIC_ARMOR).removeModifier(i); - } - } - p.getAttribute(Attribute.GENERIC_ARMOR) - .addModifier(new AttributeModifier("adapt-ghost-armor", armor, AttributeModifier.Operation.ADD_NUMBER)); + attribute.setModifier(MODIFIER, MODIFIER_KEY, armor, AttributeModifier.Operation.ADD_NUMBER); } } } @@ -114,12 +102,9 @@ public void on(EntityDamageEvent e) { int damageXP = (int) Math.min(10, 2.5 * e.getDamage()); xp(p,damageXP ); J.s(() -> { - Collection c = p.getAttribute(Attribute.GENERIC_ARMOR).getModifiers(); - for (AttributeModifier i : new ArrayList<>(c)) { - if (i.getName().equals("adapt-ghost-armor")) { - p.getAttribute(Attribute.GENERIC_ARMOR).removeModifier(i); - } - } + var attribute = Version.get().getAttribute(p, Attributes.GENERIC_ARMOR); + if (attribute == null) return; + attribute.removeModifier(MODIFIER, MODIFIER_KEY); }); } } diff --git a/src/main/java/com/volmit/adapt/content/adaptation/taming/TamingDamage.java b/src/main/java/com/volmit/adapt/content/adaptation/taming/TamingDamage.java index 70b8745e..ec0ccd87 100644 --- a/src/main/java/com/volmit/adapt/content/adaptation/taming/TamingDamage.java +++ b/src/main/java/com/volmit/adapt/content/adaptation/taming/TamingDamage.java @@ -19,12 +19,14 @@ package com.volmit.adapt.content.adaptation.taming; import com.volmit.adapt.api.adaptation.SimpleAdaptation; +import com.volmit.adapt.api.version.Version; import com.volmit.adapt.util.*; +import com.volmit.adapt.util.reflect.enums.Attributes; import lombok.NoArgsConstructor; import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.NamespacedKey; import org.bukkit.World; -import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeModifier; import org.bukkit.entity.Player; import org.bukkit.entity.Tameable; @@ -33,9 +35,8 @@ import java.util.UUID; public class TamingDamage extends SimpleAdaptation { - private final UUID attUUID = UUID.nameUUIDFromBytes("tame-damage-boost".getBytes()); - private final String attid = "att-tame-damage-boost"; - + private static final UUID MODIFIER = UUID.nameUUIDFromBytes("adapt-tame-damage-boost".getBytes()); + private static final NamespacedKey MODIFIER_KEY = NamespacedKey.fromString( "adapt:tame-damage-boost"); public TamingDamage() { super("tame-damage"); @@ -77,15 +78,12 @@ public void onTick() { } private void update(Tameable j, int level) { - AttributeModifier mod = new AttributeModifier(attUUID, attid, getDamageBoost(level), AttributeModifier.Operation.ADD_SCALAR); - if (j.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE) != null) { - j.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).removeModifier(mod); - } else { - return; - } + var attribute = Version.get().getAttribute(j, Attributes.GENERIC_ATTACK_DAMAGE); + if (attribute == null) return; + attribute.removeModifier(MODIFIER, MODIFIER_KEY); if (level > 0) { - j.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).addModifier(mod); + attribute.addModifier(MODIFIER, MODIFIER_KEY, getDamageBoost(level), AttributeModifier.Operation.ADD_SCALAR); } } diff --git a/src/main/java/com/volmit/adapt/content/adaptation/taming/TamingHealthBoost.java b/src/main/java/com/volmit/adapt/content/adaptation/taming/TamingHealthBoost.java index 4cb27198..d04c981a 100644 --- a/src/main/java/com/volmit/adapt/content/adaptation/taming/TamingHealthBoost.java +++ b/src/main/java/com/volmit/adapt/content/adaptation/taming/TamingHealthBoost.java @@ -19,12 +19,14 @@ package com.volmit.adapt.content.adaptation.taming; import com.volmit.adapt.api.adaptation.SimpleAdaptation; +import com.volmit.adapt.api.version.Version; import com.volmit.adapt.util.*; +import com.volmit.adapt.util.reflect.enums.Attributes; import lombok.NoArgsConstructor; import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.NamespacedKey; import org.bukkit.World; -import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeModifier; import org.bukkit.entity.Player; import org.bukkit.entity.Tameable; @@ -33,9 +35,8 @@ import java.util.UUID; public class TamingHealthBoost extends SimpleAdaptation { - private final UUID attUUID = UUID.nameUUIDFromBytes("health-boost".getBytes()); - private final String attid = "att-health-boost"; - + private static final UUID MODIFIER = UUID.nameUUIDFromBytes("adapt-tame-health-boost".getBytes()); + private static final NamespacedKey MODIFIER_KEY = NamespacedKey.fromString( "adapt:tame-health-boost"); public TamingHealthBoost() { super("tame-health"); @@ -78,11 +79,12 @@ public void onTick() { } private void update(Tameable j, int level) { - AttributeModifier mod = new AttributeModifier(attUUID, attid, getHealthBoost(level), AttributeModifier.Operation.ADD_SCALAR); - j.getAttribute(Attribute.GENERIC_MAX_HEALTH).removeModifier(mod); + var attribute = Version.get().getAttribute(j, Attributes.GENERIC_MAX_HEALTH); + if (attribute == null) return; + attribute.removeModifier(MODIFIER, MODIFIER_KEY); if (level > 0) { - j.getAttribute(Attribute.GENERIC_MAX_HEALTH).addModifier(mod); + attribute.addModifier(MODIFIER, MODIFIER_KEY, getHealthBoost(level), AttributeModifier.Operation.ADD_SCALAR); } } diff --git a/src/main/java/com/volmit/adapt/content/adaptation/taming/TamingHealthRegeneration.java b/src/main/java/com/volmit/adapt/content/adaptation/taming/TamingHealthRegeneration.java index 836620f9..2dbd2982 100644 --- a/src/main/java/com/volmit/adapt/content/adaptation/taming/TamingHealthRegeneration.java +++ b/src/main/java/com/volmit/adapt/content/adaptation/taming/TamingHealthRegeneration.java @@ -20,10 +20,11 @@ import com.volmit.adapt.Adapt; import com.volmit.adapt.api.adaptation.SimpleAdaptation; +import com.volmit.adapt.api.version.Version; import com.volmit.adapt.util.*; +import com.volmit.adapt.util.reflect.enums.Attributes; import lombok.NoArgsConstructor; import org.bukkit.Material; -import org.bukkit.attribute.Attribute; import org.bukkit.entity.Player; import org.bukkit.entity.Tameable; import org.bukkit.event.EventHandler; @@ -71,7 +72,8 @@ && hasAdaptation(p)) { Adapt.verbose("Tamed Entity " + tam.getUniqueId() + " last damaged " + (M.ms() - lastDamage.get(tam.getUniqueId())) + "ms ago"); return; } - double mh = tam.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(); + var attribute = Version.get().getAttribute(tam, Attributes.GENERIC_MAX_HEALTH); + double mh = attribute == null ? tam.getHealth() : attribute.getValue(); if (tam.isTamed() && tam.getOwner() instanceof Player && tam.getHealth() < mh) { Adapt.verbose("Successfully healed tamed entity " + tam.getUniqueId()); int level = getLevel(p); diff --git a/src/main/java/com/volmit/adapt/content/adaptation/tragoul/TragoulHealing.java b/src/main/java/com/volmit/adapt/content/adaptation/tragoul/TragoulHealing.java index fffa45b0..092b2d34 100644 --- a/src/main/java/com/volmit/adapt/content/adaptation/tragoul/TragoulHealing.java +++ b/src/main/java/com/volmit/adapt/content/adaptation/tragoul/TragoulHealing.java @@ -20,14 +20,15 @@ import com.volmit.adapt.Adapt; import com.volmit.adapt.api.adaptation.SimpleAdaptation; +import com.volmit.adapt.api.version.Version; import com.volmit.adapt.util.C; import com.volmit.adapt.util.Element; import com.volmit.adapt.util.Localizer; +import com.volmit.adapt.util.reflect.enums.Attributes; import lombok.NoArgsConstructor; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Particle; -import org.bukkit.attribute.Attribute; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.entity.EntityDamageByEntityEvent; @@ -81,7 +82,8 @@ public void on(EntityDamageByEntityEvent e) { double healPercentage = getConfig().minHealPercent + (getConfig().maxHealPercent - getConfig().minHealPercent) * (getLevel(p) - 1) / (getConfig().maxLevel - 1); double healAmount = e.getDamage() * healPercentage; Adapt.verbose("Healing " + p.getName() + " for " + healAmount + " (" + healPercentage * 100 + "% of " + e.getDamage() + " damage)"); - p.setHealth(Math.min(p.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(), p.getHealth() + healAmount)); + var attribute = Version.get().getAttribute(p, Attributes.GENERIC_MAX_HEALTH); + p.setHealth(Math.min(attribute == null ? p.getHealth() : attribute.getValue(), p.getHealth() + healAmount)); } } diff --git a/src/main/java/com/volmit/adapt/content/gui/SkillsGui.java b/src/main/java/com/volmit/adapt/content/gui/SkillsGui.java index dc450986..aff9bf73 100644 --- a/src/main/java/com/volmit/adapt/content/gui/SkillsGui.java +++ b/src/main/java/com/volmit/adapt/content/gui/SkillsGui.java @@ -42,7 +42,8 @@ public static void open(Player player) { w.setTag("/"); w.setDecorator((window, position, row) -> new UIElement("bg") .setName(" ") - .setMaterial(new MaterialBlock(Material.BLACK_STAINED_GLASS_PANE))); + .setMaterial(new MaterialBlock(Material.BLACK_STAINED_GLASS_PANE)) + .setModel(CustomModel.get(Material.BLACK_STAINED_GLASS_PANE, "snippets", "gui", "background"))); AdaptPlayer adaptPlayer = Adapt.instance.getAdaptServer().getPlayer(player); int ind = 0; @@ -51,7 +52,7 @@ public static void open(Player player) { return; } - if (adaptPlayer.getData().getSkillLines().size() > 0) { + if (!adaptPlayer.getData().getSkillLines().isEmpty()) { for (PlayerSkillLine i : adaptPlayer.getData().getSkillLines().sortV()) { if (i.getRawSkill(adaptPlayer).hasBlacklistPermission(adaptPlayer.getPlayer(), i.getRawSkill(adaptPlayer)) || i.getLevel() < 0) { continue; @@ -65,6 +66,7 @@ public static void open(Player player) { Skill sk = Adapt.instance.getAdaptServer().getSkillRegistry().getSkill(i.getLine()); w.setElement(pos, row, new UIElement("skill-" + sk.getName()) .setMaterial(new MaterialBlock(sk.getIcon())) + .setModel(sk.getModel()) .setName(sk.getDisplayName(i.getLevel())) .setProgress(1D) .addLore(C.ITALIC + "" + C.GRAY + sk.getDescription()) @@ -80,6 +82,7 @@ public static void open(Player player) { if (w.getElement(unlearnAllPos, unlearnAllRow) != null) unlearnAllRow++; w.setElement(unlearnAllPos, unlearnAllRow, new UIElement("unlearn-all") .setMaterial(new MaterialBlock(Material.BARRIER)) + .setModel(CustomModel.get(Material.BARRIER, "snippets", "gui", "unlearnall")) .setName("" + C.RESET + C.GRAY + Localizer.dLocalize("snippets", "gui", "unlearnall") + (AdaptConfig.get().isHardcoreNoRefunds() ? " " + C.DARK_RED + "" + C.BOLD + Localizer.dLocalize("snippets", "adaptmenu", "norefunds") diff --git a/src/main/java/com/volmit/adapt/content/item/ItemListings.java b/src/main/java/com/volmit/adapt/content/item/ItemListings.java index 80e45d06..d55fb299 100644 --- a/src/main/java/com/volmit/adapt/content/item/ItemListings.java +++ b/src/main/java/com/volmit/adapt/content/item/ItemListings.java @@ -18,8 +18,8 @@ package com.volmit.adapt.content.item; +import com.volmit.adapt.api.version.Version; import com.volmit.adapt.util.C; -import com.volmit.adapt.util.reflect.enums.EntityTypes; import lombok.Getter; import org.bukkit.ChatColor; import org.bukkit.Material; @@ -31,7 +31,7 @@ public class ItemListings { @Getter - public static List shearList = List.of( + public static final List shearList = List.of( Material.ACACIA_LEAVES, Material.AZALEA_LEAVES, Material.BIRCH_LEAVES, @@ -43,26 +43,10 @@ public class ItemListings { ); @Getter - public static List invalidDamageableEntities = List.of( - EntityType.ARMOR_STAND, - EntityType.BOAT, - EntityType.ITEM_FRAME, - EntityType.MINECART, - EntityTypes.MINECART_CHEST, - EntityTypes.MINECART_COMMAND, - EntityTypes.MINECART_FURNACE, - EntityTypes.MINECART_HOPPER, - EntityTypes.MINECART_MOB_SPAWNER, - EntityTypes.MINECART_TNT, - EntityType.PAINTING, - EntityType.CHEST_BOAT, - EntityTypes.LEASH_HITCH, - EntityType.EVOKER_FANGS, - EntityType.MARKER - ); + public static final List invalidDamageableEntities = Version.get().getInvalidDamageableEntities(); @Getter - public static List smeltOre = List.of( + public static final List smeltOre = List.of( Material.NETHER_GOLD_ORE, Material.IRON_ORE, Material.GOLD_ORE, @@ -73,7 +57,7 @@ public class ItemListings { ); @Getter - public static List ores = List.of( + public static final List ores = List.of( Material.IRON_ORE, Material.GOLD_ORE, Material.COPPER_ORE, diff --git a/src/main/java/com/volmit/adapt/content/skill/SkillAgility.java b/src/main/java/com/volmit/adapt/content/skill/SkillAgility.java index bc3159ce..eab8c9cc 100644 --- a/src/main/java/com/volmit/adapt/content/skill/SkillAgility.java +++ b/src/main/java/com/volmit/adapt/content/skill/SkillAgility.java @@ -29,6 +29,7 @@ import com.volmit.adapt.content.adaptation.agility.AgilityWallJump; import com.volmit.adapt.content.adaptation.agility.AgilityWindUp; import com.volmit.adapt.util.C; +import com.volmit.adapt.util.CustomModel; import com.volmit.adapt.util.Localizer; import lombok.NoArgsConstructor; import org.bukkit.Bukkit; @@ -63,6 +64,7 @@ public SkillAgility() { .key("challenge_move_1k") .title(Localizer.dLocalize("advancement", "challenge_move_1k", "title")) .description(Localizer.dLocalize("advancement", "challenge_move_1k", "description")) + .model(CustomModel.get(Material.LEATHER_BOOTS, "advancement", "agility", "challenge_move_1k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .child(AdaptAdvancement.builder() @@ -70,18 +72,21 @@ public SkillAgility() { .key("challenge_sprint_5k") .title(Localizer.dLocalize("advancement", "challenge_sprint_5k", "title")) .description(Localizer.dLocalize("advancement", "challenge_sprint_5k", "description")) + .model(CustomModel.get(Material.IRON_BOOTS, "advancement", "agility", "challenge_sprint_5k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.DIAMOND_BOOTS) .key("challenge_sprint_50k") .title(Localizer.dLocalize("advancement", "challenge_sprint_50k", "title")) .description(Localizer.dLocalize("advancement", "challenge_sprint_50k", "description")) + .model(CustomModel.get(Material.DIAMOND_BOOTS, "advancement", "agility", "challenge_sprint_50k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.NETHERITE_BOOTS) .key("challenge_sprint_500k") .title(Localizer.dLocalize("advancement", "challenge_sprint_500k", "title")) .description(Localizer.dLocalize("advancement", "challenge_sprint_500k", "description")) + .model(CustomModel.get(Material.NETHERITE_BOOTS, "advancement", "agility", "challenge_sprint_500k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .build()) @@ -92,6 +97,7 @@ public SkillAgility() { .key("challenge_sprint_marathon") .title(Localizer.dLocalize("advancement", "challenge_sprint_marathon", "title")) .description(Localizer.dLocalize("advancement", "challenge_sprint_marathon", "description")) + .model(CustomModel.get(Material.GOLDEN_BOOTS, "advancement", "agility", "challenge_sprint_marathon")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .build()) diff --git a/src/main/java/com/volmit/adapt/content/skill/SkillArchitect.java b/src/main/java/com/volmit/adapt/content/skill/SkillArchitect.java index d7dd5acc..cde63b17 100644 --- a/src/main/java/com/volmit/adapt/content/skill/SkillArchitect.java +++ b/src/main/java/com/volmit/adapt/content/skill/SkillArchitect.java @@ -30,6 +30,7 @@ import com.volmit.adapt.content.adaptation.architect.ArchitectPlacement; import com.volmit.adapt.content.adaptation.architect.ArchitectWirelessRedstone; import com.volmit.adapt.util.C; +import com.volmit.adapt.util.CustomModel; import com.volmit.adapt.util.J; import com.volmit.adapt.util.Localizer; import lombok.NoArgsConstructor; @@ -60,30 +61,35 @@ public SkillArchitect() { .icon(Material.BRICK).key("challenge_place_1k") .title(Localizer.dLocalize("advancement", "challenge_place_1k", "title")) .description(Localizer.dLocalize("advancement", "challenge_place_1k", "description")) + .model(CustomModel.get(Material.BRICK, "advancement", "architect", "challenge_place_1k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.BRICK) .key("challenge_place_5k") .title(Localizer.dLocalize("advancement", "challenge_place_5k", "title")) .description(Localizer.dLocalize("advancement", "challenge_place_5k", "description")) + .model(CustomModel.get(Material.BRICK, "advancement", "architect", "challenge_place_5k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.NETHER_BRICK) .key("challenge_place_50k") .title(Localizer.dLocalize("advancement", "challenge_place_50k", "title")) .description(Localizer.dLocalize("advancement", "challenge_place_50k", "description")) + .model(CustomModel.get(Material.NETHER_BRICK, "advancement", "architect", "challenge_place_50k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.NETHER_BRICK) .key("challenge_place_500k") .title(Localizer.dLocalize("advancement", "challenge_place_500k", "title")) .description(Localizer.dLocalize("advancement", "challenge_place_500k", "description")) + .model(CustomModel.get(Material.NETHER_BRICK, "advancement", "architect", "challenge_place_500k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.IRON_INGOT) .key("challenge_place_5m") .title(Localizer.dLocalize("advancement", "challenge_place_5m", "title")) .description(Localizer.dLocalize("advancement", "challenge_place_5m", "description")) + .model(CustomModel.get(Material.IRON_INGOT, "advancement", "architect", "challenge_place_5m")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .build()) diff --git a/src/main/java/com/volmit/adapt/content/skill/SkillAxes.java b/src/main/java/com/volmit/adapt/content/skill/SkillAxes.java index 559c0d3a..0accab73 100644 --- a/src/main/java/com/volmit/adapt/content/skill/SkillAxes.java +++ b/src/main/java/com/volmit/adapt/content/skill/SkillAxes.java @@ -26,6 +26,7 @@ import com.volmit.adapt.api.world.AdaptStatTracker; import com.volmit.adapt.content.adaptation.axe.*; import com.volmit.adapt.util.C; +import com.volmit.adapt.util.CustomModel; import com.volmit.adapt.util.Localizer; import lombok.NoArgsConstructor; import org.bukkit.Material; @@ -61,30 +62,35 @@ public SkillAxes() { .icon(Material.WOODEN_AXE).key("challenge_chop_1k") .title(Localizer.dLocalize("advancement", "challenge_chop_1k", "title")) .description(Localizer.dLocalize("advancement", "challenge_chop_1k", "description")) + .model(CustomModel.get(Material.WOODEN_AXE, "advancement", "axes", "challenge_chop_1k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.STONE_AXE) .key("challenge_chop_5k") .title(Localizer.dLocalize("advancement", "challenge_chop_5k", "title")) .description(Localizer.dLocalize("advancement", "challenge_chop_5k", "description")) + .model(CustomModel.get(Material.STONE_AXE, "advancement", "axes", "challenge_chop_5k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.IRON_AXE) .key("challenge_chop_50k") .title(Localizer.dLocalize("advancement", "challenge_chop_50k", "title")) .description(Localizer.dLocalize("advancement", "challenge_chop_50k", "description")) + .model(CustomModel.get(Material.IRON_AXE, "advancement", "axes", "challenge_chop_50k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.DIAMOND_AXE) .key("challenge_chop_500k") .title(Localizer.dLocalize("advancement", "challenge_chop_500k", "title")) .description(Localizer.dLocalize("advancement", "challenge_chop_500k", "description")) + .model(CustomModel.get(Material.DIAMOND_AXE, "advancement", "axes", "challenge_chop_500k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.NETHERITE_AXE) .key("challenge_chop_5m") .title(Localizer.dLocalize("advancement", "challenge_chop_5m", "title")) .description(Localizer.dLocalize("advancement", "challenge_chop_5m", "description")) + .model(CustomModel.get(Material.NETHERITE_AXE, "advancement", "axes", "challenge_chop_5m")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .build()) diff --git a/src/main/java/com/volmit/adapt/content/skill/SkillBlocking.java b/src/main/java/com/volmit/adapt/content/skill/SkillBlocking.java index 61b09539..e22aab30 100644 --- a/src/main/java/com/volmit/adapt/content/skill/SkillBlocking.java +++ b/src/main/java/com/volmit/adapt/content/skill/SkillBlocking.java @@ -29,6 +29,7 @@ import com.volmit.adapt.content.adaptation.blocking.BlockingMultiArmor; import com.volmit.adapt.content.adaptation.blocking.BlockingSaddlecrafter; import com.volmit.adapt.util.C; +import com.volmit.adapt.util.CustomModel; import com.volmit.adapt.util.Localizer; import com.volmit.adapt.util.SoundPlayer; import lombok.NoArgsConstructor; @@ -62,30 +63,35 @@ public SkillBlocking() { .icon(Material.LEATHER_CHESTPLATE).key("challenge_block_1k") .title(Localizer.dLocalize("advancement", "challenge_block_1k", "title")) .description(Localizer.dLocalize("advancement", "challenge_block_1k", "description")) + .model(CustomModel.get(Material.LEATHER_CHESTPLATE, "advancement", "blocking", "challenge_block_1k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.CHAINMAIL_CHESTPLATE) .key("challenge_block_5k") .title(Localizer.dLocalize("advancement", "challenge_block_5k", "title")) .description(Localizer.dLocalize("advancement", "challenge_block_5k", "description")) + .model(CustomModel.get(Material.CHAINMAIL_CHESTPLATE, "advancement", "blocking", "challenge_block_5k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.IRON_CHESTPLATE) .key("challenge_block_50k") .title(Localizer.dLocalize("advancement", "challenge_block_50k", "title")) .description(Localizer.dLocalize("advancement", "challenge_block_50k", "description")) + .model(CustomModel.get(Material.IRON_CHESTPLATE, "advancement", "blocking", "challenge_block_50k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.GOLDEN_CHESTPLATE) .key("challenge_block_500k") .title(Localizer.dLocalize("advancement", "challenge_block_500k", "title")) .description(Localizer.dLocalize("advancement", "challenge_block_500k", "description")) + .model(CustomModel.get(Material.GOLDEN_CHESTPLATE, "advancement", "blocking", "challenge_block_500k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.DIAMOND_CHESTPLATE) .key("challenge_block_5m") .title(Localizer.dLocalize("advancement", "challenge_block_5m", "title")) .description(Localizer.dLocalize("advancement", "challenge_block_5m", "description")) + .model(CustomModel.get(Material.DIAMOND_CHESTPLATE, "advancement", "blocking", "challenge_block_5m")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .build()) diff --git a/src/main/java/com/volmit/adapt/content/skill/SkillBrewing.java b/src/main/java/com/volmit/adapt/content/skill/SkillBrewing.java index d874d32e..bd65b0e8 100644 --- a/src/main/java/com/volmit/adapt/content/skill/SkillBrewing.java +++ b/src/main/java/com/volmit/adapt/content/skill/SkillBrewing.java @@ -30,6 +30,7 @@ import com.volmit.adapt.content.matter.BrewingStandOwner; import com.volmit.adapt.content.matter.BrewingStandOwnerMatter; import com.volmit.adapt.util.C; +import com.volmit.adapt.util.CustomModel; import com.volmit.adapt.util.Localizer; import lombok.NoArgsConstructor; import org.bukkit.Material; @@ -75,30 +76,35 @@ public SkillBrewing() { .icon(Material.POTION).key("challenge_brew_1k") .title(Localizer.dLocalize("advancement", "challenge_brew_1k", "title")) .description(Localizer.dLocalize("advancement", "challenge_brew_1k", "description")) + .model(CustomModel.get(Material.POTION, "advancement", "brewing", "challenge_brew_1k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.POTION) .key("challenge_brew_5k") .title(Localizer.dLocalize("advancement", "challenge_brew_5k", "title")) .description(Localizer.dLocalize("advancement", "challenge_brew_5k", "description")) + .model(CustomModel.get(Material.POTION, "advancement", "brewing", "challenge_brew_5k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.POTION) .key("challenge_brew_50k") .title(Localizer.dLocalize("advancement", "challenge_brew_50k", "title")) .description(Localizer.dLocalize("advancement", "challenge_brew_50k", "description")) + .model(CustomModel.get(Material.POTION, "advancement", "brewing", "challenge_brew_50k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.POTION) .key("challenge_brew_500k") .title(Localizer.dLocalize("advancement", "challenge_brew_500k", "title")) .description(Localizer.dLocalize("advancement", "challenge_brew_500k", "description")) + .model(CustomModel.get(Material.POTION, "advancement", "brewing", "challenge_brew_500k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.POTION) .key("challenge_brew_5m") .title(Localizer.dLocalize("advancement", "challenge_brew_5m", "title")) .description(Localizer.dLocalize("advancement", "challenge_brew_5m", "description")) + .model(CustomModel.get(Material.POTION, "advancement", "brewing", "challenge_brew_5m")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .build()) @@ -116,30 +122,35 @@ public SkillBrewing() { .icon(Material.SPLASH_POTION).key("challenge_brewsplash_1k") .title(Localizer.dLocalize("advancement", "challenge_brewsplash_1k", "title")) .description(Localizer.dLocalize("advancement", "challenge_brewsplash_1k", "description")) + .model(CustomModel.get(Material.SPLASH_POTION, "advancement", "brewing", "brewsplash_1k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.SPLASH_POTION) .key("challenge_brewsplash_5k") .title(Localizer.dLocalize("advancement", "challenge_brewsplash_5k", "title")) .description(Localizer.dLocalize("advancement", "challenge_brewsplash_5k", "description")) + .model(CustomModel.get(Material.SPLASH_POTION, "advancement", "brewing", "brewsplash_5k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.SPLASH_POTION) .key("challenge_brewsplash_50k") .title(Localizer.dLocalize("advancement", "challenge_brewsplash_50k", "title")) .description(Localizer.dLocalize("advancement", "challenge_brewsplash_50k", "description")) + .model(CustomModel.get(Material.SPLASH_POTION, "advancement", "brewing", "brewsplash_50k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.SPLASH_POTION) .key("challenge_brewsplash_500k") .title(Localizer.dLocalize("advancement", "challenge_brewsplash_500k", "title")) .description(Localizer.dLocalize("advancement", "challenge_brewsplash_500k", "description")) + .model(CustomModel.get(Material.SPLASH_POTION, "advancement", "brewing", "brewsplash_50k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.SPLASH_POTION) .key("challenge_brewsplash_5m") .title(Localizer.dLocalize("advancement", "challenge_brewsplash_5m", "title")) .description(Localizer.dLocalize("advancement", "challenge_brewsplash_5m", "description")) + .model(CustomModel.get(Material.SPLASH_POTION, "advancement", "brewing", "brewsplash_5m")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .build()) diff --git a/src/main/java/com/volmit/adapt/content/skill/SkillCrafting.java b/src/main/java/com/volmit/adapt/content/skill/SkillCrafting.java index 3d9f484b..a1d60124 100644 --- a/src/main/java/com/volmit/adapt/content/skill/SkillCrafting.java +++ b/src/main/java/com/volmit/adapt/content/skill/SkillCrafting.java @@ -25,6 +25,7 @@ import com.volmit.adapt.api.world.AdaptStatTracker; import com.volmit.adapt.content.adaptation.crafting.*; import com.volmit.adapt.util.C; +import com.volmit.adapt.util.CustomModel; import com.volmit.adapt.util.Localizer; import lombok.NoArgsConstructor; import org.bukkit.Bukkit; @@ -63,30 +64,35 @@ public SkillCrafting() { .icon(Material.CRAFTING_TABLE).key("challenge_craft_1k") .title(Localizer.dLocalize("advancement", "challenge_craft_1k", "title")) .description(Localizer.dLocalize("advancement", "challenge_craft_1k", "description")) + .model(CustomModel.get(Material.CRAFTING_TABLE, "advancement", "crafting", "challenge_craft_1k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.CRAFTING_TABLE) .key("challenge_craft_5k") .title(Localizer.dLocalize("advancement", "challenge_craft_5k", "title")) .description(Localizer.dLocalize("advancement", "challenge_craft_5k", "description")) + .model(CustomModel.get(Material.CRAFTING_TABLE, "advancement", "crafting", "challenge_craft_5k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.CRAFTING_TABLE) .key("challenge_craft_50k") .title(Localizer.dLocalize("advancement", "challenge_craft_50k", "title")) .description(Localizer.dLocalize("advancement", "challenge_craft_50k", "description")) + .model(CustomModel.get(Material.CRAFTING_TABLE, "advancement", "crafting", "challenge_craft_50k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.CRAFTING_TABLE) .key("challenge_craft_500k") .title(Localizer.dLocalize("advancement", "challenge_craft_500k", "title")) .description(Localizer.dLocalize("advancement", "challenge_craft_500k", "description")) + .model(CustomModel.get(Material.CRAFTING_TABLE, "advancement", "crafting", "challenge_craft_500k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.CRAFTING_TABLE) .key("challenge_craft_5m") .title(Localizer.dLocalize("advancement", "challenge_craft_5m", "title")) .description(Localizer.dLocalize("advancement", "challenge_craft_5m", "description")) + .model(CustomModel.get(Material.CRAFTING_TABLE, "advancement", "crafting", "challenge_craft_5m")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .build()) @@ -94,11 +100,11 @@ public SkillCrafting() { .build()) .build()) .build()); - registerStatTracker(AdaptStatTracker.builder().advancement("challenge_block_1k").goal(1000).stat("blocked.hits").reward(getConfig().challengeCraft1kReward).build()); - registerStatTracker(AdaptStatTracker.builder().advancement("challenge_block_5k").goal(5000).stat("blocked.hits").reward(getConfig().challengeCraft1kReward).build()); - registerStatTracker(AdaptStatTracker.builder().advancement("challenge_block_50k").goal(50000).stat("blocked.hits").reward(getConfig().challengeCraft1kReward).build()); - registerStatTracker(AdaptStatTracker.builder().advancement("challenge_block_500k").goal(500000).stat("blocked.hits").reward(getConfig().challengeCraft1kReward).build()); - registerStatTracker(AdaptStatTracker.builder().advancement("challenge_block_5m").goal(5000000).stat("blocked.hits").reward(getConfig().challengeCraft1kReward).build()); + registerStatTracker(AdaptStatTracker.builder().advancement("challenge_craft_1k").goal(1000).stat("crafted.items").reward(getConfig().challengeCraft1kReward).build()); + registerStatTracker(AdaptStatTracker.builder().advancement("challenge_craft_5k").goal(5000).stat("crafted.items").reward(getConfig().challengeCraft1kReward).build()); + registerStatTracker(AdaptStatTracker.builder().advancement("challenge_craft_50k").goal(50000).stat("crafted.items").reward(getConfig().challengeCraft1kReward).build()); + registerStatTracker(AdaptStatTracker.builder().advancement("challenge_craft_500k").goal(500000).stat("crafted.items").reward(getConfig().challengeCraft1kReward).build()); + registerStatTracker(AdaptStatTracker.builder().advancement("challenge_craft_5m").goal(5000000).stat("crafted.items").reward(getConfig().challengeCraft1kReward).build()); cooldowns = new HashMap<>(); } diff --git a/src/main/java/com/volmit/adapt/content/skill/SkillDiscovery.java b/src/main/java/com/volmit/adapt/content/skill/SkillDiscovery.java index 4417aa4a..4f87e3db 100644 --- a/src/main/java/com/volmit/adapt/content/skill/SkillDiscovery.java +++ b/src/main/java/com/volmit/adapt/content/skill/SkillDiscovery.java @@ -240,8 +240,8 @@ public void seePotionEffect(Player p, PotionEffect e) { } public void seeBiome(Player p, Biome e) { - Discovery d = getPlayer(p).getData().getSeenBiomes(); - if (d.isNewDiscovery(e)) { + Discovery d = getPlayer(p).getData().getSeenBiomes(); + if (d.isNewDiscovery(e.getKey().toString())) { xp(p, getConfig().discoverBiomeXP); } } diff --git a/src/main/java/com/volmit/adapt/content/skill/SkillEnchanting.java b/src/main/java/com/volmit/adapt/content/skill/SkillEnchanting.java index 0dc48adf..bc446137 100644 --- a/src/main/java/com/volmit/adapt/content/skill/SkillEnchanting.java +++ b/src/main/java/com/volmit/adapt/content/skill/SkillEnchanting.java @@ -28,6 +28,7 @@ import com.volmit.adapt.content.adaptation.enchanting.EnchantingQuickEnchant; import com.volmit.adapt.content.adaptation.enchanting.EnchantingXPReturn; import com.volmit.adapt.util.C; +import com.volmit.adapt.util.CustomModel; import com.volmit.adapt.util.Localizer; import lombok.NoArgsConstructor; import org.bukkit.Material; @@ -58,30 +59,35 @@ public SkillEnchanting() { .icon(Material.CRAFTING_TABLE).key("challenge_enchant_1k") .title(Localizer.dLocalize("advancement", "challenge_enchant_1k", "title")) .description(Localizer.dLocalize("advancement", "challenge_enchant_1k", "description")) + .model(CustomModel.get(Material.CRAFTING_TABLE, "advancement", "enchanting", "challenge_enchant_1k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.KNOWLEDGE_BOOK) .key("challenge_enchant_5k") .title(Localizer.dLocalize("advancement", "challenge_enchant_5k", "title")) .description(Localizer.dLocalize("advancement", "challenge_enchant_5k", "description")) + .model(CustomModel.get(Material.KNOWLEDGE_BOOK, "advancement", "enchanting", "challenge_enchant_5k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.KNOWLEDGE_BOOK) .key("challenge_enchant_50k") .title(Localizer.dLocalize("advancement", "challenge_enchant_50k", "title")) .description(Localizer.dLocalize("advancement", "challenge_enchant_50k", "description")) + .model(CustomModel.get(Material.KNOWLEDGE_BOOK, "advancement", "enchanting", "challenge_enchant_50k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.KNOWLEDGE_BOOK) .key("challenge_enchant_500k") .title(Localizer.dLocalize("advancement", "challenge_enchant_500k", "title")) .description(Localizer.dLocalize("advancement", "challenge_enchant_500k", "description")) + .model(CustomModel.get(Material.KNOWLEDGE_BOOK, "advancement", "enchanting", "challenge_enchant_500k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.KNOWLEDGE_BOOK) .key("challenge_enchant_5m") .title(Localizer.dLocalize("advancement", "challenge_enchant_5m", "title")) .description(Localizer.dLocalize("advancement", "challenge_enchant_5m", "description")) + .model(CustomModel.get(Material.KNOWLEDGE_BOOK, "advancement", "enchanting", "challenge_enchant_5m")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .build()) diff --git a/src/main/java/com/volmit/adapt/content/skill/SkillExcavation.java b/src/main/java/com/volmit/adapt/content/skill/SkillExcavation.java index a8a0f560..8821e847 100644 --- a/src/main/java/com/volmit/adapt/content/skill/SkillExcavation.java +++ b/src/main/java/com/volmit/adapt/content/skill/SkillExcavation.java @@ -29,6 +29,7 @@ import com.volmit.adapt.content.adaptation.excavation.ExcavationOmniTool; import com.volmit.adapt.content.adaptation.excavation.ExcavationSpelunker; import com.volmit.adapt.util.C; +import com.volmit.adapt.util.CustomModel; import com.volmit.adapt.util.Localizer; import lombok.NoArgsConstructor; import org.bukkit.Material; @@ -62,30 +63,35 @@ public SkillExcavation() { .icon(Material.WOODEN_SHOVEL).key("challenge_excavate_1k") .title(Localizer.dLocalize("advancement", "challenge_excavate_1k", "title")) .description(Localizer.dLocalize("advancement", "challenge_excavate_1k", "description")) + .model(CustomModel.get(Material.WOODEN_SHOVEL, "advancement", "excavation", "challenge_excavate_1k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.KNOWLEDGE_BOOK) .key("challenge_excavate_5k") .title(Localizer.dLocalize("advancement", "challenge_excavate_5k", "title")) .description(Localizer.dLocalize("advancement", "challenge_excavate_5k", "description")) + .model(CustomModel.get(Material.KNOWLEDGE_BOOK, "advancement", "excavation", "challenge_excavate_5k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.STONE_SHOVEL) .key("challenge_excavate_50k") .title(Localizer.dLocalize("advancement", "challenge_excavate_50k", "title")) .description(Localizer.dLocalize("advancement", "challenge_excavate_50k", "description")) + .model(CustomModel.get(Material.STONE_SHOVEL, "advancement", "excavation", "challenge_excavate_50k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.IRON_SHOVEL) .key("challenge_excavate_500k") .title(Localizer.dLocalize("advancement", "challenge_excavate_500k", "title")) .description(Localizer.dLocalize("advancement", "challenge_excavate_500k", "description")) + .model(CustomModel.get(Material.IRON_SHOVEL, "advancement", "excavation", "challenge_excavate_500k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.DIAMOND_SHOVEL) .key("challenge_excavate_5m") .title(Localizer.dLocalize("advancement", "challenge_excavate_5m", "title")) .description(Localizer.dLocalize("advancement", "challenge_excavate_5m", "description")) + .model(CustomModel.get(Material.DIAMOND_SHOVEL, "advancement", "excavation", "challenge_excavate_5m")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .build()) diff --git a/src/main/java/com/volmit/adapt/content/skill/SkillHerbalism.java b/src/main/java/com/volmit/adapt/content/skill/SkillHerbalism.java index 690a4c83..86719439 100644 --- a/src/main/java/com/volmit/adapt/content/skill/SkillHerbalism.java +++ b/src/main/java/com/volmit/adapt/content/skill/SkillHerbalism.java @@ -25,6 +25,7 @@ import com.volmit.adapt.api.world.AdaptStatTracker; import com.volmit.adapt.content.adaptation.herbalism.*; import com.volmit.adapt.util.C; +import com.volmit.adapt.util.CustomModel; import com.volmit.adapt.util.J; import com.volmit.adapt.util.Localizer; import lombok.NoArgsConstructor; @@ -69,21 +70,24 @@ public SkillHerbalism() { registerAdvancement(AdaptAdvancement.builder() .icon(Material.COOKED_BEEF) .key("challenge_eat_100") - .title("So much to eat!") - .description("Eat over 100 Items!") + .title(Localizer.dLocalize("advancement", "challenge_eat_100", "title")) + .description(Localizer.dLocalize("advancement", "challenge_eat_100", "description")) + .model(CustomModel.get(Material.COOKED_BEEF, "advancement", "herbalism", "challenge_eat_100")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .child(AdaptAdvancement.builder() .icon(Material.COOKED_BEEF) .key("challenge_eat_1000") - .title("Unquenchable Hunger!") - .description("Eat over 1,000 Items!") + .title(Localizer.dLocalize("advancement", "challenge_eat_1000", "title")) + .description(Localizer.dLocalize("advancement", "challenge_eat_1000", "description")) + .model(CustomModel.get(Material.COOKED_BEEF, "advancement", "herbalism", "challenge_eat_1000")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED).child(AdaptAdvancement.builder() .icon(Material.COOKED_BEEF) .key("challenge_eat_10000") - .title("EVERLASTING HUNGER!") - .description("Eat over 10,000 Items!") + .title(Localizer.dLocalize("advancement", "challenge_eat_10000", "title")) + .description(Localizer.dLocalize("advancement", "challenge_eat_10000", "description")) + .model(CustomModel.get(Material.COOKED_BEEF, "advancement", "herbalism", "challenge_eat_10000")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .build()) @@ -97,15 +101,17 @@ public SkillHerbalism() { registerAdvancement(AdaptAdvancement.builder() .icon(Material.COOKED_BEEF) .key("challenge_harvest_100") - .title("Full Harvest") - .description("Harvest over 100 crops!") + .title(Localizer.dLocalize("advancement", "challenge_harvest_100", "title")) + .description(Localizer.dLocalize("advancement", "challenge_harvest_100", "description")) + .model(CustomModel.get(Material.COOKED_BEEF, "advancement", "herbalism", "harvest_100")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .child(AdaptAdvancement.builder() .icon(Material.COOKED_BEEF) .key("challenge_harvest_1000") - .title("Grand Harvest") - .description("Harvest 1,000 crops!") + .title(Localizer.dLocalize("advancement", "challenge_harvest_1000", "title")) + .description(Localizer.dLocalize("advancement", "challenge_harvest_1000", "description")) + .model(CustomModel.get(Material.COOKED_BEEF, "advancement", "herbalism", "harvest_1000")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .build()) diff --git a/src/main/java/com/volmit/adapt/content/skill/SkillHunter.java b/src/main/java/com/volmit/adapt/content/skill/SkillHunter.java index ad24c9f4..f240650a 100644 --- a/src/main/java/com/volmit/adapt/content/skill/SkillHunter.java +++ b/src/main/java/com/volmit/adapt/content/skill/SkillHunter.java @@ -22,13 +22,15 @@ import com.volmit.adapt.api.advancement.AdaptAdvancement; import com.volmit.adapt.api.advancement.AdvancementVisibility; import com.volmit.adapt.api.skill.SimpleSkill; +import com.volmit.adapt.api.version.Version; import com.volmit.adapt.api.world.AdaptStatTracker; import com.volmit.adapt.content.adaptation.hunter.*; import com.volmit.adapt.util.C; +import com.volmit.adapt.util.CustomModel; import com.volmit.adapt.util.Localizer; +import com.volmit.adapt.util.reflect.enums.Attributes; import lombok.NoArgsConstructor; import org.bukkit.Material; -import org.bukkit.attribute.Attribute; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; @@ -70,6 +72,7 @@ public SkillHunter() { .key("horrible_person") .title(Localizer.dLocalize("advancement", "horrible_person", "title")) .description(Localizer.dLocalize("advancement", "horrible_person", "description")) + .model(CustomModel.get(Material.TURTLE_EGG, "advancement", "hunter", "horrible_person")) .frame(AdvancementFrameType.GOAL) .visibility(AdvancementVisibility.HIDDEN) .build() @@ -79,6 +82,7 @@ public SkillHunter() { .key("challenge_turtle_egg_smasher") .title(Localizer.dLocalize("advancement", "challenge_turtle_egg_smasher", "title")) .description(Localizer.dLocalize("advancement", "challenge_turtle_egg_smasher", "description")) + .model(CustomModel.get(Material.TURTLE_EGG, "advancement", "hunter", "challenge_turtle_egg_smasher")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .child(AdaptAdvancement.builder() @@ -86,6 +90,7 @@ public SkillHunter() { .key("challenge_turtle_egg_annihilator") .title(Localizer.dLocalize("advancement", "challenge_turtle_egg_annihilator", "title")) .description(Localizer.dLocalize("advancement", "challenge_turtle_egg_annihilator", "description")) + .model(CustomModel.get(Material.TURTLE_EGG, "advancement", "hunter", "challenge_turtle_egg_annihilator")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .build()) @@ -95,6 +100,7 @@ public SkillHunter() { .key("challenge_novice_hunter") .title(Localizer.dLocalize("advancement", "challenge_novice_hunter", "title")) .description(Localizer.dLocalize("advancement", "challenge_novice_hunter", "description")) + .model(CustomModel.get(Material.BONE, "advancement", "hunter", "challenge_novice_hunter")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .child(AdaptAdvancement.builder() @@ -102,6 +108,7 @@ public SkillHunter() { .key("challenge_intermediate_hunter") .title(Localizer.dLocalize("advancement", "challenge_intermediate_hunter", "title")) .description(Localizer.dLocalize("advancement", "challenge_intermediate_hunter", "description")) + .model(CustomModel.get(Material.IRON_SWORD, "advancement", "hunter", "challenge_intermediate_hunter")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .child(AdaptAdvancement.builder() @@ -109,6 +116,7 @@ public SkillHunter() { .key("challenge_advanced_hunter") .title(Localizer.dLocalize("advancement", "challenge_advanced_hunter", "title")) .description(Localizer.dLocalize("advancement", "challenge_advanced_hunter", "description")) + .model(CustomModel.get(Material.DIAMOND_SWORD, "advancement", "hunter", "challenge_advanced_hunter")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .build()) @@ -119,6 +127,7 @@ public SkillHunter() { .key("challenge_creeper_conqueror") .title(Localizer.dLocalize("advancement", "challenge_creeper_conqueror", "title")) .description(Localizer.dLocalize("advancement", "challenge_creeper_conqueror", "description")) + .model(CustomModel.get(Material.CREEPER_HEAD, "advancement", "hunter", "challenge_creeper_conqueror")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .child(AdaptAdvancement.builder() @@ -126,6 +135,7 @@ public SkillHunter() { .key("challenge_creeper_annihilator") .title(Localizer.dLocalize("advancement", "challenge_creeper_annihilator", "title")) .description(Localizer.dLocalize("advancement", "challenge_creeper_annihilator", "description")) + .model(CustomModel.get(Material.TNT, "advancement", "hunter", "challenge_creeper_annihilator")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .build()) @@ -191,7 +201,8 @@ public void on(EntityDeathEvent e) { shouldReturnForPlayer(p, () -> { if (e.getEntity().getType().equals(EntityType.CREEPER)) { double cmult = getConfig().creeperKillMultiplier; - double xpAmount = e.getEntity().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue() * getConfig().killMaxHealthXPMultiplier * cmult; + var attribute = Version.get().getAttribute(e.getEntity(), Attributes.GENERIC_MAX_HEALTH); + double xpAmount = (attribute == null ? 1 : attribute.getValue()) * getConfig().killMaxHealthXPMultiplier * cmult; if (e.getEntity().getPortalCooldown() > 0) { xpAmount *= getConfig().spawnerMobReductionXpMultiplier; } @@ -217,7 +228,8 @@ public void on(CreatureSpawnEvent e) { private void handleEntityKill(Player p, Entity entity) { if (entity instanceof LivingEntity livingEntity) { - double xpAmount = livingEntity.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue() * getConfig().killMaxHealthXPMultiplier; + var attribute = Version.get().getAttribute(livingEntity, Attributes.GENERIC_MAX_HEALTH); + double xpAmount = (attribute == null ? 1 : attribute.getValue()) * getConfig().killMaxHealthXPMultiplier; if (entity.getPortalCooldown() > 0) { xpAmount *= getConfig().spawnerMobReductionXpMultiplier; } diff --git a/src/main/java/com/volmit/adapt/content/skill/SkillPickaxes.java b/src/main/java/com/volmit/adapt/content/skill/SkillPickaxes.java index 1f134dc8..b1c6999a 100644 --- a/src/main/java/com/volmit/adapt/content/skill/SkillPickaxes.java +++ b/src/main/java/com/volmit/adapt/content/skill/SkillPickaxes.java @@ -24,11 +24,9 @@ import com.volmit.adapt.api.skill.SimpleSkill; import com.volmit.adapt.api.world.AdaptPlayer; import com.volmit.adapt.api.world.AdaptStatTracker; -import com.volmit.adapt.content.adaptation.pickaxe.PickaxeAutosmelt; -import com.volmit.adapt.content.adaptation.pickaxe.PickaxeChisel; -import com.volmit.adapt.content.adaptation.pickaxe.PickaxeDropToInventory; -import com.volmit.adapt.content.adaptation.pickaxe.PickaxeVeinminer; +import com.volmit.adapt.content.adaptation.pickaxe.*; import com.volmit.adapt.util.C; +import com.volmit.adapt.util.CustomModel; import com.volmit.adapt.util.J; import com.volmit.adapt.util.Localizer; import lombok.NoArgsConstructor; @@ -61,11 +59,13 @@ public SkillPickaxes() { registerAdaptation(new PickaxeVeinminer()); registerAdaptation(new PickaxeAutosmelt()); registerAdaptation(new PickaxeDropToInventory()); + registerAdaptation(new PickaxeSilkSpawner()); registerAdvancement(AdaptAdvancement.builder() .icon(Material.WOODEN_PICKAXE) .key("challenge_pickaxe_1k") .title(Localizer.dLocalize("advancement", "challenge_pickaxe_1k", "title")) .description(Localizer.dLocalize("advancement", "challenge_pickaxe_1k", "description")) + .model(CustomModel.get(Material.WOODEN_PICKAXE, "advancement", "pickaxe", "challenge_pickaxe_1k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .child(AdaptAdvancement.builder() @@ -73,6 +73,7 @@ public SkillPickaxes() { .key("challenge_pickaxe_5k") .title(Localizer.dLocalize("advancement", "challenge_pickaxe_5k", "title")) .description(Localizer.dLocalize("advancement", "challenge_pickaxe_5k", "description")) + .model(CustomModel.get(Material.STONE_PICKAXE, "advancement", "pickaxe", "challenge_pickaxe_5k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .child(AdaptAdvancement.builder() @@ -80,6 +81,7 @@ public SkillPickaxes() { .key("challenge_pickaxe_50k") .title(Localizer.dLocalize("advancement", "challenge_pickaxe_50k", "title")) .description(Localizer.dLocalize("advancement", "challenge_pickaxe_50k", "description")) + .model(CustomModel.get(Material.IRON_PICKAXE, "advancement", "pickaxe", "challenge_pickaxe_50k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .child(AdaptAdvancement.builder() @@ -87,6 +89,7 @@ public SkillPickaxes() { .key("challenge_pickaxe_500k") .title(Localizer.dLocalize("advancement", "challenge_pickaxe_500k", "title")) .description(Localizer.dLocalize("advancement", "challenge_pickaxe_500k", "description")) + .model(CustomModel.get(Material.DIAMOND_PICKAXE, "advancement", "pickaxe", "challenge_pickaxe_500k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .child(AdaptAdvancement.builder() @@ -94,6 +97,7 @@ public SkillPickaxes() { .key("challenge_pickaxe_5m") .title(Localizer.dLocalize("advancement", "challenge_pickaxe_5m", "title")) .description(Localizer.dLocalize("advancement", "challenge_pickaxe_5m", "description")) + .model(CustomModel.get(Material.NETHERITE_PICKAXE, "advancement", "pickaxe", "challenge_pickaxe_5m")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .build()) @@ -116,7 +120,7 @@ public void on(EntityDamageByEntityEvent e) { return; } Player p = e.getDamager() instanceof Player ? (Player) e.getDamager() : null; - if (!getConfig().getXpForAttackingWithTools) { + if (!getConfig().getXpForAttackingWithTools || p == null) { return; } diff --git a/src/main/java/com/volmit/adapt/content/skill/SkillRift.java b/src/main/java/com/volmit/adapt/content/skill/SkillRift.java index 1fe669d7..52e5f515 100644 --- a/src/main/java/com/volmit/adapt/content/skill/SkillRift.java +++ b/src/main/java/com/volmit/adapt/content/skill/SkillRift.java @@ -19,13 +19,15 @@ package com.volmit.adapt.content.skill; import com.volmit.adapt.api.skill.SimpleSkill; +import com.volmit.adapt.api.version.Version; import com.volmit.adapt.content.adaptation.rift.*; import com.volmit.adapt.util.C; import com.volmit.adapt.util.Localizer; import com.volmit.adapt.util.M; +import com.volmit.adapt.util.reflect.enums.Attributes; +import com.volmit.adapt.util.reflect.enums.EntityTypes; import lombok.NoArgsConstructor; import org.bukkit.Material; -import org.bukkit.attribute.Attribute; import org.bukkit.entity.*; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -91,14 +93,18 @@ public void on(ProjectileLaunchEvent e) { } private void handleEntityDamageByEntity(Entity entity, Player p, double damage) { - - if (entity instanceof Enderman) { - xp(p, getConfig().damageEndermanXPMultiplier * Math.min(damage, ((Enderman) entity).getAttribute(Attribute.GENERIC_MAX_HEALTH).getBaseValue())); - } else if (entity instanceof Endermite) { - xp(p, getConfig().damageEndermiteXPMultiplier * Math.min(damage, ((Endermite) entity).getAttribute(Attribute.GENERIC_MAX_HEALTH).getBaseValue())); - } else if (entity instanceof EnderDragon) { - xp(p, getConfig().damageEnderdragonXPMultiplier * Math.min(damage, ((EnderDragon) entity).getAttribute(Attribute.GENERIC_MAX_HEALTH).getBaseValue())); - } else if (entity instanceof EnderCrystal) { + if (entity instanceof LivingEntity living) { + var attribute = Version.get().getAttribute(living, Attributes.GENERIC_MAX_HEALTH); + double baseHealth = attribute == null ? 1 : attribute.getBaseValue(); + double multiplier = switch (entity.getType()) { + case ENDERMAN -> getConfig().damageEndermanXPMultiplier; + case ENDERMITE -> getConfig().damageEndermiteXPMultiplier; + case ENDER_DRAGON -> getConfig().damageEnderdragonXPMultiplier; + default -> 0; + }; + double xp = multiplier * Math.min(damage, baseHealth); + if (xp > 0) xp(p, xp); + } else if (entity.getType() == EntityTypes.ENDER_CRYSTAL) { xp(p, getConfig().damageEndCrystalXP); } } diff --git a/src/main/java/com/volmit/adapt/content/skill/SkillSeaborne.java b/src/main/java/com/volmit/adapt/content/skill/SkillSeaborne.java index c40d4d13..30e51225 100644 --- a/src/main/java/com/volmit/adapt/content/skill/SkillSeaborne.java +++ b/src/main/java/com/volmit/adapt/content/skill/SkillSeaborne.java @@ -23,14 +23,16 @@ import com.volmit.adapt.api.advancement.AdaptAdvancement; import com.volmit.adapt.api.advancement.AdvancementVisibility; import com.volmit.adapt.api.skill.SimpleSkill; +import com.volmit.adapt.api.version.Version; import com.volmit.adapt.api.world.AdaptStatTracker; import com.volmit.adapt.content.adaptation.seaborrne.*; import com.volmit.adapt.util.C; +import com.volmit.adapt.util.CustomModel; import com.volmit.adapt.util.Localizer; +import com.volmit.adapt.util.reflect.enums.Attributes; import lombok.NoArgsConstructor; import org.bukkit.Bukkit; import org.bukkit.Material; -import org.bukkit.attribute.Attribute; import org.bukkit.entity.*; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -60,8 +62,9 @@ public SkillSeaborne() { registerAdvancement(AdaptAdvancement.builder() .icon(Material.TURTLE_HELMET) .key("challenge_swim_1nm") - .title("Human Submarine!") - .description("Swim 1 Nautical Mile (1,852 blocks)") + .title(Localizer.dLocalize("advancement", "challenge_swim_1nm", "title")) + .description(Localizer.dLocalize("advancement", "challenge_swim_1nm", "description")) + .model(CustomModel.get(Material.TURTLE_HELMET, "advancement", "seaborne", "challenge_swim_1nm")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .build()); @@ -131,24 +134,34 @@ public void on(BlockBreakEvent e) { @EventHandler(priority = EventPriority.MONITOR) public void on(EntityDamageByEntityEvent e) { - if (e.isCancelled()) { + if (e.isCancelled() || !(e.getEntity() instanceof LivingEntity entity)) return; - } - if (e.getEntity() instanceof Drowned && e.getDamager() instanceof Player p) { + + if (e.getEntity().getType() == EntityType.DROWNED && e.getDamager().getType() == EntityType.PLAYER) { + var p = (Player) e.getDamager(); shouldReturnForPlayer(p, e, () -> { if (isOnCooldown(p, getConfig().seaPickleCooldown)) { return; } setCooldown(p); - xp(p, getConfig().damagedrownxpmultiplier * Math.min(e.getDamage(), ((LivingEntity) e.getEntity()).getAttribute(Attribute.GENERIC_MAX_HEALTH).getBaseValue())); + xp(p, getConfig().damagedrownxpmultiplier * Math.min(e.getDamage(), getBaseHealth(entity))); }); + } else if (e.getDamager().getType() == EntityType.TRIDENT) { + var shooter = ((Trident) e.getDamager()).getShooter(); + if (shooter instanceof Player p) { + shouldReturnForPlayer(p, e, () -> xp(p, getConfig().tridentxpmultiplier * Math.min(e.getDamage(), getBaseHealth(entity)))); + } + } else if (e.getDamager().getType() == EntityType.PLAYER) { + var p = (Player) e.getDamager(); + if (p.getInventory().getItemInMainHand().getType().equals(Material.TRIDENT)) { + shouldReturnForPlayer(p, e, () -> xp(p, getConfig().tridentxpmultiplier * Math.min(e.getDamage(), getBaseHealth(entity)))); + } } - if (e.getDamager() instanceof Projectile projectile && projectile instanceof Trident && ((Projectile) e.getDamager()).getShooter() instanceof Player p) { - shouldReturnForPlayer(p, e, () -> xp(p, getConfig().tridentxpmultiplier * Math.min(e.getDamage(), ((LivingEntity) e.getEntity()).getAttribute(Attribute.GENERIC_MAX_HEALTH).getBaseValue()))); - } - if (e.getDamager() instanceof Player p && p.getInventory().getItemInMainHand().getType().equals(Material.TRIDENT)) { - shouldReturnForPlayer(p, e, () -> xp(p, getConfig().tridentxpmultiplier * Math.min(e.getDamage(), ((LivingEntity) e.getEntity()).getAttribute(Attribute.GENERIC_MAX_HEALTH).getBaseValue()))); - } + } + + private double getBaseHealth(LivingEntity entity) { + var attribute = Version.get().getAttribute(entity, Attributes.GENERIC_MAX_HEALTH); + return attribute == null ? 0 : attribute.getBaseValue(); } @Override diff --git a/src/main/java/com/volmit/adapt/content/skill/SkillStealth.java b/src/main/java/com/volmit/adapt/content/skill/SkillStealth.java index a257ce2a..32ec85fd 100644 --- a/src/main/java/com/volmit/adapt/content/skill/SkillStealth.java +++ b/src/main/java/com/volmit/adapt/content/skill/SkillStealth.java @@ -28,6 +28,7 @@ import com.volmit.adapt.content.adaptation.stealth.StealthSnatch; import com.volmit.adapt.content.adaptation.stealth.StealthSpeed; import com.volmit.adapt.util.C; +import com.volmit.adapt.util.CustomModel; import com.volmit.adapt.util.Localizer; import lombok.NoArgsConstructor; import org.bukkit.Bukkit; @@ -57,8 +58,9 @@ public SkillStealth() { registerAdvancement(AdaptAdvancement.builder() .icon(Material.LEATHER_LEGGINGS) .key("challenge_sneak_1k") - .title("Knee Pain") - .description("Sneak over a kilometer (1,000 blocks)") + .title(Localizer.dLocalize("advancement", "challenge_sneak_1k", "title")) + .description(Localizer.dLocalize("advancement", "challenge_sneak_1k", "description")) + .model(CustomModel.get(Material.LEATHER_LEGGINGS, "advancement", "stealth", "challenge_sneak_1k")) .frame(AdvancementFrameType.CHALLENGE) .visibility(AdvancementVisibility.PARENT_GRANTED) .build()); diff --git a/src/main/java/com/volmit/adapt/nms/GlowingEntities.java b/src/main/java/com/volmit/adapt/nms/GlowingEntities.java deleted file mode 100644 index 672e8319..00000000 --- a/src/main/java/com/volmit/adapt/nms/GlowingEntities.java +++ /dev/null @@ -1,1208 +0,0 @@ -package com.volmit.adapt.nms; - -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; -import io.netty.channel.*; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Location; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.HandlerList; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.plugin.Plugin; -import org.jetbrains.annotations.NotNull; -import java.lang.reflect.*; -import java.util.*; -import java.util.concurrent.ThreadLocalRandom; -import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import java.util.logging.LogRecord; -import java.util.logging.Logger; - -/** - * A Spigot util to easily make entities glow. - *

- * 1.17 -> 1.21 - * - * @version 1.3.5 - * @author SkytAsul - */ -public class GlowingEntities implements Listener { - - protected final @NotNull Plugin plugin; - private Map glowing; - boolean enabled = false; - - private int uid; - - /** - * Initializes the Glowing API. - * - * @param plugin plugin that will be used to register the events. - */ - public GlowingEntities(@NotNull Plugin plugin) { - if (!Packets.enabled) - throw new IllegalStateException( - "The Glowing Entities API is disabled. An error has occured during initialization."); - - this.plugin = Objects.requireNonNull(plugin); - - enable(); - } - - /** - * Enables the Glowing API. - * - * @see #disable() - */ - public void enable() { - if (enabled) - throw new IllegalStateException("The Glowing Entities API has already been enabled."); - - plugin.getServer().getPluginManager().registerEvents(this, plugin); - glowing = new HashMap<>(); - uid = ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE); - enabled = true; - } - - /** - * Disables the API. - *

- * Methods such as {@link #setGlowing(int, String, Player, ChatColor, byte)} and - * {@link #unsetGlowing(int, Player)} will no longer be usable. - * - * @see #enable() - */ - public void disable() { - if (!enabled) - return; - HandlerList.unregisterAll(this); - glowing.values().forEach(playerData -> { - try { - Packets.removePacketsHandler(playerData); - } catch (ReflectiveOperationException e) { - e.printStackTrace(); - } - }); - glowing = null; - uid = 0; - enabled = false; - } - - private void ensureEnabled() { - if (!enabled) - throw new IllegalStateException("The Glowing Entities API is not enabled."); - } - - @EventHandler - public void onQuit(PlayerQuitEvent event) { - glowing.remove(event.getPlayer()); - } - - /** - * Make the {@link Entity} passed as a parameter glow with its default team color. - * - * @param entity entity to make glow - * @param receiver player which will see the entity glowing - * @throws ReflectiveOperationException - */ - public void setGlowing(Entity entity, Player receiver) throws ReflectiveOperationException { - setGlowing(entity, receiver, null); - } - - /** - * Make the {@link Entity} passed as a parameter glow with the specified color. - * - * @param entity entity to make glow - * @param receiver player which will see the entity glowing - * @param color color of the glowing effect - * @throws ReflectiveOperationException - */ - public void setGlowing(Entity entity, Player receiver, ChatColor color) throws ReflectiveOperationException { - String teamID = entity instanceof Player ? entity.getName() : entity.getUniqueId().toString(); - setGlowing(entity.getEntityId(), teamID, receiver, color, Packets.getEntityFlags(entity)); - } - - /** - * Make the entity with specified entity ID glow with its default team color. - * - * @param entityID entity id of the entity to make glow - * @param teamID internal string used to add the entity to a team - * @param receiver player which will see the entity glowing - * @throws ReflectiveOperationException - */ - public void setGlowing(int entityID, String teamID, Player receiver) throws ReflectiveOperationException { - setGlowing(entityID, teamID, receiver, null, (byte) 0); - } - - /** - * Make the entity with specified entity ID glow with the specified color. - * - * @param entityID entity id of the entity to make glow - * @param teamID internal string used to add the entity to a team - * @param receiver player which will see the entity glowing - * @param color color of the glowing effect - * @throws ReflectiveOperationException - */ - public void setGlowing(int entityID, String teamID, Player receiver, ChatColor color) - throws ReflectiveOperationException { - setGlowing(entityID, teamID, receiver, color, (byte) 0); - } - - /** - * Make the entity with specified entity ID glow with the specified color, and keep some flags. - * - * @param entityID entity id of the entity to make glow - * @param teamID internal string used to add the entity to a team - * @param receiver player which will see the entity glowing - * @param color color of the glowing effect - * @param otherFlags internal flags that must be kept (on fire, crouching...). See - * wiki.vg for more informations. - * @throws ReflectiveOperationException - */ - public void setGlowing(int entityID, String teamID, Player receiver, ChatColor color, byte otherFlags) - throws ReflectiveOperationException { - ensureEnabled(); - if (color != null && !color.isColor()) - throw new IllegalArgumentException("ChatColor must be a color format"); - - PlayerData playerData = glowing.get(receiver); - if (playerData == null) { - playerData = new PlayerData(this, receiver); - Packets.addPacketsHandler(playerData); - glowing.put(receiver, playerData); - } - - GlowingData glowingData = playerData.glowingDatas.get(entityID); - if (glowingData == null) { - // the player did not have datas related to the entity: we must create the glowing status - glowingData = new GlowingData(playerData, entityID, teamID, color, otherFlags); - playerData.glowingDatas.put(entityID, glowingData); - - Packets.createGlowing(glowingData); - if (color != null) - Packets.setGlowingColor(glowingData); - } else { - // the player already had datas related to the entity: we must update the glowing status - - if (Objects.equals(glowingData.color, color)) - return; // nothing changed - - if (color == null) { - Packets.removeGlowingColor(glowingData); - glowingData.color = color; // we must set the color after in order to fetch the previous team - } else { - glowingData.color = color; - Packets.setGlowingColor(glowingData); - } - } - } - - /** - * Make the {@link Entity} passed as a parameter loose its custom glowing effect. - *

- * This has no effect on glowing status given by another plugin or vanilla behavior. - * - * @param entity entity to remove glowing effect from - * @param receiver player which will no longer see the glowing effect - * @throws ReflectiveOperationException - */ - public void unsetGlowing(Entity entity, Player receiver) throws ReflectiveOperationException { - unsetGlowing(entity.getEntityId(), receiver); - } - - /** - * Make the entity with specified entity ID passed as a parameter loose its custom glowing effect. - *

- * This has no effect on glowing status given by another plugin or vanilla behavior. - * - * @param entityID entity id of the entity to remove glowing effect from - * @param receiver player which will no longer see the glowing effect - * @throws ReflectiveOperationException - */ - public void unsetGlowing(int entityID, Player receiver) throws ReflectiveOperationException { - ensureEnabled(); - PlayerData playerData = glowing.get(receiver); - if (playerData == null) - return; // the player do not have any entity glowing - - GlowingData glowingData = playerData.glowingDatas.remove(entityID); - if (glowingData == null) - return; // the player did not have this entity glowing - - Packets.removeGlowing(glowingData); - - if (glowingData.color != null) - Packets.removeGlowingColor(glowingData); - - /* - * if (playerData.glowingDatas.isEmpty()) { //NOSONAR // if the player do not have any other entity - * glowing, // we can safely remove all of its data to free some memory - * Packets.removePacketsHandler(playerData); glowing.remove(receiver); } - */ - // actually no, we should not remove the player datas - // as it stores which teams did it receive. - // if we do not save this information, team would be created - // twice for the player, and BungeeCord does not like that - } - - private static class PlayerData { - - final GlowingEntities instance; - final Player player; - final Map glowingDatas; - ChannelHandler packetsHandler; - EnumSet sentColors; - - PlayerData(GlowingEntities instance, Player player) { - this.instance = instance; - this.player = player; - this.glowingDatas = new HashMap<>(); - } - - } - - private static class GlowingData { - // unfortunately this cannot be a Java Record - // as the "color" field is not final - - final PlayerData player; - final int entityID; - final String teamID; - ChatColor color; - byte otherFlags; - boolean enabled; - - GlowingData(PlayerData player, int entityID, String teamID, ChatColor color, byte otherFlags) { - this.player = player; - this.entityID = entityID; - this.teamID = teamID; - this.color = color; - this.otherFlags = otherFlags; - this.enabled = true; - } - - } - - protected static class Packets { - - private static final byte GLOWING_FLAG = 1 << 6; - - private static Cache packets = - CacheBuilder.newBuilder().expireAfterWrite(5, TimeUnit.SECONDS).build(); - private static Object dummy = new Object(); - - private static Logger logger; - private static int version; - private static int versionMinor; - private static String cpack = Bukkit.getServer().getClass().getPackage().getName() + "."; - private static ProtocolMappings mappings; - public static boolean enabled = false; - - private static Method getHandle; - private static Method getDataWatcher; - - // Synched datas - private static Object watcherObjectFlags; - private static Object watcherDummy; - private static Method watcherGet; - - private static Constructor watcherItemConstructor; - private static Method watcherItemObject; - private static Method watcherItemDataGet; - - private static Method watcherBCreator; - private static Method watcherBId; - private static Method watcherBSerializer; - private static Method watcherSerializerObject; - - // Networking - private static Field playerConnection; - private static Method sendPacket; - private static Field networkManager; - private static Field channelField; - private static Class packetBundle; - private static Method packetBundlePackets; - - // Metadata - private static Class packetMetadata; - private static Constructor packetMetadataConstructor; - private static Field packetMetadataEntity; - private static Field packetMetadataItems; - - // Teams - private static EnumMap teams = new EnumMap<>(ChatColor.class); - - private static Constructor createTeamPacket; - private static Constructor createTeamPacketData; - private static Constructor createTeam; - private static Object scoreboardDummy; - private static Object pushNever; - private static Method setTeamPush; - private static Method setTeamColor; - private static Method getColorConstant; - - // Entities - static Object shulkerEntityType; - private static Constructor packetAddEntity; - private static Constructor packetRemove; - private static Object vec3dZero; - - static { - try { - logger = new Logger("GlowingEntities", null) { - @Override - public void log(LogRecord logRecord) { - logRecord.setMessage("[GlowingEntities] " + logRecord.getMessage()); - super.log(logRecord); - } - }; - logger.setParent(Bukkit.getServer().getLogger()); - logger.setLevel(Level.ALL); - - // e.g. Bukkit.getBukkitVersion() -> 1.17.1-R0.1-SNAPSHOT - String[] versions = Bukkit.getBukkitVersion().split("-R")[0].split("\\."); - version = Integer.parseInt(versions[1]); - versionMinor = versions.length <= 2 ? 0 : Integer.parseInt(versions[2]); - logger.info("Found server version 1." + version + "." + versionMinor); - - boolean remapped = Bukkit.getServer().getClass().getPackage().getName().split("\\.").length == 3; - - mappings = ProtocolMappings.getMappings(version, versionMinor, remapped); - if (mappings == null) { - mappings = ProtocolMappings.getLast(remapped); - logger.warning("Loaded not matching version of the mappings for your server version"); - } - logger.info("Loaded mappings " + mappings.name()); - - /* Global variables */ - - Class entityClass = getNMSClass("world.entity", "Entity"); - Class entityTypesClass = getNMSClass("world.entity", "EntityTypes"); - Object markerEntity = getNMSClass("world.entity", "Marker").getDeclaredConstructors()[0] - .newInstance(getField(entityTypesClass, mappings.getMarkerTypeId(), null), null); - - getHandle = getCraftClass("entity", "CraftEntity").getDeclaredMethod("getHandle"); - getDataWatcher = entityClass.getDeclaredMethod(mappings.getWatcherAccessor()); - - /* Synched datas */ - - Class dataWatcherClass = getNMSClass("network.syncher", "DataWatcher"); - - if (version > 20 || (version == 20 && versionMinor >= 5)) { - var watcherBuilder = getNMSClass("network.syncher", "DataWatcher$a") - .getDeclaredConstructor(getNMSClass("network.syncher", "SyncedDataHolder")) - .newInstance(markerEntity); - Field watcherBuilderItems = watcherBuilder.getClass().getDeclaredField(remapped ? "itemsById" : "b"); - watcherBuilderItems.setAccessible(true); // NOSONAR idc - watcherBuilderItems.set(watcherBuilder, - Array.newInstance(watcherBuilderItems.getType().componentType(), 0)); - watcherDummy = - watcherBuilder.getClass().getDeclaredMethod(remapped ? "build" : "a").invoke(watcherBuilder); - } else { - var watcherConstructorArgsType = new Class[] {entityClass}; - var watcherConstructorArgs = new Object[] {markerEntity}; - watcherDummy = dataWatcherClass.getDeclaredConstructor(watcherConstructorArgsType) - .newInstance(watcherConstructorArgs); - } - - watcherObjectFlags = getField(entityClass, mappings.getWatcherFlags(), null); - watcherGet = dataWatcherClass.getDeclaredMethod(mappings.getWatcherGet(), watcherObjectFlags.getClass()); - - if (version < 19 || (version == 19 && versionMinor < 3)) { - Class watcherItem = getNMSClass("network.syncher", "DataWatcher$Item"); - watcherItemConstructor = watcherItem.getDeclaredConstructor(watcherObjectFlags.getClass(), Object.class); - watcherItemObject = watcherItem.getDeclaredMethod("a"); - watcherItemDataGet = watcherItem.getDeclaredMethod("b"); - } else { - String subclass = version > 20 || (version == 20 && versionMinor >= 5) ? "c" : "b"; - Class watcherB = getNMSClass("network.syncher", "DataWatcher$" + subclass); - watcherBCreator = watcherB.getDeclaredMethod("a", watcherObjectFlags.getClass(), Object.class); - watcherBId = watcherB.getDeclaredMethod("a"); - watcherBSerializer = watcherB.getDeclaredMethod("b"); - watcherItemDataGet = watcherB.getDeclaredMethod("c"); - watcherSerializerObject = - getNMSClass("network.syncher", "DataWatcherSerializer").getDeclaredMethod("a", int.class); - } - - /* Networking */ - - playerConnection = getField(getNMSClass("server.level", "EntityPlayer"), mappings.getPlayerConnection()); - sendPacket = getNMSClass("server.network", "PlayerConnection").getMethod(mappings.getSendPacket(), - getNMSClass("network.protocol", "Packet")); - networkManager = - getInheritedField(getNMSClass("server.network", "PlayerConnection"), mappings.getNetworkManager()); - channelField = getField(getNMSClass("network", "NetworkManager"), mappings.getChannel()); - - if (version > 19 || (version == 19 && versionMinor >= 4)) { - packetBundle = getNMSClass("network.protocol.game", "ClientboundBundlePacket"); - packetBundlePackets = - packetBundle.getMethod(version > 20 || (version == 20 && versionMinor >= 5) ? "b" : "a"); - } - - /* Metadata */ - - packetMetadata = getNMSClass("network.protocol.game", "PacketPlayOutEntityMetadata"); - packetMetadataEntity = getField(packetMetadata, mappings.getMetadataEntity()); - packetMetadataItems = getField(packetMetadata, mappings.getMetadataItems()); - if (version < 19 || (version == 19 && versionMinor < 3)) { - packetMetadataConstructor = - packetMetadata.getDeclaredConstructor(int.class, dataWatcherClass, boolean.class); - } else { - packetMetadataConstructor = packetMetadata.getDeclaredConstructor(int.class, List.class); - } - - /* Teams */ - - Class scoreboardClass = getNMSClass("world.scores", "Scoreboard"); - Class teamClass = getNMSClass("world.scores", "ScoreboardTeam"); - Class pushClass = getNMSClass("world.scores", "ScoreboardTeamBase$EnumTeamPush"); - Class chatFormatClass = getNMSClass("EnumChatFormat"); - - createTeamPacket = getNMSClass("network.protocol.game", "PacketPlayOutScoreboardTeam") - .getDeclaredConstructor(String.class, int.class, Optional.class, Collection.class); - createTeamPacket.setAccessible(true); - createTeamPacketData = getNMSClass("network.protocol.game", "PacketPlayOutScoreboardTeam$b") - .getDeclaredConstructor(teamClass); - createTeam = teamClass.getDeclaredConstructor(scoreboardClass, String.class); - scoreboardDummy = scoreboardClass.getDeclaredConstructor().newInstance(); - pushNever = pushClass.getDeclaredField("b").get(null); - setTeamPush = teamClass.getDeclaredMethod(mappings.getTeamSetCollision(), pushClass); - setTeamColor = teamClass.getDeclaredMethod(mappings.getTeamSetColor(), chatFormatClass); - getColorConstant = chatFormatClass.getDeclaredMethod("a", char.class); - - /* Entities */ - - Class shulkerClass = getNMSClass("world.entity.monster", "EntityShulker"); - for (Field field : entityTypesClass.getDeclaredFields()) { - if (field.getType() != entityTypesClass) - continue; - - ParameterizedType fieldType = (ParameterizedType) field.getGenericType(); - if (fieldType.getActualTypeArguments()[0] == shulkerClass) { - shulkerEntityType = field.get(null); - break; - } - } - if (shulkerEntityType == null) - throw new IllegalStateException(); - - Class vec3dClass = getNMSClass("world.phys", "Vec3D"); - vec3dZero = vec3dClass.getConstructor(double.class, double.class, double.class).newInstance(0d, 0d, 0d); - - - // arg10 was added after version 1.18.2 - if (version >= 19) { - packetAddEntity = getNMSClass("network.protocol.game", "PacketPlayOutSpawnEntity") - .getDeclaredConstructor(int.class, UUID.class, double.class, double.class, double.class, float.class, - float.class, entityTypesClass, int.class, vec3dClass, double.class); - } else { - packetAddEntity = getNMSClass("network.protocol.game", "PacketPlayOutSpawnEntity") - .getDeclaredConstructor(int.class, UUID.class, double.class, double.class, double.class, float.class, - float.class, entityTypesClass, int.class, vec3dClass); - } - - - packetRemove = getNMSClass("network.protocol.game", "PacketPlayOutEntityDestroy") - .getDeclaredConstructor(version == 17 && versionMinor == 0 ? int.class : int[].class); - - enabled = true; - } catch (Exception ex) { - String errorMsg = - "Glowing Entities reflection failed to initialize. The util is disabled. Please ensure your version (" - + Bukkit.getServer().getClass().getPackage().getName() + ") is supported."; - if (logger == null) { - ex.printStackTrace(); - System.err.println(errorMsg); - } else { - logger.log(Level.SEVERE, errorMsg, ex); - } - } - } - - public static void sendPackets(Player p, Object... packets) throws ReflectiveOperationException { - Object connection = playerConnection.get(getHandle.invoke(p)); - for (Object packet : packets) { - if (packet == null) - continue; - sendPacket.invoke(connection, packet); - } - } - - public static byte getEntityFlags(Entity entity) throws ReflectiveOperationException { - Object nmsEntity = getHandle.invoke(entity); - Object dataWatcher = getDataWatcher.invoke(nmsEntity); - return (byte) watcherGet.invoke(dataWatcher, watcherObjectFlags); - } - - public static void createGlowing(GlowingData glowingData) throws ReflectiveOperationException { - setMetadata(glowingData.player.player, glowingData.entityID, computeFlags(glowingData), true); - } - - private static byte computeFlags(GlowingData glowingData) { - byte newFlags = glowingData.otherFlags; - if (glowingData.enabled) { - newFlags |= GLOWING_FLAG; - } else { - newFlags &= ~GLOWING_FLAG; - } - return newFlags; - } - - public static Object createFlagWatcherItem(byte newFlags) throws ReflectiveOperationException { - return watcherItemConstructor != null ? watcherItemConstructor.newInstance(watcherObjectFlags, newFlags) - : watcherBCreator.invoke(null, watcherObjectFlags, newFlags); - } - - public static void removeGlowing(GlowingData glowingData) throws ReflectiveOperationException { - setMetadata(glowingData.player.player, glowingData.entityID, glowingData.otherFlags, true); - } - - public static void updateGlowingState(GlowingData glowingData) throws ReflectiveOperationException { - if (glowingData.enabled) - createGlowing(glowingData); - else - removeGlowing(glowingData); - } - - @SuppressWarnings("squid:S3011") - public static void setMetadata(Player player, int entityId, byte flags, boolean ignore) - throws ReflectiveOperationException { - List dataItems = new ArrayList<>(1); - dataItems.add(watcherItemConstructor != null ? watcherItemConstructor.newInstance(watcherObjectFlags, flags) - : watcherBCreator.invoke(null, watcherObjectFlags, flags)); - - Object packetMetadata; - if (version < 19 || (version == 19 && versionMinor < 3)) { - packetMetadata = packetMetadataConstructor.newInstance(entityId, watcherDummy, false); - packetMetadataItems.set(packetMetadata, dataItems); - } else { - packetMetadata = packetMetadataConstructor.newInstance(entityId, dataItems); - } - if (ignore) - packets.put(packetMetadata, dummy); - sendPackets(player, packetMetadata); - } - - public static void setGlowingColor(GlowingData glowingData) throws ReflectiveOperationException { - boolean sendCreation = false; - if (glowingData.player.sentColors == null) { - glowingData.player.sentColors = EnumSet.of(glowingData.color); - sendCreation = true; - } else if (glowingData.player.sentColors.add(glowingData.color)) { - sendCreation = true; - } - - TeamData teamData = teams.get(glowingData.color); - if (teamData == null) { - teamData = new TeamData(glowingData.player.instance.uid, glowingData.color); - teams.put(glowingData.color, teamData); - } - - Object entityAddPacket = teamData.getEntityAddPacket(glowingData.teamID); - if (sendCreation) { - sendPackets(glowingData.player.player, teamData.creationPacket, entityAddPacket); - } else { - sendPackets(glowingData.player.player, entityAddPacket); - } - } - - public static void removeGlowingColor(GlowingData glowingData) throws ReflectiveOperationException { - TeamData teamData = teams.get(glowingData.color); - if (teamData == null) - return; // must not happen; this means the color has not been set previously - - sendPackets(glowingData.player.player, teamData.getEntityRemovePacket(glowingData.teamID)); - } - - public static void createEntity(Player player, int entityId, UUID entityUuid, Object entityType, Location location) - throws IllegalArgumentException, ReflectiveOperationException { - Object packet; - if (version >= 19) { - packet = packetAddEntity.newInstance(entityId, entityUuid, location.getX(), location.getY(), - location.getZ(), location.getPitch(), location.getYaw(), entityType, 0, vec3dZero, 0d); - } else { - packet = packetAddEntity.newInstance(entityId, entityUuid, location.getX(), location.getY(), - location.getZ(), location.getPitch(), location.getYaw(), entityType, 0, vec3dZero); - } - sendPackets(player, packet); - } - - public static void removeEntities(Player player, int... entitiesId) throws ReflectiveOperationException { - Object[] packets; - if (version == 17 && versionMinor == 0) { - packets = new Object[entitiesId.length]; - for (int i = 0; i < entitiesId.length; i++) { - packets[i] = packetRemove.newInstance(entitiesId[i]); - } - } else { - packets = new Object[] {packetRemove.newInstance(entitiesId)}; - } - - sendPackets(player, packets); - } - - private static Channel getChannel(Player player) throws ReflectiveOperationException { - return (Channel) channelField.get(networkManager.get(playerConnection.get(getHandle.invoke(player)))); - } - - public static void addPacketsHandler(PlayerData playerData) throws ReflectiveOperationException { - playerData.packetsHandler = new ChannelDuplexHandler() { - @Override - public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - if (msg.getClass().equals(packetMetadata) && packets.asMap().remove(msg) == null) { - int entityID = packetMetadataEntity.getInt(msg); - GlowingData glowingData = playerData.glowingDatas.get(entityID); - if (glowingData != null) { - - List items = (List) packetMetadataItems.get(msg); - if (items != null) { - - boolean containsFlags = false; - boolean edited = false; - for (int i = 0; i < items.size(); i++) { - Object item = items.get(i); - Object watcherObject; - if (watcherItemObject != null) { - watcherObject = watcherItemObject.invoke(item); - } else { - Object serializer = watcherBSerializer.invoke(item); - watcherObject = watcherSerializerObject.invoke(serializer, watcherBId.invoke(item)); - } - - if (watcherObject.equals(watcherObjectFlags)) { - containsFlags = true; - byte flags = (byte) watcherItemDataGet.invoke(item); - glowingData.otherFlags = flags; - byte newFlags = computeFlags(glowingData); - if (newFlags != flags) { - edited = true; - items = new ArrayList<>(items); - // we cannot simply edit the item as it may be backed in the datawatcher, so we - // make a copy of the list - items.set(i, createFlagWatcherItem(newFlags)); - break; - // we can break right now as the "flags" datawatcher object may not be present - // twice in the same packet - } - } - } - - if (!edited && !containsFlags) { - // if the packet does not contain any flag information, we are unsure if it is a packet - // simply containing informations about another object's data update OR if it is a packet - // containing all non-default informations of the entity. Such as packet can be sent when - // the player has got far away from the entity and come in sight distance again. - // In this case, we must add manually the "flags" object, otherwise it would stay 0 and - // the entity would not be glowing. - // Ideally, we should listen for an "entity add" packet to be sure we are in the case - // above, but honestly it's annoying because there are multiple types of "entity add" - // packets, so we do like this instead. Less performant, but not by far. - byte flags = computeFlags(glowingData); - if (flags != 0) { - edited = true; - items = new ArrayList<>(items); - items.add(createFlagWatcherItem(flags)); - } - } - - if (edited) { - // some of the metadata packets are broadcasted to all players near the target entity. - // hence, if we directly edit the packet, some users that were not intended to see the - // glowing color will be able to see it. We should send a new packet to the viewer only. - - Object newMsg; - if (version < 19 || (version == 19 && versionMinor < 3)) { - newMsg = packetMetadataConstructor.newInstance(entityID, watcherDummy, false); - packetMetadataItems.set(newMsg, items); - } else { - newMsg = packetMetadataConstructor.newInstance(entityID, items); - } - packets.put(newMsg, dummy); - sendPackets(playerData.player, newMsg); - - return; // we cancel the send of this packet - } - } - } - } else if (packetBundle != null && msg.getClass().equals(packetBundle)) { - handlePacketBundle(msg); - } - super.write(ctx, msg, promise); - } - - @SuppressWarnings("rawtypes") - private void handlePacketBundle(Object bundle) throws ReflectiveOperationException { - Iterable subPackets = (Iterable) packetBundlePackets.invoke(bundle); - for (Iterator iterator = subPackets.iterator(); iterator.hasNext();) { - Object packet = iterator.next(); - - if (packet.getClass().equals(packetMetadata)) { - int entityID = packetMetadataEntity.getInt(packet); - GlowingData glowingData = playerData.glowingDatas.get(entityID); - if (glowingData != null) { - // means the bundle packet contains metadata about an entity that must be glowing. - // editing a bundle packet is annoying, so we'll let it go to the player - // and then send a metadata packet containing the correct glowing flag. - - Bukkit.getScheduler().runTaskLaterAsynchronously(playerData.instance.plugin, () -> { - try { - updateGlowingState(glowingData); - } catch (ReflectiveOperationException e) { - e.printStackTrace(); - } - }, 1L); - return; - } - } - } - } - - }; - - getChannel(playerData.player).pipeline().addBefore("packet_handler", null, playerData.packetsHandler); - } - - public static void removePacketsHandler(PlayerData playerData) throws ReflectiveOperationException { - if (playerData.packetsHandler != null) { - getChannel(playerData.player).pipeline().remove(playerData.packetsHandler); - } - } - - /* Reflection utils */ - @Deprecated - private static Object getField(Class clazz, String name, Object instance) throws ReflectiveOperationException { - return getField(clazz, name).get(instance); - } - - private static Field getField(Class clazz, String name) throws ReflectiveOperationException { - Field field = clazz.getDeclaredField(name); - field.setAccessible(true); - return field; - } - - private static Field getInheritedField(Class clazz, String name) throws ReflectiveOperationException { - Class superclass = clazz; - do { - try { - Field field = superclass.getDeclaredField(name); - field.setAccessible(true); - return field; - } catch (NoSuchFieldException ex) { - } - } while ((superclass = clazz.getSuperclass()) != null); - - // if we are here this means the field is not in superclasses - throw new NoSuchFieldException(name); - } - - private static Class getCraftClass(String craftPackage, String className) throws ClassNotFoundException { - return Class.forName(cpack + craftPackage + "." + className); - } - - private static Class getNMSClass(String className) throws ClassNotFoundException { - return Class.forName("net.minecraft." + className); - } - - private static Class getNMSClass(String nmPackage, String className) throws ClassNotFoundException { - return Class.forName("net.minecraft." + nmPackage + "." + className); - } - - private static class TeamData { - - private final String id; - private final Object creationPacket; - - private final Cache addPackets = - CacheBuilder.newBuilder().expireAfterAccess(3, TimeUnit.MINUTES).build(); - private final Cache removePackets = - CacheBuilder.newBuilder().expireAfterAccess(3, TimeUnit.MINUTES).build(); - - public TeamData(int uid, ChatColor color) throws ReflectiveOperationException { - if (!color.isColor()) - throw new IllegalArgumentException(); - id = "glow-" + uid + color.getChar(); - Object team = createTeam.newInstance(scoreboardDummy, id); - setTeamPush.invoke(team, pushNever); - setTeamColor.invoke(team, getColorConstant.invoke(null, color.getChar())); - Object packetData = createTeamPacketData.newInstance(team); - creationPacket = createTeamPacket.newInstance(id, 0, Optional.of(packetData), Collections.EMPTY_LIST); - } - - public Object getEntityAddPacket(String teamID) throws ReflectiveOperationException { - Object packet = addPackets.getIfPresent(teamID); - if (packet == null) { - packet = createTeamPacket.newInstance(id, 3, Optional.empty(), Arrays.asList(teamID)); - addPackets.put(teamID, packet); - } - return packet; - } - - public Object getEntityRemovePacket(String teamID) throws ReflectiveOperationException { - Object packet = removePackets.getIfPresent(teamID); - if (packet == null) { - packet = createTeamPacket.newInstance(id, 4, Optional.empty(), Arrays.asList(teamID)); - removePackets.put(teamID, packet); - } - return packet; - } - - } - - private enum ProtocolMappings { - - V1_17( - 17, - 0, - false, - "Z", - "Y", - "getDataWatcher", - "get", - "b", - "a", - "sendPacket", - "k", - "setCollisionRule", - "setColor", - "a", - "b"), - V1_18( - 18, - 0, - false, - "Z", - "Y", - "ai", - "a", - "b", - "a", - "a", - "m", - "a", - "a", - "a", - "b"), - V1_19( - 19, - 0, - false, - "Z", - "ab", - "ai", - null, - "b", - "b", - "a", - "m", - "a", - "a", - "a", - "b"), - V1_19_3( - 19, - 3, - false, - null, - null, - "al", - null, - null, - null, - null, - null, - null, - null, - "b", - "c"), - V1_19_4( - 19, - 4, - false, - "an", - null, - "aj", - null, - null, - "h", - null, - null, - null, - null, - null, - null), - V1_20( - 20, - 0, - false, - "an", - "am", - "aj", - "b", - "c", - "h", - "a", - "m", - "a", - "a", - "b", - "c"), - V1_20_2( - 20, - 2, - false, - "ao", - null, - "al", - null, - null, - "c", - "b", - "n", - null, - null, - null, - null), - V1_20_3( - 20, - 3, - false, - null, - "an", - "an", - null, - null, - null, - null, - null, - null, - null, - null, - null), - V1_20_5( - 20, - 5, - false, - "ap", - "aq", - "ap", - "a", - null, - "e", - null, - null, - null, - null, - "c", - "d"), - V1_20_5_REMAPPED( - 20, - 5, - true, - "DATA_SHARED_FLAGS_ID", - "MARKER", - "getEntityData", - "get", - "connection", - "connection", - "send", - "channel", - "setCollisionRule", - "setColor", - "id", - "packedItems" - ), - V1_21( - 21, - 0, - false, - null, - null, - "ar", - null, - null, - null, - null, - null, - null, - null, - null, - null - ), - V1_21_REMAPPED( - 21, - 0, - true, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null - ) - ; - - private final int major, minor; - private final boolean remapped; - private String watcherFlags; - private String markerTypeId; - private String watcherAccessor; - private String watcherGet; - private String playerConnection; - private String networkManager; - private String sendPacket; - private String channel; - private String teamSetCollsion; - private String teamSetColor; - private String metadataEntity; - private String metadataItems; - - private ProtocolMappings(int major, int minor, boolean remapped, - String watcherFlags, String markerTypeId, String watcherAccessor, String watcherGet, - String playerConnection, String networkManager, String sendPacket, String channel, - String teamSetCollsion, String teamSetColor, String metdatataEntity, String metadataItems) { - this.major = major; - this.minor = minor; - this.remapped = remapped; - this.watcherFlags = watcherFlags; - this.markerTypeId = markerTypeId; - this.watcherAccessor = watcherAccessor; - this.watcherGet = watcherGet; - this.playerConnection = playerConnection; - this.networkManager = networkManager; - this.sendPacket = sendPacket; - this.channel = channel; - this.teamSetCollsion = teamSetCollsion; - this.teamSetColor = teamSetColor; - this.metadataEntity = metdatataEntity; - this.metadataItems = metadataItems; - } - - public int getMajor() { - return major; - } - - public int getMinor() { - return minor; - } - - public boolean isRemapped() { - return remapped; - } - - public String getWatcherFlags() { - return watcherFlags; - } - - public String getMarkerTypeId() { - return markerTypeId; - } - - public String getWatcherAccessor() { - return watcherAccessor; - } - - public String getWatcherGet() { - return watcherGet; - } - - public String getPlayerConnection() { - return playerConnection; - } - - public String getNetworkManager() { - return networkManager; - } - - public String getSendPacket() { - return sendPacket; - } - - public String getChannel() { - return channel; - } - - public String getTeamSetCollision() { - return teamSetCollsion; - } - - public String getTeamSetColor() { - return teamSetColor; - } - - public String getMetadataEntity() { - return metadataEntity; - } - - public String getMetadataItems() { - return metadataItems; - } - - static { - try { - fillAll(); - } catch (ReflectiveOperationException ex) { - logger.severe("Failed to fill up all datas for mappings."); - ex.printStackTrace(); - } - } - - private static void fillAll() throws ReflectiveOperationException { - ProtocolMappings lastUnmapped = V1_17; - ProtocolMappings lastRemapped = V1_20_5_REMAPPED; - // /!\ we start at 1 - for (int i = 1; i < ProtocolMappings.values().length; i++) { - ProtocolMappings map = ProtocolMappings.values()[i]; - for (Field field : ProtocolMappings.class.getDeclaredFields()) { - if (field.getType() == String.class && field.get(map) == null) { - field.set(map, field.get(map.isRemapped() ? lastRemapped : lastUnmapped)); - } - } - if (map.isRemapped()) - lastRemapped = map; - else - lastUnmapped = map; - } - } - - public static ProtocolMappings getMappings(int major, int minor, boolean remapped) { - ProtocolMappings lastGood = null; - for (ProtocolMappings map : values()) { - if (map.isRemapped() != remapped) - continue; - - // loop in ascending version order - if (major == map.getMajor()) { - if (minor == map.getMinor()) - return map; // perfect match - - if (minor > map.getMinor()) - lastGood = map; // looking for newer minor version - - if (minor < map.getMinor()) - return lastGood; // looking for older minor version: we get the last correct one - } - } - // will return either null if no mappings matched the major => fallback to latest major with a - // warning, either the last mappings with same major and smaller minor - return lastGood; - } - - public static ProtocolMappings getLast(boolean remapped) { - return Arrays.stream(values()).filter(map -> map.isRemapped() == remapped).reduce((l, r) -> r).get(); - } - - } - - } - -} \ No newline at end of file diff --git a/src/main/java/com/volmit/adapt/util/BurstExecutor.java b/src/main/java/com/volmit/adapt/util/BurstExecutor.java index 9919e7bc..9c312f9f 100644 --- a/src/main/java/com/volmit/adapt/util/BurstExecutor.java +++ b/src/main/java/com/volmit/adapt/util/BurstExecutor.java @@ -55,7 +55,7 @@ public BurstExecutor queue(Runnable[] r) { public void complete() { synchronized (futures) { try { - CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])).get(); + CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).get(); futures.clear(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); diff --git a/src/main/java/com/volmit/adapt/util/C.java b/src/main/java/com/volmit/adapt/util/C.java index 0b268ea0..5023dd64 100644 --- a/src/main/java/com/volmit/adapt/util/C.java +++ b/src/main/java/com/volmit/adapt/util/C.java @@ -18,6 +18,8 @@ package com.volmit.adapt.util; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.TextComponent; import org.apache.commons.lang3.Validate; import org.bukkit.ChatColor; import org.bukkit.Color; @@ -28,8 +30,6 @@ import java.util.Map; import java.util.regex.Pattern; -import static com.volmit.adapt.util.LZString.compress; - /** * Colors * @@ -192,7 +192,7 @@ public net.md_5.bungee.api.ChatColor asBungee() { /** * Represents magical characters that change around randomly */ - MAGIC('k', 0x10, true) { + MAGIC("", 'k', 0x10, true) { @Override public net.md_5.bungee.api.ChatColor asBungee() { return net.md_5.bungee.api.ChatColor.MAGIC; @@ -219,7 +219,7 @@ public net.md_5.bungee.api.ChatColor asBungee() { /** * Makes the text appear underlined. */ - UNDERLINE('n', 0x13, true) { + UNDERLINE("", 'n', 0x13, true) { @Override public net.md_5.bungee.api.ChatColor asBungee() { return net.md_5.bungee.api.ChatColor.UNDERLINE; @@ -243,8 +243,10 @@ public net.md_5.bungee.api.ChatColor asBungee() { public net.md_5.bungee.api.ChatColor asBungee() { return net.md_5.bungee.api.ChatColor.RESET; } - }; + }, + + ; /** * The special character which prefixes all chat colour codes. Use this if you * need to dynamically convert colour codes from your custom format. @@ -253,30 +255,31 @@ public net.md_5.bungee.api.ChatColor asBungee() { public final static C[] COLORCYCLE = new C[]{C.GOLD, C.YELLOW, C.GREEN, C.AQUA, C.LIGHT_PURPLE, C.AQUA, C.GREEN, C.YELLOW, C.GOLD, C.RED}; private static final Pattern STRIP_COLOR_PATTERN = Pattern.compile("(?i)" + COLOR_CHAR + "[0-9A-FK-OR]"); private final static C[] COLORS = new C[]{C.BLACK, C.DARK_BLUE, C.DARK_GREEN, C.DARK_AQUA, C.DARK_RED, C.DARK_PURPLE, C.GOLD, C.GRAY, C.DARK_GRAY, C.BLUE, C.GREEN, C.AQUA, C.RED, C.LIGHT_PURPLE, C.YELLOW, C.WHITE}; - private final static Map BY_ID = new HashMap(); - private final static Map BY_CHAR = new HashMap(); - private final static Map dyeChatMap = new HashMap(); - private final static Map chatHexMap = new HashMap(); - private final static Map dyeHexMap = new HashMap(); + @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") + private final static Map BY_ID = new HashMap<>(); + private final static Map BY_CHAR = new HashMap<>(); + private final static Map dyeChatMap = new HashMap<>(); + private final static Map chatHexMap = new HashMap<>(); + private final static Map dyeHexMap = new HashMap<>(); static { - chatHexMap.put(C.BLACK, "#000"); - chatHexMap.put(C.DARK_BLUE, "#00a"); - chatHexMap.put(C.DARK_GREEN, "#0a0"); - chatHexMap.put(C.DARK_AQUA, "#0aa"); - chatHexMap.put(C.DARK_RED, "#a00"); - chatHexMap.put(C.ADAPT, "#a00"); - chatHexMap.put(C.DARK_PURPLE, "#a0a"); - chatHexMap.put(C.GOLD, "#fa0"); - chatHexMap.put(C.GRAY, "#999"); - chatHexMap.put(C.DARK_GRAY, "#555"); - chatHexMap.put(C.BLUE, "#55f"); - chatHexMap.put(C.GREEN, "#5c5"); - chatHexMap.put(C.AQUA, "#5cc"); - chatHexMap.put(C.RED, "#f55"); - chatHexMap.put(C.LIGHT_PURPLE, "#f5f"); - chatHexMap.put(C.YELLOW, "#cc5"); - chatHexMap.put(C.WHITE, "#aaa"); + chatHexMap.put(C.BLACK, "#000000"); + chatHexMap.put(C.DARK_BLUE, "#0000AA"); + chatHexMap.put(C.DARK_GREEN, "#00AA00"); + chatHexMap.put(C.DARK_AQUA, "#00AAAA"); + chatHexMap.put(C.DARK_RED, "#AA0000"); + chatHexMap.put(C.ADAPT, "#AA0000"); + chatHexMap.put(C.DARK_PURPLE, "#AA00AA"); + chatHexMap.put(C.GOLD, "#FFAA00"); + chatHexMap.put(C.GRAY, "#AAAAAA"); + chatHexMap.put(C.DARK_GRAY, "#555555"); + chatHexMap.put(C.BLUE, "#5555FF"); + chatHexMap.put(C.GREEN, "#55FF55"); + chatHexMap.put(C.AQUA, "#55FFFF"); + chatHexMap.put(C.RED, "#FF5555"); + chatHexMap.put(C.LIGHT_PURPLE, "#FF55FF"); + chatHexMap.put(C.YELLOW, "#FFFF55"); + chatHexMap.put(C.WHITE, "#FFFFFF"); dyeChatMap.put(DyeColor.BLACK, C.DARK_GRAY); dyeChatMap.put(DyeColor.BLUE, C.DARK_BLUE); dyeChatMap.put(DyeColor.BROWN, C.GOLD); @@ -320,8 +323,8 @@ public net.md_5.bungee.api.ChatColor asBungee() { private final int intCode; private final char code; - private final boolean isFormat; private final String token; + private final boolean isFormat; private final String toString; C(char code, int intCode) { @@ -333,7 +336,7 @@ public net.md_5.bungee.api.ChatColor asBungee() { } C(char code, int intCode, boolean isFormat) { - this("^", code, intCode, isFormat); + this("^", code, intCode, false); } C(String token, char code, int intCode, boolean isFormat) { @@ -344,6 +347,80 @@ public net.md_5.bungee.api.ChatColor asBungee() { this.toString = new String(new char[]{COLOR_CHAR, code}); } + public static float[] spin(float[] c, int shift) { + return new float[]{spin(c[0], shift), spinc(c[1], shift), spinc(c[2], shift)}; + } + + public static float[] spin(float[] c, int a, int b, int d) { + return new float[]{spin(c[0], a), spinc(c[1], b), spinc(c[2], d)}; + } + + public static float spin(float c, int shift) { + float g = ((((int) Math.floor(c * 360)) + shift) % 360) / 360F; + return g < 0 ? 1f - g : g; + } + + public static float spinc(float c, int shift) { + float g = ((((int) Math.floor(c * 255)) + shift)) / 255F; + return Math.max(0f, Math.min(g, 1f)); + } + + public static java.awt.Color spin(java.awt.Color c, int h, int s, int b) { + float[] hsb = java.awt.Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null); + hsb = spin(hsb, h, s, b); + return java.awt.Color.getHSBColor(hsb[0], hsb[1], hsb[2]); + } + + public static String spinToHex(C color, int h, int s, int b) { + return "#" + Integer.toHexString(spin(color.awtColor(), h, s, b).getRGB()).substring(2); + } + + public static String aura(String s, int hrad, int srad, int vrad) { + return aura(s, hrad, srad, vrad, 0.3D); + } + + public static String aura(String s, int hrad, int srad, int vrad, double pulse) { + String msg = compress(s); + StringBuilder b = new StringBuilder(); + boolean c = false; + + for (char i : msg.toCharArray()) { + if (c) { + c = false; + + C o = C.getByChar(i); + + if (hrad != 0 || srad != 0 || vrad != 0) { + if (pulse > 0) { + b.append(VolmitSender.pulse(spinToHex(o, hrad, srad, vrad), spinToHex(o, -hrad, -srad, -vrad), pulse)); + } else { + b.append(""); + } + } else { + b.append(C.getByChar(i).token); + } + + continue; + } + + if (i == C.COLOR_CHAR) { + c = true; + continue; + } + + b.append(i); + } + + return b.toString(); + } + + public static String compress(String c) { + return BaseComponent.toLegacyText(TextComponent.fromLegacyText(c)); + } /** * Gets the color represented by the specified color code @@ -354,7 +431,8 @@ public net.md_5.bungee.api.ChatColor asBungee() { */ public static C getByChar(char code) { try { - return BY_CHAR.get(code); + C c = BY_CHAR.get(code); + return c == null ? C.WHITE : c; } catch (Exception e) { return C.WHITE; } @@ -407,9 +485,9 @@ public static C dyeToChat(DyeColor dclr) { } public static DyeColor chatToDye(ChatColor color) { - for (DyeColor i : dyeChatMap.keySet()) { - if (dyeChatMap.get(i).toString().equals(color.toString())) { - return i; + for (Map.Entry entry : dyeChatMap.entrySet()) { + if (entry.getValue().toString().equals(color.toString())) { + return entry.getKey(); } } @@ -417,12 +495,12 @@ public static DyeColor chatToDye(ChatColor color) { } @SuppressWarnings("unlikely-arg-type") - public static String chatToHex(ChatColor clr) { + public static String chatToHex(C clr) { if (chatHexMap.containsKey(clr)) { return chatHexMap.get(clr); } - return "#000"; + return "#000000"; } public static String dyeToHex(DyeColor clr) { @@ -430,7 +508,7 @@ public static String dyeToHex(DyeColor clr) { return dyeHexMap.get(clr); } - return "#000"; + return "#000000"; } public static Color hexToColor(String hex) { @@ -438,7 +516,7 @@ public static Color hexToColor(String hex) { hex = hex.substring(1); } - if (hex.indexOf("x") != -1) { + if (hex.contains("x")) { hex = hex.substring(hex.indexOf("x")); } @@ -454,81 +532,6 @@ public static Color hexToColor(String hex) { return Color.fromBGR(x & 0xffffff); } - public java.awt.Color awtColor() { - return java.awt.Color.decode(hex()); - } - - public static float[] spin(float[] c, int shift) { - return new float[]{spin(c[0], shift), spinc(c[1], shift), spinc(c[2], shift)}; - } - - public static float[] spin(float[] c, int a, int b, int d) { - return new float[]{spin(c[0], a), spinc(c[1], b), spinc(c[2], d)}; - } - - public static float spin(float c, int shift) { - float g = ((((int) Math.floor(c * 360)) + shift) % 360) / 360F; - return g < 0 ? 1f - g : g; - } - - public static float spinc(float c, int shift) { - float g = ((((int) Math.floor(c * 255)) + shift)) / 255F; - return Math.max(0f, Math.min(g, 1f)); - } - - public static java.awt.Color spin(java.awt.Color c, int h, int s, int b) { - float[] hsb = java.awt.Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null); - hsb = spin(hsb, h, s, b); - return java.awt.Color.getHSBColor(hsb[0], hsb[1], hsb[2]); - } - - public static String spinToHex(C color, int h, int s, int b) { - return "#" + Integer.toHexString(spin(color.awtColor(), h, s, b).getRGB()).substring(2); - } - - public static String aura(String s, int hrad, int srad, int vrad) { - return aura(s, hrad, srad, vrad, 0.3D); - } - - public static String aura(String s, int hrad, int srad, int vrad, double pulse) { - String msg = compress(s); - StringBuilder b = new StringBuilder(); - boolean c = false; - - for (char i : msg.toCharArray()) { - if (c) { - c = false; - - C o = C.getByChar(i); - - if (hrad != 0 || srad != 0 || vrad != 0) { - if (pulse > 0) { - b.append(VolmitSender.pulse(spinToHex(o, hrad, srad, vrad), spinToHex(o, -hrad, -srad, -vrad), pulse)); - } else { - b.append(""); - } - } else { - b.append(C.getByChar(i).token); - } - - continue; - } - - if (i == C.COLOR_CHAR) { - c = true; - continue; - } - - b.append(i); - } - - return b.toString(); - } - public static Color rgbToColor(String rgb) { String[] parts = rgb.split("[^0-9]+"); if (parts.length < 3) { @@ -610,7 +613,7 @@ public static C randomColor() { * @return Any remaining ChatColors to pass onto the next line. */ public static String getLastColors(String input) { - String result = ""; + StringBuilder result = new StringBuilder(); int length = input.length(); // Search backwards from the end as it is faster @@ -621,7 +624,7 @@ public static String getLastColors(String input) { C color = getByChar(c); if (color != null) { - result = color + result; + result.insert(0, color); // Once we find a color or reset we can stop searching if (color.isColor() || color.equals(RESET)) { @@ -631,7 +634,7 @@ public static String getLastColors(String input) { } } - return result; + return result.toString(); } public net.md_5.bungee.api.ChatColor asBungee() { @@ -660,7 +663,11 @@ public DyeColor dye() { } public String hex() { - return chatToHex(chatColor()); + return chatToHex(this); + } + + public java.awt.Color awtColor() { + return java.awt.Color.decode(hex()); } /** @@ -689,104 +696,42 @@ public ChatColor chatColor() { } public byte getMeta() { - switch (this) { - case AQUA: - return 11; - case BLACK: - return 0; - case BLUE: - return 9; - case BOLD: - return -1; - case DARK_AQUA: - return 9; - case DARK_BLUE: - return 1; - case DARK_GRAY: - return 8; - case DARK_GREEN: - return 2; - case DARK_PURPLE: - return 5; - case DARK_RED: - return 4; - case GOLD: - return 6; - case GRAY: - return 7; - case GREEN: - return 10; - case ITALIC: - return -1; - case LIGHT_PURPLE: - return 13; - case MAGIC: - return -1; - case RED: - return 12; - case RESET: - return -1; - case STRIKETHROUGH: - return -1; - case UNDERLINE: - return -1; - case WHITE: - return 15; - case YELLOW: - return 14; - default: - return -1; - } + return switch (this) { + case AQUA -> (byte) 11; + case BLACK -> (byte) 0; + case BLUE, DARK_AQUA -> (byte) 9; + case BOLD, UNDERLINE, STRIKETHROUGH, RESET, MAGIC, ITALIC -> (byte) -1; + case DARK_BLUE -> (byte) 1; + case DARK_GRAY -> (byte) 8; + case DARK_GREEN -> (byte) 2; + case DARK_PURPLE -> (byte) 5; + case DARK_RED -> (byte) 4; + case GOLD -> (byte) 6; + case GRAY -> (byte) 7; + case GREEN -> (byte) 10; + case LIGHT_PURPLE -> (byte) 13; + case RED -> (byte) 12; + case YELLOW -> (byte) 14; + default -> (byte) 15; + }; } public byte getItemMeta() { - switch (this) { - case AQUA: - return 9; - case BLACK: - return 15; - case BLUE: - return 3; - case BOLD: - return -1; - case DARK_AQUA: - return 9; - case DARK_BLUE: - return 11; - case DARK_GRAY: - return 7; - case DARK_GREEN: - return 13; - case DARK_PURPLE: - return 10; - case DARK_RED: - return 14; - case GOLD: - return 4; - case GRAY: - return 8; - case GREEN: - return 5; - case ITALIC: - return -1; - case LIGHT_PURPLE: - return 2; - case MAGIC: - return -1; - case RED: - return 14; - case RESET: - return -1; - case STRIKETHROUGH: - return -1; - case UNDERLINE: - return -1; - case WHITE: - return 0; - case YELLOW: - return 4; - default: - return -1; - } + return switch (this) { + case AQUA, DARK_AQUA -> (byte) 9; + case BLUE -> (byte) 3; + case BOLD, UNDERLINE, RESET, STRIKETHROUGH, MAGIC, ITALIC -> (byte) -1; + case DARK_BLUE -> (byte) 11; + case DARK_GRAY -> (byte) 7; + case DARK_GREEN -> (byte) 13; + case DARK_PURPLE -> (byte) 10; + case DARK_RED, RED -> (byte) 14; + case GOLD, YELLOW -> (byte) 4; + case GRAY -> (byte) 8; + case GREEN -> (byte) 5; + case LIGHT_PURPLE -> (byte) 2; + case WHITE -> (byte) 0; + default -> (byte) 15; + }; } } \ No newline at end of file diff --git a/src/main/java/com/volmit/adapt/util/CustomModel.java b/src/main/java/com/volmit/adapt/util/CustomModel.java new file mode 100644 index 00000000..ee29a2a0 --- /dev/null +++ b/src/main/java/com/volmit/adapt/util/CustomModel.java @@ -0,0 +1,163 @@ +package com.volmit.adapt.util; + +import art.arcane.amulet.io.FileWatcher; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import com.volmit.adapt.Adapt; +import com.volmit.adapt.AdaptConfig; +import com.volmit.adapt.api.tick.TickedObject; +import com.volmit.adapt.util.collection.KMap; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; + +import static com.volmit.adapt.Adapt.instance; + +public record CustomModel(Material material, int model) { + private static UpdateChecker updateChecker = null; + private static final Gson GSON = new GsonBuilder() + .disableHtmlEscaping() + .setPrettyPrinting() + .create(); + + public ItemStack toItemStack() { + return toItemStack(new ItemStack(material)); + } + + public ItemStack toItemStack(ItemStack itemStack) { + var meta = itemStack.getItemMeta(); + if (meta == null || model == 0) + return itemStack; + + meta.setCustomModelData(model); + itemStack.setItemMeta(meta); + return itemStack; + } + + public static CustomModel get(Material fallback, String... path) { + if (!AdaptConfig.get().isCustomModels()) + return new CustomModel(fallback, 0); + + if (updateChecker == null) + updateChecker = new UpdateChecker(); + return updateChecker.get(fallback, path); + } + + public static void clear() { + if (updateChecker == null) + return; + updateChecker.unregister(); + updateChecker = null; + } + + private static class UpdateChecker extends TickedObject { + private final Object lock = new Object(); + private final File modelsFile; + private final FileWatcher fw; + private final KMap cache = new KMap<>(); + private JsonObject json = new JsonObject(); + + public UpdateChecker() { + super("config", "config-models", 1000); + modelsFile = instance.getDataFile("adapt", "models.json"); + fw = new FileWatcher(modelsFile); + fw.checkModified(); + instance.getTicker().register(this); + + try { + readFile(); + } catch (IOException e) { + Adapt.error("Failed to read models.json"); + e.printStackTrace(); + } + } + + @Override + public void onTick() { + if (!AdaptConfig.get().isHotReload()) + return; + + synchronized (lock) { + if (!fw.checkModified() || !modelsFile.exists()) + return; + + try { + readFile(); + cache.clear(); + Adapt.info("Hotloaded " + modelsFile.getPath()); + fw.checkModified(); + } catch (IOException e) { + Adapt.error("Failed to read models.json"); + e.printStackTrace(); + } + } + } + + public CustomModel get(Material fallback, String... path) { + return cache.computeIfAbsent(String.join("", path), k -> { + var json = this.json; + for (var s : path) { + if (!json.has(s)) + return set(new CustomModel(fallback, 0), path); + var v = json.get(s); + if (!v.isJsonObject()) { + Adapt.warn("Invalid json at path: " + String.join(".", path)); + return new CustomModel(fallback, 0); + } + json = v.getAsJsonObject(); + } + return new CustomModel(Material.valueOf(json.get("material").getAsString().toUpperCase()), json.get("model").getAsInt()); + }); + } + + public CustomModel set(CustomModel data, String... path) { + var json = this.json; + for (var s : path) { + if (!json.has(s)) + json.add(s, new JsonObject()); + + var v = json.get(s); + if (!v.isJsonObject()) { + v = new JsonObject(); + json.add(s, v); + } + json = v.getAsJsonObject(); + } + + json.addProperty("material", data.material.name()); + json.addProperty("model", data.model); + + try { + writeFile(); + } catch (IOException e) { + Adapt.error("Failed to write models.json"); + e.printStackTrace(); + } + return data; + } + + public void readFile() throws IOException { + synchronized (lock) { + if (!modelsFile.exists()) { + json = new JsonObject(); + return; + } + try (FileReader reader = new FileReader(modelsFile)) { + json = GSON.fromJson(reader, JsonObject.class); + } + } + } + + public void writeFile() throws IOException { + synchronized (lock) { + var s = GSON.toJson(json); + IO.writeAll(modelsFile, s); + fw.checkModified(); + } + } + } +} diff --git a/src/main/java/com/volmit/adapt/util/Element.java b/src/main/java/com/volmit/adapt/util/Element.java index 2bff84c9..6443c729 100644 --- a/src/main/java/com/volmit/adapt/util/Element.java +++ b/src/main/java/com/volmit/adapt/util/Element.java @@ -37,6 +37,10 @@ public interface Element { Element setName(String name); + CustomModel getModel(); + + Element setModel(CustomModel model); + double getProgress(); Element setProgress(double progress); diff --git a/src/main/java/com/volmit/adapt/util/Localizer.java b/src/main/java/com/volmit/adapt/util/Localizer.java index 9de68842..7e299369 100644 --- a/src/main/java/com/volmit/adapt/util/Localizer.java +++ b/src/main/java/com/volmit/adapt/util/Localizer.java @@ -25,6 +25,8 @@ import com.volmit.adapt.AdaptConfig; import com.volmit.adapt.util.secret.SecretSplash; import lombok.SneakyThrows; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import java.io.File; import java.io.InputStream; @@ -113,6 +115,7 @@ public static String dLocalize(String s1, String s2, String s3) { Adapt.wordKey.put(s1 + s2 + s3, jsonObj.get(s1).getAsJsonObject().get(s2).getAsJsonObject().get(s3).getAsString()); } } - return Adapt.wordKey.get(s1 + s2 + s3); + return LegacyComponentSerializer.legacySection() + .serialize(MiniMessage.miniMessage().deserialize(Adapt.wordKey.get(s1 + s2 + s3))); } } diff --git a/src/main/java/com/volmit/adapt/util/Sphere.java b/src/main/java/com/volmit/adapt/util/Sphere.java new file mode 100644 index 00000000..07ea94bb --- /dev/null +++ b/src/main/java/com/volmit/adapt/util/Sphere.java @@ -0,0 +1,49 @@ +package com.volmit.adapt.util; + +import com.volmit.adapt.util.collection.KList; + +import java.util.Iterator; + +public class Sphere implements Iterator, Cloneable { + private final KList blocks; + private int i = 0; + + public Sphere(int radius) { + int dist = radius * radius * radius; + + blocks = new KList<>(); + for (int x = -radius; x <= radius; x++) { + for (int z = -radius; z <= radius; z++) { + for (int y = -radius; y <= radius; y++) { + if (x * x + z * z + y * y > dist) + continue; + + blocks.add(new BlockPosition(x, y, z)); + } + } + } + } + + private Sphere(KList blocks) { + this.blocks = blocks.copy(); + } + + public void reset() { + i = 0; + } + + @Override + public boolean hasNext() { + return i < blocks.size(); + } + + @Override + public BlockPosition next() { + return blocks.get(i++); + } + + @Override + public Sphere clone() { + return new Sphere(blocks); + } +} diff --git a/src/main/java/com/volmit/adapt/util/UIElement.java b/src/main/java/com/volmit/adapt/util/UIElement.java index f82962d6..ec21f708 100644 --- a/src/main/java/com/volmit/adapt/util/UIElement.java +++ b/src/main/java/com/volmit/adapt/util/UIElement.java @@ -32,6 +32,7 @@ public class UIElement implements Element { private final String id; private final List lore; private MaterialBlock material; + private CustomModel model; private boolean enchanted; private String name; private double progress; @@ -94,6 +95,17 @@ public UIElement setName(String name) { return this; } + @Override + public CustomModel getModel() { + return model; + } + + @Override + public UIElement setModel(CustomModel model) { + this.model = model; + return this; + } + @Override public List getLore() { return lore; @@ -215,8 +227,13 @@ public int getCount() { @Override public ItemStack computeItemStack() { try { - ItemStack is = new ItemStack(getMaterial().getMaterial(), getCount(), getEffectiveDurability()); + ItemStack is = getModel() != null ? getModel().toItemStack() : + new ItemStack(getMaterial().getMaterial()); + is.setAmount(getCount()); + is.setDurability(getEffectiveDurability()); + ItemMeta im = is.getItemMeta(); + if (im == null) return is; im.setDisplayName(getName()); im.setLore(getLore().copy()); if (isEnchanted()) { diff --git a/src/main/java/com/volmit/adapt/util/UIWindow.java b/src/main/java/com/volmit/adapt/util/UIWindow.java index 42745641..3973111b 100644 --- a/src/main/java/com/volmit/adapt/util/UIWindow.java +++ b/src/main/java/com/volmit/adapt/util/UIWindow.java @@ -19,6 +19,9 @@ package com.volmit.adapt.util; import com.volmit.adapt.Adapt; +import com.volmit.adapt.api.version.Version; +import lombok.Getter; +import lombok.Setter; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -29,6 +32,7 @@ import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; import java.util.HashMap; @@ -74,8 +78,7 @@ public void on(InventoryClickEvent e) { return; } - // 1.14 bukkit api change, removed getTitle() and getName() from Inventory.class - if (!viewer.getOpenInventory().getTitle().equals(title)) { + if (!(e.getInventory().getHolder() instanceof Holder)) { return; } @@ -174,7 +177,7 @@ public void on(InventoryCloseEvent e) { return; } - if (!e.getPlayer().getOpenInventory().getTitle().equals(title)) { + if (!(e.getInventory().getHolder() instanceof Holder)) { return; } @@ -221,22 +224,20 @@ public UIWindow setVisible(boolean visible) { if (visible) { Bukkit.getPluginManager().registerEvents(this, Adapt.instance); - if (getResolution().getType().equals(InventoryType.CHEST)) { - inventory = Bukkit.createInventory(null, getViewportHeight() * 9, getTitle()); + var openInventory = viewer.getOpenInventory().getTopInventory(); + if (openInventory.getHolder() instanceof Holder holder) { + inventory = getCurrentInventory(this, holder); } else { - inventory = Bukkit.createInventory(null, getResolution().getType(), getTitle()); + inventory = createInventory(this); } - viewer.openInventory(inventory); - this.visible = visible; + this.visible = true; updateInventory(); } else { - this.visible = visible; + this.visible = false; HandlerList.unregisterAll(this); viewer.closeInventory(); } - - this.visible = visible; return this; } @@ -413,6 +414,9 @@ public Window clearElements() { @Override public Window updateInventory() { if (isVisible()) { + if (Version.SET_TITLE) { + viewer.getOpenInventory().setTitle(getTitle()); + } ItemStack[] is = inventory.getContents(); Set isf = new HashSet<>(); @@ -452,6 +456,54 @@ public ItemStack computeItemStack(int viewportSlot) { @Override public Window reopen() { + if (Version.SET_TITLE) { + visible = false; + HandlerList.unregisterAll(this); + return open(); + } return this.close().open(); } + + @Setter + @Getter + private static class Holder implements InventoryHolder { + private Inventory inventory; + private WindowResolution resolution; + private UIWindow window; + + public void unregister() { + HandlerList.unregisterAll(window); + window.visible = false; + } + } + + private static Inventory createInventory(UIWindow window) { + var holder = new Holder(); + Inventory inventory; + if (window.getResolution().getType().equals(InventoryType.CHEST)) { + inventory = Bukkit.createInventory(holder, window.getViewportHeight() * 9, window.getTitle()); + } else { + inventory = Bukkit.createInventory(holder, window.getResolution().getType(), window.getTitle()); + } + holder.setResolution(window.getResolution()); + holder.setInventory(inventory); + holder.setWindow(window); + + window.viewer.openInventory(inventory); + return inventory; + } + + private static Inventory getCurrentInventory(UIWindow window, Holder holder) { + if (!Version.SET_TITLE || holder.getResolution() != window.getResolution()) { + holder.window.close(); + return createInventory(window); + } + + var openInventory = holder.inventory; + holder.unregister(); + holder.setWindow(window); + + openInventory.clear(); + return openInventory; + } } diff --git a/src/main/java/com/volmit/adapt/util/reflect/enums/Attributes.java b/src/main/java/com/volmit/adapt/util/reflect/enums/Attributes.java new file mode 100644 index 00000000..af9bd9fc --- /dev/null +++ b/src/main/java/com/volmit/adapt/util/reflect/enums/Attributes.java @@ -0,0 +1,11 @@ +package com.volmit.adapt.util.reflect.enums; + +import com.volmit.adapt.util.reflect.Reflect; +import org.bukkit.attribute.Attribute; + +public class Attributes { + public static final Attribute GENERIC_ARMOR = Reflect.getField(Attribute.class, "GENERIC_ARMOR", "ARMOR"); + public static final Attribute GENERIC_ATTACK_DAMAGE = Reflect.getField(Attribute.class, "GENERIC_ATTACK_DAMAGE", "ATTACK_DAMAGE"); + public static final Attribute GENERIC_MAX_HEALTH = Reflect.getField(Attribute.class, "GENERIC_MAX_HEALTH", "MAX_HEALTH"); + public static final Attribute GENERIC_MOVEMENT_SPEED = Reflect.getField(Attribute.class, "GENERIC_MOVEMENT_SPEED", "MOVEMENT_SPEED"); +} diff --git a/src/main/java/com/volmit/adapt/util/reflect/enums/Enchantments.java b/src/main/java/com/volmit/adapt/util/reflect/enums/Enchantments.java index f68d26b5..b2d3e6b8 100644 --- a/src/main/java/com/volmit/adapt/util/reflect/enums/Enchantments.java +++ b/src/main/java/com/volmit/adapt/util/reflect/enums/Enchantments.java @@ -5,7 +5,7 @@ public class Enchantments { - public static Enchantment DURABILITY = Reflect.getField(Enchantment.class, "DURABILITY", "UNBREAKING"); - public static Enchantment ARROW_INFINITE = Reflect.getField(Enchantment.class, "ARROW_INFINITE", "INFINITY"); - public static Enchantment LOOT_BONUS_BLOCKS = Reflect.getField(Enchantment.class, "LOOT_BONUS_BLOCKS", "FORTUNE"); + public static final Enchantment DURABILITY = Reflect.getField(Enchantment.class, "DURABILITY", "UNBREAKING"); + public static final Enchantment ARROW_INFINITE = Reflect.getField(Enchantment.class, "ARROW_INFINITE", "INFINITY"); + public static final Enchantment LOOT_BONUS_BLOCKS = Reflect.getField(Enchantment.class, "LOOT_BONUS_BLOCKS", "FORTUNE"); } diff --git a/src/main/java/com/volmit/adapt/util/reflect/enums/EntityTypes.java b/src/main/java/com/volmit/adapt/util/reflect/enums/EntityTypes.java index cf52efbe..2aa6e333 100644 --- a/src/main/java/com/volmit/adapt/util/reflect/enums/EntityTypes.java +++ b/src/main/java/com/volmit/adapt/util/reflect/enums/EntityTypes.java @@ -4,13 +4,5 @@ import org.bukkit.entity.EntityType; public class EntityTypes { - - public static EntityType MINECART_CHEST = Reflect.getEnum(EntityType.class, "MINECART_CHEST", "CHEST_MINECART"); - public static EntityType MINECART_COMMAND = Reflect.getEnum(EntityType.class, "MINECART_COMMAND", "COMMAND_BLOCK_MINECART"); - public static EntityType MINECART_FURNACE = Reflect.getEnum(EntityType.class, "MINECART_FURNACE", "FURNACE_MINECART"); - public static EntityType MINECART_HOPPER = Reflect.getEnum(EntityType.class, "MINECART_HOPPER", "HOPPER_MINECART"); - public static EntityType MINECART_MOB_SPAWNER = Reflect.getEnum(EntityType.class, "MINECART_MOB_SPAWNER", "SPAWNER_MINECART"); - public static EntityType MINECART_TNT = Reflect.getEnum(EntityType.class, "MINECART_TNT", "TNT_MINECART"); - - public static EntityType LEASH_HITCH = Reflect.getEnum(EntityType.class, "LEASH_HITCH", "LEASH_KNOT"); + public static final EntityType ENDER_CRYSTAL = Reflect.getEnum(EntityType.class, "ENDER_CRYSTAL", "END_CRYSTAL"); } diff --git a/src/main/java/com/volmit/adapt/util/reflect/enums/ItemFlags.java b/src/main/java/com/volmit/adapt/util/reflect/enums/ItemFlags.java index 8a955563..237cb871 100644 --- a/src/main/java/com/volmit/adapt/util/reflect/enums/ItemFlags.java +++ b/src/main/java/com/volmit/adapt/util/reflect/enums/ItemFlags.java @@ -5,5 +5,5 @@ public class ItemFlags { - public static ItemFlag HIDE_POTION_EFFECTS = Reflect.getEnum(ItemFlag.class, "HIDE_POTION_EFFECTS", "HIDE_ADDITIONAL_TOOLTIP"); + public static final ItemFlag HIDE_POTION_EFFECTS = Reflect.getEnum(ItemFlag.class, "HIDE_POTION_EFFECTS", "HIDE_ADDITIONAL_TOOLTIP"); } diff --git a/src/main/resources/en_US.json b/src/main/resources/en_US.json index c6a7a1d5..0fc7d60a 100644 --- a/src/main/resources/en_US.json +++ b/src/main/resources/en_US.json @@ -231,6 +231,34 @@ "challenge_pickaxe_5m": { "title": "Legendary Miner", "description": "Break 5,000,000 Blocks" + }, + "challenge_eat_100": { + "title": "So much to eat!", + "description": "Eat over 100 Items!" + }, + "challenge_eat_1000": { + "title": "Unquenchable Hunger!", + "description": "Eat over 1,000 Items!" + }, + "challenge_eat_10000": { + "title": "EVERLASTING HUNGER!", + "description": "Eat over 10,000 Items!" + }, + "challenge_harvest_100": { + "title": "Full Harvest", + "description": "Harvest over 100 crops!" + }, + "challenge_harvest_1000": { + "title": "Grand Harvest", + "description": "Harvest over 1,000 crops!" + }, + "challenge_swim_1nm": { + "title": "Human Submarine!", + "description": "Swim 1 Nautical Mile (1,852 blocks)" + }, + "challenge_sneak_1k": { + "title": "Knee Pain", + "description": "Sneak over a kilometer (1,000 blocks)" } }, "items": { @@ -920,6 +948,12 @@ "description": "When you break a block it teleports the item into your inventory", "lore1": "Whenever an item is dropped from a block you break it goes into your inventory if it can." }, + "silkspawner": { + "name": "Pickaxe Silk-Spawner", + "description": "Makes Spawners drop when broken", + "lore1": "Makes Spawners breakable with silk touch.", + "lore2": "Makes Spawners breakable while sneaking." + }, "veinminer": { "name": "Veinminer", "description": "Allows you to break blocks in a Vein/Cluster of Vanilla ores", diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 13aa7dcb..336a53b8 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -21,6 +21,7 @@ libraries: - net.kyori:adventure-api:4.13.1 - net.kyori:adventure-text-minimessage:4.13.1 - it.unimi.dsi:fastutil:8.5.13 + - fr.skytasul:glowingentities:1.4 commands: adapt: {} diff --git a/version/v1_19_2/src/main/java/com/volmit/adapt/api/version/v1_19_2/AttributeImpl.java b/version/v1_19_2/src/main/java/com/volmit/adapt/api/version/v1_19_2/AttributeImpl.java index 67a508d6..8fe8adf8 100644 --- a/version/v1_19_2/src/main/java/com/volmit/adapt/api/version/v1_19_2/AttributeImpl.java +++ b/version/v1_19_2/src/main/java/com/volmit/adapt/api/version/v1_19_2/AttributeImpl.java @@ -1,38 +1,73 @@ package com.volmit.adapt.api.version.v1_19_2; import com.volmit.adapt.api.version.IAttribute; +import com.volmit.adapt.util.collection.KList; import org.bukkit.NamespacedKey; import org.bukkit.attribute.AttributeInstance; import org.bukkit.attribute.AttributeModifier; import java.util.UUID; import java.util.function.Predicate; +import java.util.stream.Collectors; public record AttributeImpl(AttributeInstance instance) implements IAttribute { + @Override + public double getValue() { + return instance.getValue(); + } + + @Override + public double getDefaultValue() { + return instance.getDefaultValue(); + } + + @Override + public double getBaseValue() { + return instance.getBaseValue(); + } + + @Override + public void setBaseValue(double baseValue) { + instance.setBaseValue(baseValue); + } + @Override @SuppressWarnings("all") - public void addAttributeModifier(UUID uuid, NamespacedKey key, double amount, AttributeModifier.Operation operation) { - instance.getModifiers().add(new AttributeModifier(uuid, key.getNamespace() + "-" + key.getKey(), amount, operation)); + public void addModifier(UUID uuid, NamespacedKey key, double amount, AttributeModifier.Operation operation) { + instance.addModifier(new AttributeModifier(uuid, key.getNamespace() + "-" + key.getKey(), amount, operation)); } @Override - public boolean hasAttributeModifier(UUID uuid, NamespacedKey key) { + public boolean hasModifier(UUID uuid, NamespacedKey key) { return instance.getModifiers() .stream() .anyMatch(filter(uuid, key)); } @Override - public void removeAttributeModifier(UUID uuid, NamespacedKey key) { + public void removeModifier(UUID uuid, NamespacedKey key) { instance.getModifiers() .stream() .filter(filter(uuid, key)) .forEach(instance::removeModifier); } + @Override + public KList getModifier(UUID uuid, NamespacedKey key) { + return instance.getModifiers() + .stream() + .filter(filter(uuid, key)) + .map(AttributeImpl::wrap) + .collect(Collectors.toCollection(KList::new)); + } + private Predicate filter(UUID uuid, NamespacedKey key) { String name = key.getNamespace() + "-" + key.getKey(); return m -> m.getUniqueId().equals(uuid) || m.getName().equals(name); } + + private static Modifier wrap(AttributeModifier modifier) { + return new Modifier(modifier.getUniqueId(), null, modifier.getAmount() ,modifier.getOperation()); + } } diff --git a/version/v1_19_2/src/main/java/com/volmit/adapt/api/version/v1_19_2/Bindings.java b/version/v1_19_2/src/main/java/com/volmit/adapt/api/version/v1_19_2/Bindings.java index 1143cd91..7318832e 100644 --- a/version/v1_19_2/src/main/java/com/volmit/adapt/api/version/v1_19_2/Bindings.java +++ b/version/v1_19_2/src/main/java/com/volmit/adapt/api/version/v1_19_2/Bindings.java @@ -3,16 +3,20 @@ import com.volmit.adapt.api.potion.PotionBuilder; import com.volmit.adapt.api.version.IAttribute; import com.volmit.adapt.api.version.IBindings; +import org.bukkit.attribute.Attributable; import org.bukkit.attribute.Attribute; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.potion.PotionData; +import org.jetbrains.annotations.Unmodifiable; import org.spigotmc.event.entity.EntityDismountEvent; import org.spigotmc.event.entity.EntityMountEvent; import java.util.HashSet; +import java.util.List; import java.util.Optional; import java.util.Set; import java.util.function.Consumer; @@ -22,8 +26,8 @@ public class Bindings implements IBindings { private final Set> dismountListeners = new HashSet<>(); @Override - public IAttribute getAttribute(Player player, Attribute modifier) { - return Optional.ofNullable(player.getAttribute(modifier)) + public IAttribute getAttribute(Attributable attributable, Attribute modifier) { + return Optional.ofNullable(attributable.getAttribute(modifier)) .map(AttributeImpl::new) .orElse(null); } @@ -49,6 +53,28 @@ public ItemStack buildPotion(PotionBuilder builder) { return stack; } + @Override + @Unmodifiable + public List getInvalidDamageableEntities() { + return List.of( + EntityType.ARMOR_STAND, + EntityType.BOAT, + EntityType.ITEM_FRAME, + EntityType.MINECART, + EntityType.MINECART_CHEST, + EntityType.MINECART_COMMAND, + EntityType.MINECART_FURNACE, + EntityType.MINECART_HOPPER, + EntityType.MINECART_MOB_SPAWNER, + EntityType.MINECART_TNT, + EntityType.PAINTING, + EntityType.CHEST_BOAT, + EntityType.LEASH_HITCH, + EntityType.EVOKER_FANGS, + EntityType.MARKER + ); + } + @EventHandler public void on(EntityMountEvent e) { if (e.getEntity() instanceof Player p) { diff --git a/version/v1_20_4/src/main/java/com/volmit/adapt/api/version/v1_20_4/AttributeImpl.java b/version/v1_20_4/src/main/java/com/volmit/adapt/api/version/v1_20_4/AttributeImpl.java index e16859ad..0b12ad80 100644 --- a/version/v1_20_4/src/main/java/com/volmit/adapt/api/version/v1_20_4/AttributeImpl.java +++ b/version/v1_20_4/src/main/java/com/volmit/adapt/api/version/v1_20_4/AttributeImpl.java @@ -1,38 +1,73 @@ package com.volmit.adapt.api.version.v1_20_4; import com.volmit.adapt.api.version.IAttribute; +import com.volmit.adapt.util.collection.KList; import org.bukkit.NamespacedKey; import org.bukkit.attribute.AttributeInstance; import org.bukkit.attribute.AttributeModifier; import java.util.UUID; import java.util.function.Predicate; +import java.util.stream.Collectors; public record AttributeImpl(AttributeInstance instance) implements IAttribute { + @Override + public double getValue() { + return instance.getValue(); + } + + @Override + public double getDefaultValue() { + return instance.getDefaultValue(); + } + + @Override + public double getBaseValue() { + return instance.getBaseValue(); + } + + @Override + public void setBaseValue(double baseValue) { + instance.setBaseValue(baseValue); + } + @Override @SuppressWarnings("all") - public void addAttributeModifier(UUID uuid, NamespacedKey key, double amount, AttributeModifier.Operation operation) { - instance.getModifiers().add(new AttributeModifier(uuid, key.getNamespace() + "-" + key.getKey(), amount, operation)); + public void addModifier(UUID uuid, NamespacedKey key, double amount, AttributeModifier.Operation operation) { + instance.addModifier(new AttributeModifier(uuid, key.getNamespace() + "-" + key.getKey(), amount, operation)); } @Override - public boolean hasAttributeModifier(UUID uuid, NamespacedKey key) { + public boolean hasModifier(UUID uuid, NamespacedKey key) { return instance.getModifiers() .stream() .anyMatch(filter(uuid, key)); } @Override - public void removeAttributeModifier(UUID uuid, NamespacedKey key) { + public void removeModifier(UUID uuid, NamespacedKey key) { instance.getModifiers() .stream() .filter(filter(uuid, key)) .forEach(instance::removeModifier); } + @Override + public KList getModifier(UUID uuid, NamespacedKey key) { + return instance.getModifiers() + .stream() + .filter(filter(uuid, key)) + .map(AttributeImpl::wrap) + .collect(Collectors.toCollection(KList::new)); + } + private Predicate filter(UUID uuid, NamespacedKey key) { String name = key.getNamespace() + "-" + key.getKey(); return m -> m.getUniqueId().equals(uuid) || m.getName().equals(name); } + + private static Modifier wrap(AttributeModifier modifier) { + return new Modifier(modifier.getUniqueId(), null, modifier.getAmount() ,modifier.getOperation()); + } } diff --git a/version/v1_20_4/src/main/java/com/volmit/adapt/api/version/v1_20_4/Bindings.java b/version/v1_20_4/src/main/java/com/volmit/adapt/api/version/v1_20_4/Bindings.java index 1ff78de2..631b95f7 100644 --- a/version/v1_20_4/src/main/java/com/volmit/adapt/api/version/v1_20_4/Bindings.java +++ b/version/v1_20_4/src/main/java/com/volmit/adapt/api/version/v1_20_4/Bindings.java @@ -3,7 +3,9 @@ import com.volmit.adapt.api.potion.PotionBuilder; import com.volmit.adapt.api.version.IAttribute; import com.volmit.adapt.api.version.IBindings; +import org.bukkit.attribute.Attributable; import org.bukkit.attribute.Attribute; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.entity.EntityDismountEvent; @@ -11,8 +13,10 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.potion.PotionData; +import org.jetbrains.annotations.Unmodifiable; import java.util.HashSet; +import java.util.List; import java.util.Optional; import java.util.Set; import java.util.function.Consumer; @@ -22,8 +26,8 @@ public class Bindings implements IBindings { private final Set> dismountListeners = new HashSet<>(); @Override - public IAttribute getAttribute(Player player, Attribute modifier) { - return Optional.ofNullable(player.getAttribute(modifier)) + public IAttribute getAttribute(Attributable attributable, Attribute modifier) { + return Optional.ofNullable(attributable.getAttribute(modifier)) .map(AttributeImpl::new) .orElse(null); } @@ -49,6 +53,28 @@ public ItemStack buildPotion(PotionBuilder builder) { return stack; } + @Override + @Unmodifiable + public List getInvalidDamageableEntities() { + return List.of( + EntityType.ARMOR_STAND, + EntityType.BOAT, + EntityType.ITEM_FRAME, + EntityType.MINECART, + EntityType.MINECART_CHEST, + EntityType.MINECART_COMMAND, + EntityType.MINECART_FURNACE, + EntityType.MINECART_HOPPER, + EntityType.MINECART_MOB_SPAWNER, + EntityType.MINECART_TNT, + EntityType.PAINTING, + EntityType.CHEST_BOAT, + EntityType.LEASH_HITCH, + EntityType.EVOKER_FANGS, + EntityType.MARKER + ); + } + @EventHandler public void on(EntityMountEvent e) { if (e.getEntity() instanceof Player p) { diff --git a/version/v1_20_5/src/main/java/com/volmit/adapt/api/version/v1_20_5/AttributeImpl.java b/version/v1_20_5/src/main/java/com/volmit/adapt/api/version/v1_20_5/AttributeImpl.java index a5ddaac1..6d82a064 100644 --- a/version/v1_20_5/src/main/java/com/volmit/adapt/api/version/v1_20_5/AttributeImpl.java +++ b/version/v1_20_5/src/main/java/com/volmit/adapt/api/version/v1_20_5/AttributeImpl.java @@ -1,6 +1,7 @@ package com.volmit.adapt.api.version.v1_20_5; import com.volmit.adapt.api.version.IAttribute; +import com.volmit.adapt.util.collection.KList; import org.bukkit.NamespacedKey; import org.bukkit.attribute.AttributeInstance; import org.bukkit.attribute.AttributeModifier; @@ -8,32 +9,66 @@ import java.util.UUID; import java.util.function.Predicate; +import java.util.stream.Collectors; public record AttributeImpl(AttributeInstance instance) implements IAttribute { + @Override + public double getValue() { + return instance.getValue(); + } + + @Override + public double getDefaultValue() { + return instance.getDefaultValue(); + } + + @Override + public double getBaseValue() { + return instance.getBaseValue(); + } + + @Override + public void setBaseValue(double baseValue) { + instance.setBaseValue(baseValue); + } + @Override @SuppressWarnings("all") - public void addAttributeModifier(UUID uuid, NamespacedKey key, double amount, AttributeModifier.Operation operation) { - instance.getModifiers().add(new AttributeModifier(uuid, key.getNamespace() + "-" + key.getKey(), amount, operation, EquipmentSlotGroup.ANY)); + public void addModifier(UUID uuid, NamespacedKey key, double amount, AttributeModifier.Operation operation) { + instance.addModifier(new AttributeModifier(uuid, key.getNamespace() + "-" + key.getKey(), amount, operation, EquipmentSlotGroup.ANY)); } @Override - public boolean hasAttributeModifier(UUID uuid, NamespacedKey key) { + public boolean hasModifier(UUID uuid, NamespacedKey key) { return instance.getModifiers() .stream() .anyMatch(filter(uuid, key)); } @Override - public void removeAttributeModifier(UUID uuid, NamespacedKey key) { + public void removeModifier(UUID uuid, NamespacedKey key) { instance.getModifiers() .stream() .filter(filter(uuid, key)) .forEach(instance::removeModifier); } + @Override + public KList getModifier(UUID uuid, NamespacedKey key) { + return instance.getModifiers() + .stream() + .filter(filter(uuid, key)) + .map(AttributeImpl::wrap) + .collect(Collectors.toCollection(KList::new)); + } + private Predicate filter(UUID uuid, NamespacedKey key) { String name = key.getNamespace() + "-" + key.getKey(); return m -> m.getUniqueId().equals(uuid) || m.getName().equals(name); } + + private static Modifier wrap(AttributeModifier modifier) { + return new Modifier(modifier.getUniqueId(), null, modifier.getAmount() ,modifier.getOperation()); + } } diff --git a/version/v1_20_5/src/main/java/com/volmit/adapt/api/version/v1_20_5/Bindings.java b/version/v1_20_5/src/main/java/com/volmit/adapt/api/version/v1_20_5/Bindings.java index 2b6345f2..6871d9a2 100644 --- a/version/v1_20_5/src/main/java/com/volmit/adapt/api/version/v1_20_5/Bindings.java +++ b/version/v1_20_5/src/main/java/com/volmit/adapt/api/version/v1_20_5/Bindings.java @@ -4,7 +4,9 @@ import com.volmit.adapt.api.version.IAttribute; import com.volmit.adapt.api.version.IBindings; import com.volmit.adapt.util.reflect.Reflect; +import org.bukkit.attribute.Attributable; import org.bukkit.attribute.Attribute; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.entity.EntityDismountEvent; @@ -12,8 +14,10 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.potion.PotionType; +import org.jetbrains.annotations.Unmodifiable; import java.util.HashSet; +import java.util.List; import java.util.Optional; import java.util.Set; import java.util.function.Consumer; @@ -23,8 +27,8 @@ public class Bindings implements IBindings { private final Set> dismountListeners = new HashSet<>(); @Override - public IAttribute getAttribute(Player player, Attribute modifier) { - return Optional.ofNullable(player.getAttribute(modifier)) + public IAttribute getAttribute(Attributable attributable, Attribute modifier) { + return Optional.ofNullable(attributable.getAttribute(modifier)) .map(AttributeImpl::new) .orElse(null); } @@ -60,6 +64,27 @@ public ItemStack buildPotion(PotionBuilder builder) { return stack; } + @Override + @Unmodifiable + public List getInvalidDamageableEntities() { + return List.of( + EntityType.ARMOR_STAND, + EntityType.BOAT, + EntityType.ITEM_FRAME, + EntityType.MINECART, + EntityType.CHEST_MINECART, + EntityType.COMMAND_BLOCK_MINECART, + EntityType.FURNACE_MINECART, + EntityType.HOPPER_MINECART, + EntityType.SPAWNER_MINECART, + EntityType.PAINTING, + EntityType.CHEST_BOAT, + EntityType.LEASH_KNOT, + EntityType.EVOKER_FANGS, + EntityType.MARKER + ); + } + @EventHandler public void on(EntityMountEvent e) { if (e.getEntity() instanceof Player p) { diff --git a/version/v1_21/src/main/java/com/volmit/adapt/api/version/v1_21_0/AttributeImpl.java b/version/v1_21/src/main/java/com/volmit/adapt/api/version/v1_21_0/AttributeImpl.java index a5f882cb..ad089cb6 100644 --- a/version/v1_21/src/main/java/com/volmit/adapt/api/version/v1_21_0/AttributeImpl.java +++ b/version/v1_21/src/main/java/com/volmit/adapt/api/version/v1_21_0/AttributeImpl.java @@ -1,33 +1,68 @@ package com.volmit.adapt.api.version.v1_21_0; import com.volmit.adapt.api.version.IAttribute; +import com.volmit.adapt.util.collection.KList; import org.bukkit.NamespacedKey; import org.bukkit.attribute.AttributeInstance; import org.bukkit.attribute.AttributeModifier; import org.bukkit.inventory.EquipmentSlotGroup; import java.util.UUID; +import java.util.stream.Collectors; public record AttributeImpl(AttributeInstance instance) implements IAttribute { + @Override + public double getValue() { + return instance.getValue(); + } + + @Override + public double getDefaultValue() { + return instance.getDefaultValue(); + } + + @Override + public double getBaseValue() { + return instance.getBaseValue(); + } + + @Override + public void setBaseValue(double baseValue) { + instance.setBaseValue(baseValue); + } + @Override @SuppressWarnings("all") - public void addAttributeModifier(UUID uuid, NamespacedKey key, double amount, AttributeModifier.Operation operation) { - instance.getModifiers().add(new AttributeModifier(key, amount, operation, EquipmentSlotGroup.ANY)); + public void addModifier(UUID uuid, NamespacedKey key, double amount, AttributeModifier.Operation operation) { + instance.addModifier(new AttributeModifier(key, amount, operation, EquipmentSlotGroup.ANY)); } @Override - public boolean hasAttributeModifier(UUID uuid, NamespacedKey key) { + public boolean hasModifier(UUID uuid, NamespacedKey key) { return instance.getModifiers() .stream() .anyMatch(m -> m.getKey().equals(key)); } @Override - public void removeAttributeModifier(UUID uuid, NamespacedKey key) { + public void removeModifier(UUID uuid, NamespacedKey key) { instance.getModifiers() .stream() .filter(m -> m.getKey().equals(key)) .forEach(instance::removeModifier); } + + @Override + public KList getModifier(UUID uuid, NamespacedKey key) { + return instance.getModifiers() + .stream() + .filter(m -> m.getKey().equals(key)) + .map(AttributeImpl::wrap) + .collect(Collectors.toCollection(KList::new)); + } + + private static Modifier wrap(AttributeModifier modifier) { + return new Modifier(null, modifier.getKey(), modifier.getAmount() ,modifier.getOperation()); + } } diff --git a/version/v1_21/src/main/java/com/volmit/adapt/api/version/v1_21_0/Bindings.java b/version/v1_21/src/main/java/com/volmit/adapt/api/version/v1_21_0/Bindings.java index f91f96f2..c102feec 100644 --- a/version/v1_21/src/main/java/com/volmit/adapt/api/version/v1_21_0/Bindings.java +++ b/version/v1_21/src/main/java/com/volmit/adapt/api/version/v1_21_0/Bindings.java @@ -4,7 +4,9 @@ import com.volmit.adapt.api.version.IAttribute; import com.volmit.adapt.api.version.IBindings; import com.volmit.adapt.util.reflect.Reflect; +import org.bukkit.attribute.Attributable; import org.bukkit.attribute.Attribute; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.entity.EntityDismountEvent; @@ -12,8 +14,10 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.potion.PotionType; +import org.jetbrains.annotations.Unmodifiable; import java.util.HashSet; +import java.util.List; import java.util.Optional; import java.util.Set; import java.util.function.Consumer; @@ -23,8 +27,8 @@ public class Bindings implements IBindings { private final Set> dismountListeners = new HashSet<>(); @Override - public IAttribute getAttribute(Player player, Attribute modifier) { - return Optional.ofNullable(player.getAttribute(modifier)) + public IAttribute getAttribute(Attributable attributable, Attribute modifier) { + return Optional.ofNullable(attributable.getAttribute(modifier)) .map(AttributeImpl::new) .orElse(null); } @@ -60,6 +64,27 @@ public ItemStack buildPotion(PotionBuilder builder) { return stack; } + @Override + @Unmodifiable + public List getInvalidDamageableEntities() { + return List.of( + EntityType.ARMOR_STAND, + EntityType.BOAT, + EntityType.ITEM_FRAME, + EntityType.MINECART, + EntityType.CHEST_MINECART, + EntityType.COMMAND_BLOCK_MINECART, + EntityType.FURNACE_MINECART, + EntityType.HOPPER_MINECART, + EntityType.SPAWNER_MINECART, + EntityType.PAINTING, + EntityType.CHEST_BOAT, + EntityType.LEASH_KNOT, + EntityType.EVOKER_FANGS, + EntityType.MARKER + ); + } + @EventHandler public void on(EntityMountEvent e) { if (e.getEntity() instanceof Player p) { diff --git a/version/v1_21_2/src/main/java/com/volmit/adapt/api/version/v1_21_2/AttributeImpl.java b/version/v1_21_2/src/main/java/com/volmit/adapt/api/version/v1_21_2/AttributeImpl.java new file mode 100644 index 00000000..8a41c63d --- /dev/null +++ b/version/v1_21_2/src/main/java/com/volmit/adapt/api/version/v1_21_2/AttributeImpl.java @@ -0,0 +1,68 @@ +package com.volmit.adapt.api.version.v1_21_2; + +import com.volmit.adapt.api.version.IAttribute; +import com.volmit.adapt.util.collection.KList; +import org.bukkit.NamespacedKey; +import org.bukkit.attribute.AttributeInstance; +import org.bukkit.attribute.AttributeModifier; +import org.bukkit.inventory.EquipmentSlotGroup; + +import java.util.UUID; +import java.util.stream.Collectors; + +public record AttributeImpl(AttributeInstance instance) implements IAttribute { + + @Override + public double getValue() { + return instance.getValue(); + } + + @Override + public double getDefaultValue() { + return instance.getDefaultValue(); + } + + @Override + public double getBaseValue() { + return instance.getBaseValue(); + } + + @Override + public void setBaseValue(double baseValue) { + instance.setBaseValue(baseValue); + } + + @Override + @SuppressWarnings("all") + public void addModifier(UUID uuid, NamespacedKey key, double amount, AttributeModifier.Operation operation) { + instance.addModifier(new AttributeModifier(key, amount, operation, EquipmentSlotGroup.ANY)); + } + + @Override + public boolean hasModifier(UUID uuid, NamespacedKey key) { + return instance.getModifiers() + .stream() + .anyMatch(m -> m.getKey().equals(key)); + } + + @Override + public void removeModifier(UUID uuid, NamespacedKey key) { + instance.getModifiers() + .stream() + .filter(m -> m.getKey().equals(key)) + .forEach(instance::removeModifier); + } + + @Override + public KList getModifier(UUID uuid, NamespacedKey key) { + return instance.getModifiers() + .stream() + .filter(m -> m.getKey().equals(key)) + .map(AttributeImpl::wrap) + .collect(Collectors.toCollection(KList::new)); + } + + private static Modifier wrap(AttributeModifier modifier) { + return new Modifier(null, modifier.getKey(), modifier.getAmount() ,modifier.getOperation()); + } +} diff --git a/version/v1_21_2/src/main/java/com/volmit/adapt/api/version/v1_21_2/Bindings.java b/version/v1_21_2/src/main/java/com/volmit/adapt/api/version/v1_21_2/Bindings.java new file mode 100644 index 00000000..35fda245 --- /dev/null +++ b/version/v1_21_2/src/main/java/com/volmit/adapt/api/version/v1_21_2/Bindings.java @@ -0,0 +1,120 @@ +package com.volmit.adapt.api.version.v1_21_2; + +import com.volmit.adapt.api.potion.PotionBuilder; +import com.volmit.adapt.api.version.IAttribute; +import com.volmit.adapt.api.version.IBindings; +import com.volmit.adapt.util.reflect.Reflect; +import org.bukkit.attribute.Attributable; +import org.bukkit.attribute.Attribute; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDismountEvent; +import org.bukkit.event.entity.EntityMountEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.potion.PotionType; +import org.jetbrains.annotations.Unmodifiable; + +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; + +public class Bindings implements IBindings { + private final Set> mountListeners = new HashSet<>(); + private final Set> dismountListeners = new HashSet<>(); + + @Override + public IAttribute getAttribute(Attributable attributable, Attribute modifier) { + return Optional.ofNullable(attributable.getAttribute(modifier)) + .map(AttributeImpl::new) + .orElse(null); + } + + @Override + public void addEntityMountListener(Consumer consumer) { + mountListeners.add(consumer); + } + + @Override + public void addEntityDismountListener(Consumer consumer) { + dismountListeners.add(consumer); + } + + @Override + public ItemStack buildPotion(PotionBuilder builder) { + ItemStack stack = IBindings.super.buildPotion(builder); + PotionMeta meta = (PotionMeta) stack.getItemMeta(); + assert meta != null; + + PotionType type = builder.getBaseType(); + if (type == null) { + meta.setBasePotionType(null); + } else if (builder.isExtended()) { + meta.setBasePotionType(Reflect.getEnum(PotionType.class, "LONG_"+type.name()).orElse(type)); + } else if (builder.isUpgraded()) { + meta.setBasePotionType(Reflect.getEnum(PotionType.class, "STRONG_"+type.name()).orElse(type)); + } else { + meta.setBasePotionType(type); + } + + stack.setItemMeta(meta); + return stack; + } + + @Override + @Unmodifiable + public List getInvalidDamageableEntities() { + return List.of( + EntityType.ARMOR_STAND, + + EntityType.BIRCH_BOAT, + EntityType.ACACIA_BOAT, + EntityType.CHERRY_BOAT, + EntityType.JUNGLE_BOAT, + EntityType.DARK_OAK_BOAT, + EntityType.MANGROVE_BOAT, + EntityType.SPRUCE_BOAT, + EntityType.OAK_BOAT, + + EntityType.ITEM_FRAME, + EntityType.MINECART, + EntityType.CHEST_MINECART, + EntityType.COMMAND_BLOCK_MINECART, + EntityType.FURNACE_MINECART, + EntityType.HOPPER_MINECART, + EntityType.SPAWNER_MINECART, + EntityType.TNT_MINECART, + EntityType.PAINTING, + + EntityType.BIRCH_CHEST_BOAT, + EntityType.ACACIA_CHEST_BOAT, + EntityType.CHERRY_CHEST_BOAT, + EntityType.JUNGLE_CHEST_BOAT, + EntityType.DARK_OAK_CHEST_BOAT, + EntityType.MANGROVE_CHEST_BOAT, + EntityType.SPRUCE_CHEST_BOAT, + EntityType.OAK_CHEST_BOAT, + + EntityType.LEASH_KNOT, + EntityType.EVOKER_FANGS, + EntityType.MARKER + ); + } + + @EventHandler + public void on(EntityMountEvent e) { + if (e.getEntity() instanceof Player p) { + mountListeners.forEach(l -> l.accept(p)); + } + } + + @EventHandler + public void on(EntityDismountEvent e) { + if (e.getEntity() instanceof Player p) { + dismountListeners.forEach(l -> l.accept(p)); + } + } +}