diff --git a/.gitattributes b/.gitattributes index 1fb5395e5..0280f24bd 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,3 +2,4 @@ *.png binary *.wav binary +p \ No newline at end of file diff --git a/1 b/1 deleted file mode 100644 index c0087c86d..000000000 --- a/1 +++ /dev/null @@ -1,11 +0,0 @@ -SkillShot tweaks -# Please enter the commit message for your changes. Lines starting -# with '#' will be ignored, and an empty message aborts the commit. -# -# On branch master -# Your branch is up to date with 'origin/master'. -# -# Changes to be committed: -# modified: src/main/java/com/gmail/nossr50/skills/archery/Archery.java -# modified: src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java -# diff --git a/Changelog.txt b/Changelog.txt index 633dcd1b5..9757aa906 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -203,6 +203,23 @@ Version 2.2.0 Added API method to check if a skill was being level capped Added 'UndefinedSkillBehaviour' for trying to use a method that has no behaviour defined for the provided skill +Version 2.1.115 + Green Thumb now requires a hoe to activate + Hoes no longer give free replants + You can sneak to break plants with a hoe in your hand (or just put the hoe away) + Using a hoe on non-fully grown crops will replant them as a convenience feature + New sound option in sounds.yml called 'ITEM_CONSUMED', plays when eating seeds for Green Thumb + Cocoa plants now require GT of at least 2 to start at the second stage of growth + Green Terra now boosts growth on Green Thumb by 1 stage (doesn't go above the maximum value though) + There is now a feature in place to prevent breaking a newly automatically replanted (via green thumb) crop from being breakable for a few seconds after it appears + Fixed a bug where Salvage always gave the best results + Fixed an issue with arrows causing exceptions with players not yet having data loaded + Spectral arrows are now tracked by mcMMO + Use minimum level of salvageable properly + Fix Axes Critical Strikes default permissions ( new fixed permission: mcmmo.ability.axes.criticalstrikes ) + Fix potential null pointer exception for salvage + Updated locale entry 'Herbalism.SubSkill.GreenTerra.Description' + Version 2.1.114 Fix some more locale usages, should aim to further prevent issues with oddball locales Fixed a bug where newer versions of MySQL did not like our rank command diff --git a/build.gradle.kts b/build.gradle.kts index 325e37558..1ee93ce4e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,11 +6,14 @@ subprojects { repositories { mavenLocal() mavenCentral() + maven("https://oss.sonatype.org/content/groups/public/") maven("https://repo.spongepowered.org/maven") maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots") maven("https://repo.codemc.org/repository/maven-public") maven("https://maven.sk89q.com/repo") maven("https://mvnrepository.com/artifact/org.jetbrains/annotations") + maven("https://repo.aikar.co/content/groups/aikar/") + maven("https://hub.spigotmc.org/nexus/content/groups/public/") } tasks { diff --git a/mcmmo-api/src/main/java/com/gmail/nossr50/mcmmo/api/platform/util/MetadataStore.java b/mcmmo-api/src/main/java/com/gmail/nossr50/mcmmo/api/platform/util/MetadataStore.java index 539d70da3..f23df27bf 100644 --- a/mcmmo-api/src/main/java/com/gmail/nossr50/mcmmo/api/platform/util/MetadataStore.java +++ b/mcmmo-api/src/main/java/com/gmail/nossr50/mcmmo/api/platform/util/MetadataStore.java @@ -1,7 +1,6 @@ package com.gmail.nossr50.mcmmo.api.platform.util; import com.gmail.nossr50.mcmmo.api.data.MMOEntity; - import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/mcmmo-bukkit/src/main/java/com/gmail/nossr50/mcmmo/bukkit/BukkitBoostrap.java b/mcmmo-bukkit/src/main/java/com/gmail/nossr50/mcmmo/bukkit/BukkitBoostrap.java index 212572c36..98cd5e11b 100644 --- a/mcmmo-bukkit/src/main/java/com/gmail/nossr50/mcmmo/bukkit/BukkitBoostrap.java +++ b/mcmmo-bukkit/src/main/java/com/gmail/nossr50/mcmmo/bukkit/BukkitBoostrap.java @@ -1,11 +1,6 @@ package com.gmail.nossr50.mcmmo.bukkit; -import com.gmail.nossr50.listeners.BlockListener; -import com.gmail.nossr50.listeners.EntityListener; -import com.gmail.nossr50.listeners.InventoryListener; -import com.gmail.nossr50.listeners.PlayerListener; -import com.gmail.nossr50.listeners.SelfListener; -import com.gmail.nossr50.listeners.WorldListener; +import com.gmail.nossr50.listeners.*; import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcmmo.api.platform.PlatformProvider; import com.gmail.nossr50.mcmmo.api.platform.ServerSoftwareType; @@ -14,7 +9,6 @@ import com.gmail.nossr50.mcmmo.api.platform.util.MetadataStore; import com.gmail.nossr50.mcmmo.api.platform.util.MobHealthBarManager; import com.gmail.nossr50.mcmmo.bukkit.platform.scheduler.BukkitPlatformScheduler; import com.gmail.nossr50.mcmmo.bukkit.platform.util.BukkitMobHealthBarManager; - import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.event.HandlerList; diff --git a/mcmmo-bukkit/src/main/java/com/gmail/nossr50/mcmmo/bukkit/platform/scheduler/BukkitPlatformScheduler.java b/mcmmo-bukkit/src/main/java/com/gmail/nossr50/mcmmo/bukkit/platform/scheduler/BukkitPlatformScheduler.java index e8872347f..8d84ef185 100644 --- a/mcmmo-bukkit/src/main/java/com/gmail/nossr50/mcmmo/bukkit/platform/scheduler/BukkitPlatformScheduler.java +++ b/mcmmo-bukkit/src/main/java/com/gmail/nossr50/mcmmo/bukkit/platform/scheduler/BukkitPlatformScheduler.java @@ -3,7 +3,6 @@ package com.gmail.nossr50.mcmmo.bukkit.platform.scheduler; import com.gmail.nossr50.mcmmo.api.platform.scheduler.PlatformScheduler; import com.gmail.nossr50.mcmmo.api.platform.scheduler.Task; import com.gmail.nossr50.mcmmo.bukkit.BukkitBoostrap; - import org.bukkit.Bukkit; import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.scheduler.BukkitTask; diff --git a/mcmmo-bukkit/src/main/java/com/gmail/nossr50/mcmmo/bukkit/platform/scheduler/MMOBukkitTask.java b/mcmmo-bukkit/src/main/java/com/gmail/nossr50/mcmmo/bukkit/platform/scheduler/MMOBukkitTask.java index 0b4f5e581..e322decd1 100644 --- a/mcmmo-bukkit/src/main/java/com/gmail/nossr50/mcmmo/bukkit/platform/scheduler/MMOBukkitTask.java +++ b/mcmmo-bukkit/src/main/java/com/gmail/nossr50/mcmmo/bukkit/platform/scheduler/MMOBukkitTask.java @@ -2,7 +2,6 @@ package com.gmail.nossr50.mcmmo.bukkit.platform.scheduler; import com.gmail.nossr50.mcmmo.api.platform.scheduler.Task; import com.google.common.base.Preconditions; - import org.bukkit.scheduler.BukkitTask; import java.util.function.Consumer; diff --git a/mcmmo-bukkit/src/main/java/com/gmail/nossr50/mcmmo/bukkit/platform/util/BukkitMobHealthBarManager.java b/mcmmo-bukkit/src/main/java/com/gmail/nossr50/mcmmo/bukkit/platform/util/BukkitMobHealthBarManager.java index fa93557e5..21902d8a7 100644 --- a/mcmmo-bukkit/src/main/java/com/gmail/nossr50/mcmmo/bukkit/platform/util/BukkitMobHealthBarManager.java +++ b/mcmmo-bukkit/src/main/java/com/gmail/nossr50/mcmmo/bukkit/platform/util/BukkitMobHealthBarManager.java @@ -9,7 +9,6 @@ import com.gmail.nossr50.mcmmo.api.data.MMOPlayer; import com.gmail.nossr50.mcmmo.api.platform.util.MobHealthBarManager; import com.gmail.nossr50.runnables.MobHealthDisplayUpdaterTask; import com.gmail.nossr50.util.StringUtils; - import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.LivingEntity; diff --git a/mcmmo-bukkit/src/main/resources/plugin.yml b/mcmmo-bukkit/src/main/resources/plugin.yml index f24b8540f..38fca6f87 100644 --- a/mcmmo-bukkit/src/main/resources/plugin.yml +++ b/mcmmo-bukkit/src/main/resources/plugin.yml @@ -19,9 +19,6 @@ load: POSTWORLD api-version: 1.13 commands: - mmodebug: - aliases: [mcmmodebugmode] - description: Toggles a debug mode which will print useful information to chat mmoinfo: aliases: [mcinfo] description: Info pages for mcMMO @@ -264,7 +261,7 @@ permissions: description: Allows access to all Axes abilities children: mcmmo.ability.axes.axemastery: true - mcmmo.ability.axes.criticalhit: true + mcmmo.ability.axes.criticalstrikes: true mcmmo.ability.axes.greaterimpact: true mcmmo.ability.axes.armorimpact: true mcmmo.ability.axes.skullsplitter: true @@ -273,8 +270,8 @@ permissions: description: Adds damage to axes mcmmo.ability.axes.axemastery: description: Allows bonus damage from Axes - mcmmo.ability.axes.criticalhit: - description: Allows access to the Critical Hit ability + mcmmo.ability.axes.criticalstrikes: + description: Allows access to the Critical Strikes ability mcmmo.ability.axes.greaterimpact: description: Allows access to the Greater Impact ability mcmmo.ability.axes.armorimpact: @@ -628,6 +625,10 @@ permissions: children: mcmmo.commands.mcconvert.all: true mcmmo.commands.xprate.all: true + mcmmo.commands.nbttools: true + mcmmo.commands.nbttools: + default: false + description: Modify or Read NBT of an item in-hand mcmmo.bypass.*: default: false description: Implies all bypass permissions. @@ -731,6 +732,7 @@ permissions: mcmmo.commands.mcmmoreload: true mcmmo.commands.mmoedit: true mcmmo.commands.mmoedit.others: true + mcmmo.commands.nbttools: true mcmmo.commands.mmoshowdb: true mcmmo.commands.ptp.world.all: true mcmmo.commands.reloadlocale: true diff --git a/mcmmo-core/build.gradle.kts b/mcmmo-core/build.gradle.kts index c5a6a7ea3..6d3e231fd 100644 --- a/mcmmo-core/build.gradle.kts +++ b/mcmmo-core/build.gradle.kts @@ -1,3 +1,4 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import org.apache.tools.ant.filters.ReplaceTokens plugins { @@ -7,10 +8,6 @@ plugins { tasks { - build { - dependsOn(shadowJar) - } - shadowJar { dependencies { include(dependency("org.spongepowered:configurate-yaml")) @@ -20,12 +17,24 @@ tasks { include(dependency("org.apache.tomcat:tomcat-jdbc")) include(dependency("org.apache.tomcat:tomcat-juli")) include(dependency("com.typesafe:config")) + include(dependency("co.aikar:acf-core")) + include(dependency("co.aikar:acf-bukkit")) + include(dependency("net.kyori:text-api")) + include(dependency("net.kyori:text-adapter-bukkit")) + include(dependency("net.kyori:text-serializer-gson")) exclude(dependency("org.spigotmc:spigot")) } relocate("org.apache.commons.logging", "com.gmail.nossr50.commons.logging") relocate("org.apache.juli", "com.gmail.nossr50.database.tomcat.juli") relocate("org.apache.tomcat", "com.gmail.nossr50.database.tomcat") relocate("org.bstats", "com.gmail.nossr50.metrics.bstat") + relocate("co.aikar.commands", "com.gmail.nossr50.aikar.commands") + relocate("co.aikar.locales", "com.gmail.nossr50.aikar.locales") + relocate("co.aikar.table", "com.gmail.nossr50.aikar.table") + relocate("net.jodah.expiringmap", "com.gmail.nossr50.expiringmap") + relocate("net.kyori.text", "com.gmail.nossr50.kyoripowered.text") + + mergeServiceFiles() } processResources { @@ -34,6 +43,16 @@ tasks { } } + + build { + dependsOn(shadowJar) + } +} + +tasks.named("shadowJar") { + dependencies{ + include { true } + } } @@ -44,6 +63,11 @@ dependencies { api("org.spongepowered:configurate-core:3.7-SNAPSHOT") api("org.spongepowered:configurate-yaml:3.7-SNAPSHOT") api("org.spongepowered:configurate-hocon:3.7-SNAPSHOT") + api("co.aikar:acf-core:0.5.0-SNAPSHOT") //Don't change without updating the artifacts for its dependencies (see the other comments) + api("co.aikar:acf-paper:0.5.0-SNAPSHOT") //Don't change without updating the artifacts for its dependencies (see the other comments) + api("net.kyori:text-api:3.0.2") + api("net.kyori:text-serializer-gson:3.0.2") + api("net.kyori:text-adapter-bukkit:3.0.4-SNAPSHOT") implementation("org.jetbrains:annotations:17.0.0") implementation("org.apache.maven.scm:maven-scm-provider-gitexe:1.8.1") implementation("org.bstats:bstats-bukkit:1.4") diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/commands/admin/NBTToolsCommand.java b/mcmmo-core/src/main/java/com/gmail/nossr50/commands/admin/NBTToolsCommand.java new file mode 100644 index 000000000..4e36613f6 --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/commands/admin/NBTToolsCommand.java @@ -0,0 +1,66 @@ +package com.gmail.nossr50.commands.admin; + +import co.aikar.commands.BaseCommand; +import co.aikar.commands.annotation.*; +import com.gmail.nossr50.mcMMO; +import net.kyori.text.TextComponent; +import net.kyori.text.adapter.bukkit.TextAdapter; +import net.kyori.text.format.TextColor; +import net.kyori.text.serializer.gson.GsonComponentSerializer; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +@CommandAlias("nbttools") +@Description("Read or Modify values of NBT on an item in-hand") +public class NBTToolsCommand extends BaseCommand { + + public static final String STYLE_TEXT_1 = "//////////"; + @Dependency + private mcMMO plugin; + + @Default + @CommandPermission("mcmmo.commands.nbttools") + public void onCommand(Player player) { + //TODO: Add some help messages + player.sendMessage("hi"); + } + + /** + * Show the NBT tags of an item in hand + */ + @Subcommand("tags show") + public void onShowTags(Player player) { + final TextComponent textComponent = TextComponent.builder() + .content(plugin.getLocaleManager().getString("mcMMO.Template.Prefix")) + .append("NBT Tools") + .color(TextColor.GOLD) + .append(" - ") + .append("Showing NBT Tags (") + .append(player.getInventory().getItemInMainHand().getType().getKey().toString()) + .color(TextColor.GREEN) + .append(")") + .color(TextColor.GOLD) + .append(TextComponent.newline()) + .build(); + + String json = GsonComponentSerializer.INSTANCE.serialize(textComponent); + TextAdapter.sendMessage(player, textComponent); + + //Show NBT tags to player + player.sendMessage(STYLE_TEXT_1 + " NBT TOOLS " + STYLE_TEXT_1); + player.sendMessage("NBT Analysis: " + player.getInventory().getItemInMainHand().getType().getKey().toString()); + player.sendMessage(STYLE_TEXT_1 + STYLE_TEXT_1); + plugin.getNbtManager().printNBT(player.getInventory().getItemInMainHand(), player); + player.sendMessage(ChatColor.GRAY + "NBT Analysis completed!"); + } + + @Subcommand("tags add") + public void onAddTags(Player player) { + + } + + @Subcommand("tags remove") + public void onRemoveTags(Player player) { + + } +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/commands/admin/PlayerDebug.java b/mcmmo-core/src/main/java/com/gmail/nossr50/commands/admin/PlayerDebug.java deleted file mode 100644 index 7e6849d71..000000000 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/commands/admin/PlayerDebug.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.gmail.nossr50.commands.admin; - -import com.gmail.nossr50.mcMMO; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; - -public class PlayerDebug implements CommandExecutor { - - private final mcMMO pluginRef; - - public PlayerDebug(mcMMO pluginRef) { - this.pluginRef = pluginRef; - } - - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - return false; - } -} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/commands/admin/PlayerDebugCommand.java b/mcmmo-core/src/main/java/com/gmail/nossr50/commands/admin/PlayerDebugCommand.java index 67accad16..42c099553 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/commands/admin/PlayerDebugCommand.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/commands/admin/PlayerDebugCommand.java @@ -1,29 +1,32 @@ package com.gmail.nossr50.commands.admin; +import co.aikar.commands.BaseCommand; +import co.aikar.commands.annotation.CommandAlias; +import co.aikar.commands.annotation.Default; +import co.aikar.commands.annotation.Dependency; +import co.aikar.commands.annotation.Description; import com.gmail.nossr50.datatypes.player.BukkitMMOPlayer; import com.gmail.nossr50.mcMMO; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -public class PlayerDebugCommand implements CommandExecutor { - private final mcMMO pluginRef; +@CommandAlias("mmodebug") +@Description("Puts the player into debug mode, which helps problem solve bugs in mcMMO.") +public class PlayerDebugCommand extends BaseCommand { - public PlayerDebugCommand(mcMMO pluginRef) { - this.pluginRef = pluginRef; - } + @Dependency + private mcMMO plugin; - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + @Default + public void onCommand(CommandSender sender) { if(sender instanceof Player) { BukkitMMOPlayer mcMMOPlayer = pluginRef.getUserManager().getPlayer((Player) sender); mcMMOPlayer.toggleDebugMode(); //Toggle debug mode pluginRef.getNotificationManager().sendPlayerInformationChatOnlyPrefixed(mcMMOPlayer.getNative(), "Commands.Mmodebug.Toggle", String.valueOf(mcMMOPlayer.isDebugMode())); - return true; } else { - return false; + //TODO: Localize + sender.sendMessage("Players only"); } } diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/ranks/SkillRankProperty.java b/mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/ranks/SkillRankProperty.java index 96220ee83..1b7ac8398 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/ranks/SkillRankProperty.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/ranks/SkillRankProperty.java @@ -3,7 +3,6 @@ package com.gmail.nossr50.config.skills.ranks; import com.gmail.nossr50.api.exceptions.MissingSkillPropertyDefinition; import com.gmail.nossr50.datatypes.skills.properties.SkillProperty; import com.gmail.nossr50.mcMMO; -import org.apache.logging.log4j.Level; import java.util.HashMap; diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/config/sound/ConfigSound.java b/mcmmo-core/src/main/java/com/gmail/nossr50/config/sound/ConfigSound.java index b026aa887..bdc81e44c 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/config/sound/ConfigSound.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/config/sound/ConfigSound.java @@ -30,6 +30,7 @@ public class ConfigSound { SOUND_SETTINGS_MAP_DEFAULT.put(SoundType.TIRED, new SoundSetting(1.0, 1.7)); SOUND_SETTINGS_MAP_DEFAULT.put(SoundType.BLEED, new SoundSetting(2.0, 2.0)); SOUND_SETTINGS_MAP_DEFAULT.put(SoundType.GLASS, new SoundSetting(1.0, 1.0)); + SOUND_SETTINGS_MAP_DEFAULT.put(SoundType.ITEM_CONSUMED, new SoundSetting(1.0, 2.0)); } @Setting(value = "Sound-Settings", comment = "Adjust sound settings for various mcMMO sounds here." + diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/core/MetadataConstants.java b/mcmmo-core/src/main/java/com/gmail/nossr50/core/MetadataConstants.java index c747747d1..a01576ae3 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/core/MetadataConstants.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/core/MetadataConstants.java @@ -1,7 +1,6 @@ package com.gmail.nossr50.core; import com.gmail.nossr50.mcmmo.api.platform.util.MetadataKey; - import org.bukkit.metadata.FixedMetadataValue; /** @@ -10,6 +9,7 @@ import org.bukkit.metadata.FixedMetadataValue; public class MetadataConstants { /* Metadata Values */ + public static final MetadataKey REPLANT_META_KEY = new MetadataKey<>("mcMMO: Recently Replanted"); public static final MetadataKey FISH_HOOK_REF_METAKEY = new MetadataKey<>("mcMMO: Fish Hook Tracker"); public static final MetadataKey DODGE_TRACKER = new MetadataKey<>("mcMMO: Dodge Tracker"); public static final MetadataKey CUSTOM_DAMAGE_METAKEY = new MetadataKey<>("mcMMO: Custom Damage"); @@ -34,4 +34,6 @@ public class MetadataConstants { public final static MetadataKey PETS_ANIMAL_TRACKING_METAKEY = new MetadataKey<>("mcMMO: Pet Animal"); public static final MetadataKey COTW_TEMPORARY_SUMMON = new MetadataKey<>("mcMMO: COTW Entity"); + public static FixedMetadataValue metadataValue; //Gains value in onEnable + } diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/core/PlatformManager.java b/mcmmo-core/src/main/java/com/gmail/nossr50/core/PlatformManager.java new file mode 100644 index 000000000..52577f163 --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/core/PlatformManager.java @@ -0,0 +1,34 @@ +package com.gmail.nossr50.core; + +import com.gmail.nossr50.core.adapters.NMS_114.BukkitPlatformAdapter; +import com.gmail.nossr50.core.adapters.PlatformAdapter; +import com.gmail.nossr50.mcMMO; + +public class PlatformManager { + private PlatformAdapter platformAdapter; + private mcMMO pluginRef; + + public PlatformManager(mcMMO pluginRef) { + this.pluginRef = pluginRef; + initAdapters(); + } + + /** + * Initialize the adapters based on the current platform + */ + private void initAdapters() { + pluginRef.getLogger().info("Initializing platform adapters..."); + //Determine which platform we are on and load the correct adapter + //For now this will be hardcoded for testing purposes + platformAdapter = new BukkitPlatformAdapter(); + } + + /** + * Get the current platform adapter implementation + * @return the current platform adapter + */ + public PlatformAdapter getPlatformAdapter() { + return platformAdapter; + } + +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/core/adapters/NBTAdapter.java b/mcmmo-core/src/main/java/com/gmail/nossr50/core/adapters/NBTAdapter.java new file mode 100644 index 000000000..7013f0d3b --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/core/adapters/NBTAdapter.java @@ -0,0 +1,13 @@ +package com.gmail.nossr50.core.adapters; + +import com.gmail.nossr50.core.nbt.NBTBase; + +public interface NBTAdapter { + + /** + * Transform our NBT type representation to its implementation on the target platform + * @param nbtBase target NBT type representation + * @return platform specific implementation of our NBT Type + */ + Object asNative(NBTBase nbtBase); +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/core/adapters/NMS_114/BukkitNBTAdapter.java b/mcmmo-core/src/main/java/com/gmail/nossr50/core/adapters/NMS_114/BukkitNBTAdapter.java new file mode 100644 index 000000000..431c5a9ea --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/core/adapters/NMS_114/BukkitNBTAdapter.java @@ -0,0 +1,158 @@ +package com.gmail.nossr50.core.adapters.NMS_114; + +import com.gmail.nossr50.core.adapters.NBTAdapter; +import com.gmail.nossr50.core.nbt.NBTBase; +import com.gmail.nossr50.core.nbt.NBTList; +import com.gmail.nossr50.core.nbt.*; +import net.minecraft.server.v1_14_R1.*; + +public class BukkitNBTAdapter implements NBTAdapter { + + @Override + public Object asNative(NBTBase nbtBase) { + switch(nbtBase.getNBTType()) { + case END: + return new NBTTagEnd(); + case BYTE: + return asNativeNBTByte((NBTByte) nbtBase); + case SHORT: + return asNativeNBTShort((NBTShort) nbtBase); + case INT: + return asNativeNBTInt((NBTInt) nbtBase); + case LONG: + return asNativeNBTLong((NBTLong) nbtBase); + case FLOAT: + return asNativeNBTFloat((NBTFloat) nbtBase); + case DOUBLE: + return asNativeNBTDouble((NBTDouble) nbtBase); + case BYTE_ARRAY: + return asNativeNBTByteArray((NBTByteArray) nbtBase); + case STRING: + return asNativeNBTString((NBTString) nbtBase); + case LIST: + return asNativeNBTList((NBTList) nbtBase); + case COMPOUND: + return asNativeNBTCompound((NBTCompound) nbtBase); + case INT_ARRAY: + return asNativeNBTIntArray((NBTIntArray) nbtBase); + case LONG_ARRAY: + return asNativeNBTLongArray((NBTLongArray) nbtBase); + } + + return null; + } + + /** + * Create a NBTTagByte (NMS Type) from our NBTByte representation + * @param nbtByte target NBTByte + * @return NBTTagByte copy of our NBTByte representation + */ + private NBTTagByte asNativeNBTByte(NBTByte nbtByte) { + return new NBTTagByte(nbtByte.getValue()); + } + + /** + * Create a NBTTagShort (NMS Type) from our NBTShort representation + * @param nbtShort target NBTShort + * @return NBTTagShort copy of our NBTShort representation + */ + private NBTTagShort asNativeNBTShort(NBTShort nbtShort) { + return new NBTTagShort(nbtShort.getValue()); + } + + /** + * Create a NBTTagInt (NMS Type) from our NBTInt representation + * @param nbtInt target NBTInt + * @return NBTTagInt copy of our NBTInt representation + */ + private NBTTagInt asNativeNBTInt(NBTInt nbtInt) { + return new NBTTagInt(nbtInt.getValue()); + } + + /** + * Create a NBTTagLong (NMS Type) from our NBTLong representation + * @param nbtLong target NBTLong + * @return NBTTagLong copy of our NBTLong representation + */ + private NBTTagLong asNativeNBTLong(NBTLong nbtLong) { + return new NBTTagLong(nbtLong.getValue()); + } + + /** + * Create a NBTTagFloat (NMS Type) from our NBTFloat representation + * @param nbtFloat target NBTFloat + * @return NBTTagFloat copy of our NBTFloat representation + */ + private NBTTagFloat asNativeNBTFloat(NBTFloat nbtFloat) { + return new NBTTagFloat(nbtFloat.getValue()); + } + + /** + * Create a NBTTagDouble (NMS Type) from our NBTDouble representation + * @param nbtDouble target NBTDouble + * @return NBTTagDouble copy of our NBTDouble representation + */ + private NBTTagDouble asNativeNBTDouble(NBTDouble nbtDouble) { + return new NBTTagDouble(nbtDouble.getValue()); + } + + /** + * Create a NBTTagByteArray (NMS Type) from our NBTByteArray representation + * @param nbtByteArray target NBTByteArray + * @return NBTTagByteArray copy of our NBTByteArray representation + */ + private NBTTagByteArray asNativeNBTByteArray(NBTByteArray nbtByteArray) { + return new NBTTagByteArray(nbtByteArray.getValues()); + } + + /** + * Create a NBTTagString (NMS Type) from our NBTString representation + * @param nbtString target NBTString + * @return NBTTagString copy of our NBTString representation + */ + private NBTTagString asNativeNBTString(NBTString nbtString) { + return new NBTTagString(nbtString.getValue()); + } + + /** + * Create a NBTTagList (NMS Type) from our NBTList representation + * @param nbtList target NBTList + * @return NBTTagList copy of our NBTList representation + */ + private NBTTagList asNativeNBTList(NBTList nbtList) { + NBTTagList nbtTagList = new NBTTagList(); + nbtList.setValues(nbtList.getValues()); + return nbtTagList; + } + + /** + * Create a NBTTagCompound (NMS Type) from our NBTCompound representation + * @param nbtCompound target NBTCompound + * @return NBTTagCompound copy of our NBTCompound representation + */ + //TODO: Finish + private NBTTagCompound asNativeNBTCompound(NBTCompound nbtCompound) { + System.out.println("FINISH asNativeNBTCompound()"); + NBTTagCompound nbtTagCompound = new NBTTagCompound(); + + return nbtTagCompound; + } + + /** + * Create a NBTTagIntArray (NMS Type) from our NBTIntArray representation + * @param nbtIntArray target NBTIntArray + * @return NBTTagIntArray copy of our NBTIntArray representation + */ + private NBTTagIntArray asNativeNBTIntArray(NBTIntArray nbtIntArray) { + return new NBTTagIntArray(nbtIntArray.getValues()); + } + + /** + * Create a NBTTagLongArray (NMS Type) from our NBTLongArray representation + * @param nbtLongArray target NBTLongArray + * @return NBTTagLongArray copy of our NBTLongArray representation + */ + private NBTTagLongArray asNativeNBTLongArray(NBTLongArray nbtLongArray) { + return new NBTTagLongArray(nbtLongArray.getValues()); + } +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/core/adapters/NMS_114/BukkitPlatformAdapter.java b/mcmmo-core/src/main/java/com/gmail/nossr50/core/adapters/NMS_114/BukkitPlatformAdapter.java new file mode 100644 index 000000000..5dee0d806 --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/core/adapters/NMS_114/BukkitPlatformAdapter.java @@ -0,0 +1,11 @@ +package com.gmail.nossr50.core.adapters.NMS_114; + +import com.gmail.nossr50.core.adapters.PlatformAdapter; + +public class BukkitPlatformAdapter extends PlatformAdapter { + + public BukkitPlatformAdapter() { + super(new BukkitNBTAdapter()); + } + +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/core/adapters/PlatformAdapter.java b/mcmmo-core/src/main/java/com/gmail/nossr50/core/adapters/PlatformAdapter.java new file mode 100644 index 000000000..0d49ac52e --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/core/adapters/PlatformAdapter.java @@ -0,0 +1,19 @@ +package com.gmail.nossr50.core.adapters; + +public abstract class PlatformAdapter { + + private NBTAdapter nbtAdapter; //nbt + + public PlatformAdapter(NBTAdapter nbtAdapter) { + this.nbtAdapter = nbtAdapter; + } + + /** + * Get the NBT Adapter for this platform + * @return the platform's NBT adapter + */ + public NBTAdapter getNbtAdapter() { + return nbtAdapter; + } + +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTBase.java b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTBase.java new file mode 100644 index 000000000..620100b85 --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTBase.java @@ -0,0 +1,11 @@ +package com.gmail.nossr50.core.nbt; + +public interface NBTBase { + + /** + * Get the NBTType for this NBTBase + * @return this NBTType + */ + NBTType getNBTType(); + +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTByte.java b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTByte.java new file mode 100644 index 000000000..d484da24d --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTByte.java @@ -0,0 +1,45 @@ +package com.gmail.nossr50.core.nbt; + +import java.util.Objects; + +public class NBTByte implements NBTBase { + + private byte value; + + public NBTByte(byte value) { + this.value = value; + } + + @Override + public NBTType getNBTType() { + return NBTType.BYTE; + } + + public byte getValue() { + return value; + } + + public void setValue(byte value) { + this.value = value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + NBTByte nbtByte = (NBTByte) o; + return value == nbtByte.value; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public String toString() { + return "NBTByte{" + + "value=" + value + + '}'; + } +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTByteArray.java b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTByteArray.java new file mode 100644 index 000000000..bd6fdaa27 --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTByteArray.java @@ -0,0 +1,49 @@ +package com.gmail.nossr50.core.nbt; + +import java.util.Arrays; + +public class NBTByteArray implements NBTBase { + + private byte[] values; + + public NBTByteArray(byte[] values) { + this.values = values; + } + + @Override + public NBTType getNBTType() { + return NBTType.BYTE_ARRAY; + } + + public int getLength() { + return values.length; + } + + public byte[] getValues() { + return values; + } + + public void setValues(byte[] values) { + this.values = values; + } + + @Override + public String toString() { + return "NBTByteArray{" + + "values=" + Arrays.toString(values) + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + NBTByteArray that = (NBTByteArray) o; + return Arrays.equals(values, that.values); + } + + @Override + public int hashCode() { + return Arrays.hashCode(values); + } +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTCompound.java b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTCompound.java new file mode 100644 index 000000000..a34150975 --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTCompound.java @@ -0,0 +1,65 @@ +package com.gmail.nossr50.core.nbt; + +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.util.*; + +public class NBTCompound implements NBTBase { + + @NonNull + private Map tagMap; + + public NBTCompound() { + tagMap = new LinkedHashMap<>(); + } + + @Override + public NBTType getNBTType() { + return NBTType.COMPOUND; + } + + public NBTBase getTag(String key) { + return tagMap.get(key); + } + + public void addNBT(String tagKey, NBTBase nbt) { + tagMap.put(tagKey, nbt); + } + + public Collection getMapValues() { + return tagMap.values(); + } + + public Set getMapKeys() { + return tagMap.keySet(); + } + + public int getMapSize() { + return tagMap.size(); + } + + public void removeEntry(String tagKey) { + tagMap.remove(tagKey); + } + + @Override + public String toString() { + return "NBTCompound{" + + "tagMap=" + tagMap + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + NBTCompound that = (NBTCompound) o; + return tagMap.equals(that.tagMap); + } + + @Override + public int hashCode() { + return Objects.hash(tagMap); + } +} + diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTDouble.java b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTDouble.java new file mode 100644 index 000000000..979ba526a --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTDouble.java @@ -0,0 +1,45 @@ +package com.gmail.nossr50.core.nbt; + +import java.util.Objects; + +public class NBTDouble implements NBTBase { + + private double value; + + public NBTDouble(double value) { + this.value = value; + } + + @Override + public NBTType getNBTType() { + return NBTType.DOUBLE; + } + + public double getValue() { + return value; + } + + public void setValue(double value) { + this.value = value; + } + + @Override + public String toString() { + return "NBTDouble{" + + "value=" + value + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + NBTDouble nbtDouble = (NBTDouble) o; + return Double.compare(nbtDouble.value, value) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTEnd.java b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTEnd.java new file mode 100644 index 000000000..71bf1d7ef --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTEnd.java @@ -0,0 +1,8 @@ +package com.gmail.nossr50.core.nbt; + +public class NBTEnd implements NBTBase { + @Override + public NBTType getNBTType() { + return NBTType.END; + } +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTFloat.java b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTFloat.java new file mode 100644 index 000000000..98a401da5 --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTFloat.java @@ -0,0 +1,45 @@ +package com.gmail.nossr50.core.nbt; + +import java.util.Objects; + +public class NBTFloat implements NBTBase { + + private float value; + + public NBTFloat(float value) { + this.value = value; + } + + @Override + public NBTType getNBTType() { + return NBTType.FLOAT; + } + + public float getValue() { + return value; + } + + public void setValue(float value) { + this.value = value; + } + + @Override + public String toString() { + return "NBTFloat{" + + "value=" + value + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + NBTFloat nbtFloat = (NBTFloat) o; + return Float.compare(nbtFloat.value, value) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTInt.java b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTInt.java new file mode 100644 index 000000000..85f87a9fa --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTInt.java @@ -0,0 +1,45 @@ +package com.gmail.nossr50.core.nbt; + +import java.util.Objects; + +public class NBTInt implements NBTBase { + + private int value; + + public NBTInt(int value) { + this.value = value; + } + + @Override + public NBTType getNBTType() { + return NBTType.INT; + } + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } + + @Override + public String toString() { + return "NBTInt{" + + "value=" + value + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + NBTInt nbtInt = (NBTInt) o; + return value == nbtInt.value; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTIntArray.java b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTIntArray.java new file mode 100644 index 000000000..05e0bf518 --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTIntArray.java @@ -0,0 +1,49 @@ +package com.gmail.nossr50.core.nbt; + +import java.util.Arrays; + +public class NBTIntArray implements NBTBase { + + private int[] values; + + public NBTIntArray(int[] values) { + this.values = values; + } + + @Override + public NBTType getNBTType() { + return NBTType.INT_ARRAY; + } + + public int getLength() { + return values.length; + } + + public int[] getValues() { + return values; + } + + public void setValues(int[] values) { + this.values = values; + } + + @Override + public String toString() { + return "NBTIntArray{" + + "values=" + Arrays.toString(values) + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + NBTIntArray that = (NBTIntArray) o; + return Arrays.equals(values, that.values); + } + + @Override + public int hashCode() { + return Arrays.hashCode(values); + } +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTList.java b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTList.java new file mode 100644 index 000000000..706e4b68e --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTList.java @@ -0,0 +1,53 @@ +package com.gmail.nossr50.core.nbt; + +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.util.List; +import java.util.Objects; + +public class NBTList implements NBTBase { + + @NonNull + private List values; + + public NBTList(@NonNull List values) { + this.values = values; + } + + @Override + public NBTType getNBTType() { + return NBTType.LIST; + } + + public int getLength() { + return values.size(); + } + + public List getValues() { + return values; + } + + public void setValues(@NonNull List values) { + this.values = values; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + NBTList nbtList = (NBTList) o; + return values.equals(nbtList.values); + } + + @Override + public int hashCode() { + return Objects.hash(values); + } + + @Override + public String toString() { + return "NBTList{" + + "values=" + values + + '}'; + } +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTLong.java b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTLong.java new file mode 100644 index 000000000..35225fe47 --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTLong.java @@ -0,0 +1,45 @@ +package com.gmail.nossr50.core.nbt; + +import java.util.Objects; + +public class NBTLong implements NBTBase { + + private long value; + + public NBTLong(long value) { + this.value = value; + } + + public long getValue() { + return value; + } + + public void setValue(long value) { + this.value = value; + } + + @Override + public NBTType getNBTType() { + return NBTType.LONG; + } + + @Override + public String toString() { + return "NBTLong{" + + "value=" + value + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + NBTLong nbtLong = (NBTLong) o; + return value == nbtLong.value; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTLongArray.java b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTLongArray.java new file mode 100644 index 000000000..482ec9c6a --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTLongArray.java @@ -0,0 +1,49 @@ +package com.gmail.nossr50.core.nbt; + +import java.util.Arrays; + +public class NBTLongArray implements NBTBase { + + private long[] values; + + public NBTLongArray(long[] values) { + this.values = values; + } + + @Override + public NBTType getNBTType() { + return NBTType.LONG_ARRAY; + } + + public int getLength() { + return values.length; + } + + public long[] getValues() { + return values; + } + + public void setValues(long[] values) { + this.values = values; + } + + @Override + public String toString() { + return "NBTLongArray{" + + "values=" + Arrays.toString(values) + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + NBTLongArray that = (NBTLongArray) o; + return Arrays.equals(values, that.values); + } + + @Override + public int hashCode() { + return Arrays.hashCode(values); + } +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTShort.java b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTShort.java new file mode 100644 index 000000000..8b508c055 --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTShort.java @@ -0,0 +1,45 @@ +package com.gmail.nossr50.core.nbt; + +import java.util.Objects; + +public class NBTShort implements NBTBase { + + private short value; + + public NBTShort(short value) { + this.value = value; + } + + @Override + public NBTType getNBTType() { + return NBTType.SHORT; + } + + public short getValue() { + return value; + } + + public void setValue(short value) { + this.value = value; + } + + @Override + public String toString() { + return "NBTShort{" + + "value=" + value + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + NBTShort nbtShort = (NBTShort) o; + return value == nbtShort.value; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTString.java b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTString.java new file mode 100644 index 000000000..4f5a763c9 --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTString.java @@ -0,0 +1,50 @@ +package com.gmail.nossr50.core.nbt; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; + +public class NBTString implements NBTBase { + + @NonNull + private String value; + + public NBTString(@NonNull String value) { + this.value = value; + } + + @Override + public NBTType getNBTType() { + return NBTType.STRING; + } + + @NotNull + public String getValue() { + return value; + } + + public void setValue(@NotNull String value) { + this.value = value; + } + + @Override + public String toString() { + return "NBTString{" + + "value='" + value + '\'' + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + NBTString nbtString = (NBTString) o; + return value.equals(nbtString.value); + } + + @Override + public int hashCode() { + return Objects.hash(value); + } +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTType.java b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTType.java new file mode 100644 index 000000000..40d162dbf --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/core/nbt/NBTType.java @@ -0,0 +1,22 @@ +package com.gmail.nossr50.core.nbt; + +/** + * Represents the NBT Type + * Based on NBT Structure in 1.14.4 + */ +public enum NBTType { + ////String[] a = new String[]{"END", "BYTE", "SHORT", "INT", "LONG", "FLOAT", "DOUBLE", "BYTE[]", "STRING", "LIST", "COMPOUND", "INT[]", "LONG[]"}; + END, + BYTE, + SHORT, + INT, + LONG, + FLOAT, + DOUBLE, + BYTE_ARRAY, + STRING, + LIST, + COMPOUND, + INT_ARRAY, + LONG_ARRAY +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/meta/OldName.java b/mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/meta/OldName.java index 60907b342..9aac9b224 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/meta/OldName.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/meta/OldName.java @@ -11,4 +11,5 @@ public class OldName extends FixedMetadataValue { public OldName(String oldName, mcMMO plugin) { super(plugin, oldName); } + } diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/meta/RecentlyReplantedCropMeta.java b/mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/meta/RecentlyReplantedCropMeta.java new file mode 100644 index 000000000..20d8e00df --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/meta/RecentlyReplantedCropMeta.java @@ -0,0 +1,17 @@ +package com.gmail.nossr50.datatypes.meta; + +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.plugin.Plugin; + +public class RecentlyReplantedCropMeta extends FixedMetadataValue { + + /** + * Initializes a FixedMetadataValue with an Object + * + * @param owningPlugin the {@link Plugin} that created this metadata value + */ + public RecentlyReplantedCropMeta(Plugin owningPlugin, Boolean recentlyPlanted) { + super(owningPlugin, recentlyPlanted); + } + +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/skills/behaviours/HerbalismBehaviour.java b/mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/skills/behaviours/HerbalismBehaviour.java index 4aeadb38e..2fbe6e8fa 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/skills/behaviours/HerbalismBehaviour.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/skills/behaviours/HerbalismBehaviour.java @@ -1,6 +1,5 @@ package com.gmail.nossr50.datatypes.skills.behaviours; -import com.gmail.nossr50.core.MetadataConstants; import com.gmail.nossr50.mcMMO; import org.bukkit.Material; import org.bukkit.block.BlockState; @@ -23,7 +22,8 @@ public class HerbalismBehaviour { /** * Convert blocks affected by the Green Thumb & Green Terra abilities. * - * @param blockState The {@link BlockState} to check ability activation for + * @param blockState + * The {@link BlockState} to check ability activation for * @return true if the ability was successful, false otherwise */ public boolean convertGreenTerraBlocks(BlockState blockState) { @@ -36,16 +36,16 @@ public class HerbalismBehaviour { blockState.setType(Material.MOSSY_STONE_BRICKS); return true; - case DIRT: - case GRASS_PATH: + case DIRT : + case GRASS_PATH : blockState.setType(Material.GRASS_BLOCK); return true; - case COBBLESTONE: + case COBBLESTONE : blockState.setType(Material.MOSSY_COBBLESTONE); return true; - default: + default : return false; } } @@ -53,29 +53,21 @@ public class HerbalismBehaviour { /** * Convert blocks affected by the Green Thumb & Green Terra abilities. * - * @param blockState The {@link BlockState} to check ability activation for + * @param blockState + * The {@link BlockState} to check ability activation for * @return true if the ability was successful, false otherwise */ public boolean convertShroomThumb(BlockState blockState) { switch (blockState.getType()) { - case DIRT: + case DIRT : case GRASS_BLOCK: - case GRASS_PATH: + case GRASS_PATH : blockState.setType(Material.MYCELIUM); return true; - default: + default : return false; } } - /** - * Check if the block has a recently grown crop from Green Thumb - * - * @param blockState The {@link BlockState} to check green thumb regrown for - * @return true if the block is recently regrown, false otherwise - */ - public boolean isRecentlyRegrown(BlockState blockState) { - return blockState.hasMetadata(MetadataConstants.GREEN_THUMB_METAKEY) && !pluginRef.getSkillTools().cooldownExpired(blockState.getMetadata(MetadataConstants.GREEN_THUMB_METAKEY).get(0).asInt(), 1); - } } diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/dumpster/HolidayManager.java b/mcmmo-core/src/main/java/com/gmail/nossr50/dumpster/HolidayManager.java index 1da8bccd3..7610ef00d 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/dumpster/HolidayManager.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/dumpster/HolidayManager.java @@ -370,7 +370,7 @@ // int levelTotal = Misc.getRandom().nextInt(1 + pluginRef.getUserManager().getPlayer(player).getSkillLevel(PrimarySkillType.MINING)) + 1; // pluginRef.getSoundManager().sendSound(player, player.getLocation(), SoundType.LEVEL_UP); // mcMMO.getNotificationManager().sendPlayerInformation(player, NotificationType.HOLIDAY, "Holiday.AprilFools.Levelup", StringUtils.getCapitalized(fakeSkillType.toString()), String.valueOf(levelTotal)); -//// ParticleEffectUtils.fireworkParticleShower(player, ALL_COLORS.get(Misc.getRandom().nextInt(ALL_COLORS.size()))); +//// pluginRef.getParticleEffectUtils().fireworkParticleShower(player, ALL_COLORS.get(Misc.getRandom().nextInt(ALL_COLORS.size()))); // } // // public void registerAprilCommand() { diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/dumpster/SalvageManager.java b/mcmmo-core/src/main/java/com/gmail/nossr50/dumpster/SalvageManager.java new file mode 100644 index 000000000..1c2fca938 --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/dumpster/SalvageManager.java @@ -0,0 +1,330 @@ +//package com.gmail.nossr50.skills.salvage; +// +//import com.gmail.nossr50.config.AdvancedConfig; +//import com.gmail.nossr50.config.Config; +//import com.gmail.nossr50.config.experience.ExperienceConfig; +//import com.gmail.nossr50.datatypes.interactions.NotificationType; +//import com.gmail.nossr50.datatypes.player.McMMOPlayer; +//import com.gmail.nossr50.datatypes.skills.PrimarySkillType; +//import com.gmail.nossr50.datatypes.skills.SubSkillType; +//import com.gmail.nossr50.locale.LocaleLoader; +//import com.gmail.nossr50.mcMMO; +//import com.gmail.nossr50.skills.SkillManager; +//import com.gmail.nossr50.skills.salvage.salvageables.Salvageable; +//import com.gmail.nossr50.util.EventUtils; +//import com.gmail.nossr50.util.Misc; +//import com.gmail.nossr50.util.Permissions; +//import com.gmail.nossr50.util.StringUtils; +//import com.gmail.nossr50.util.player.NotificationManager; +//import com.gmail.nossr50.util.random.RandomChanceSkillStatic; +//import com.gmail.nossr50.util.random.RandomChanceUtil; +//import com.gmail.nossr50.util.skills.RankUtils; +//import com.gmail.nossr50.util.skills.SkillUtils; +//import com.gmail.nossr50.util.sounds.SoundManager; +//import com.gmail.nossr50.util.sounds.SoundType; +//import org.bukkit.Location; +//import org.bukkit.Material; +//import org.bukkit.enchantments.Enchantment; +//import org.bukkit.entity.Player; +//import org.bukkit.inventory.ItemStack; +//import org.bukkit.inventory.meta.EnchantmentStorageMeta; +// +//import java.util.Map; +//import java.util.Map.Entry; +// +//public class SalvageManager extends SkillManager { +// private boolean placedAnvil; +// private int lastClick; +// +// public SalvageManager(McMMOPlayer mcMMOPlayer) { +// super(mcMMOPlayer, PrimarySkillType.SALVAGE); +// } +// +// /** +// * Handles notifications for placing an anvil. +// */ +// public void placedAnvilCheck() { +// Player player = getPlayer(); +// +// if (getPlacedAnvil()) { +// return; +// } +// +// if (Config.getInstance().getSalvageAnvilMessagesEnabled()) { +// NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Salvage.Listener.Anvil"); +// } +// +// if (Config.getInstance().getSalvageAnvilPlaceSoundsEnabled()) { +// SoundManager.sendSound(player, player.getLocation(), SoundType.ANVIL); +// } +// +// togglePlacedAnvil(); +// } +// +// public void handleSalvage(Location location, ItemStack item) { +// Player player = getPlayer(); +// +// Salvageable salvageable = mcMMO.getSalvageableManager().getSalvageable(item.getType()); +// +// if (item.getItemMeta() != null && item.getItemMeta().isUnbreakable()) { +// NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Anvil.Unbreakable"); +// return; +// } +// +// // Permissions checks on material and item types +// if (!Permissions.salvageItemType(player, salvageable.getSalvageItemType())) { +// NotificationManager.sendPlayerInformation(player, NotificationType.NO_PERMISSION, "mcMMO.NoPermission"); +// return; +// } +// +// if (!Permissions.salvageMaterialType(player, salvageable.getSalvageMaterialType())) { +// NotificationManager.sendPlayerInformation(player, NotificationType.NO_PERMISSION, "mcMMO.NoPermission"); +// return; +// } +// +// /*int skillLevel = getSkillLevel();*/ +// int minimumSalvageableLevel = salvageable.getMinimumLevel(); +// +// // Level check +// if (getSkillLevel() < minimumSalvageableLevel) { +// NotificationManager.sendPlayerInformation(player, NotificationType.REQUIREMENTS_NOT_MET, "Salvage.Skills.Adept.Level", String.valueOf(RankUtils.getUnlockLevel(SubSkillType.SALVAGE_ARCANE_SALVAGE)), StringUtils.getPrettyItemString(item.getType())); +// return; +// } +// +// int potentialSalvageYield = Salvage.calculateSalvageableAmount(item.getDurability(), salvageable.getMaximumDurability(), salvageable.getMaximumQuantity()); +// +// if (potentialSalvageYield <= 0) { +// NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Salvage.Skills.TooDamaged"); +// return; +// } +// +// potentialSalvageYield = Math.min(potentialSalvageYield, getSalvageLimit()); // Always get at least something back, if you're capable of salvaging it. +// +// player.getInventory().setItemInMainHand(new ItemStack(Material.AIR)); +// location.add(0.5, 1, 0.5); +// +// Map enchants = item.getEnchantments(); +// +// ItemStack enchantBook = null; +// if (!enchants.isEmpty()) { +// enchantBook = arcaneSalvageCheck(enchants); +// } +// +// //Lottery on Salvageable Amount +// +// int lotteryResults = 1; +// int chanceOfSuccess = 99; +// +// for(int x = 0; x < potentialSalvageYield-1; x++) { +// +// if(RandomChanceUtil.rollDice(chanceOfSuccess, 100)) { +// chanceOfSuccess-=3; +// chanceOfSuccess = Math.max(chanceOfSuccess, 90); +// +// lotteryResults+=1; +// } +// } +// +// if(lotteryResults == potentialSalvageYield && potentialSalvageYield != 1 && RankUtils.isPlayerMaxRankInSubSkill(player, SubSkillType.SALVAGE_ARCANE_SALVAGE)) { +// NotificationManager.sendPlayerInformationChatOnly(player, "Salvage.Skills.Lottery.Perfect", String.valueOf(lotteryResults), StringUtils.getPrettyItemString(item.getType())); +// } else if(salvageable.getMaximumQuantity() == 1 || getSalvageLimit() >= salvageable.getMaximumQuantity()) { +// NotificationManager.sendPlayerInformationChatOnly(player, "Salvage.Skills.Lottery.Normal", String.valueOf(lotteryResults), StringUtils.getPrettyItemString(item.getType())); +// } else { +// NotificationManager.sendPlayerInformationChatOnly(player, "Salvage.Skills.Lottery.Untrained", String.valueOf(lotteryResults), StringUtils.getPrettyItemString(item.getType())); +// } +// +// ItemStack salvageResults = new ItemStack(salvageable.getSalvageMaterial(), lotteryResults); +// +// //Call event +// if (EventUtils.callSalvageCheckEvent(player, item, salvageResults, enchantBook).isCancelled()) { +// return; +// } +// +// Location anvilLoc = location.clone(); +// Location playerLoc = player.getLocation().clone(); +// double distance = anvilLoc.distance(playerLoc); +// +// double speedLimit = .6; +// double minSpeed = .3; +// +// //Clamp the speed and vary it by distance +// double vectorSpeed = Math.min(speedLimit, Math.max(minSpeed, distance * .2)); +// +// //Add a very small amount of height +// anvilLoc.add(0, .1, 0); +// +// if (enchantBook != null) { +// Misc.spawnItemTowardsLocation(anvilLoc.clone(), playerLoc.clone(), enchantBook, vectorSpeed); +// } +// +// Misc.spawnItemTowardsLocation(anvilLoc.clone(), playerLoc.clone(), salvageResults, vectorSpeed); +// +// // BWONG BWONG BWONG - CLUNK! +// if (Config.getInstance().getSalvageAnvilUseSoundsEnabled()) { +// SoundManager.sendSound(player, player.getLocation(), SoundType.ITEM_BREAK); +// } +// +// NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Salvage.Skills.Success"); +// } +// +// /*public double getMaxSalvagePercentage() { +// return Math.min((((Salvage.salvageMaxPercentage / Salvage.salvageMaxPercentageLevel) * getSkillLevel()) / 100.0D), Salvage.salvageMaxPercentage / 100.0D); +// }*/ +// +// public int getSalvageLimit() { +// return (RankUtils.getRank(getPlayer(), SubSkillType.SALVAGE_SCRAP_COLLECTOR)); +// } +// +// /** +// * Gets the Arcane Salvage rank +// * +// * @return the current Arcane Salvage rank +// */ +// public int getArcaneSalvageRank() { +// return RankUtils.getRank(getPlayer(), SubSkillType.SALVAGE_ARCANE_SALVAGE); +// } +// +// /*public double getExtractFullEnchantChance() { +// int skillLevel = getSkillLevel(); +// +// for (Tier tier : Tier.values()) { +// if (skillLevel >= tier.getLevel()) { +// return tier.getExtractFullEnchantChance(); +// } +// } +// +// return 0; +// } +// +// public double getExtractPartialEnchantChance() { +// int skillLevel = getSkillLevel(); +// +// for (Tier tier : Tier.values()) { +// if (skillLevel >= tier.getLevel()) { +// return tier.getExtractPartialEnchantChance(); +// } +// } +// +// return 0; +// }*/ +// +// public double getExtractFullEnchantChance() { +// if(Permissions.hasSalvageEnchantBypassPerk(getPlayer())) +// return 100.0D; +// +// return AdvancedConfig.getInstance().getArcaneSalvageExtractFullEnchantsChance(getArcaneSalvageRank()); +// } +// +// public double getExtractPartialEnchantChance() { +// return AdvancedConfig.getInstance().getArcaneSalvageExtractPartialEnchantsChance(getArcaneSalvageRank()); +// } +// +// private ItemStack arcaneSalvageCheck(Map enchants) { +// Player player = getPlayer(); +// +// if (!RankUtils.hasUnlockedSubskill(player, SubSkillType.SALVAGE_ARCANE_SALVAGE) || !Permissions.arcaneSalvage(player)) { +// NotificationManager.sendPlayerInformationChatOnly(player, "Salvage.Skills.ArcaneFailed"); +// return null; +// } +// +// ItemStack book = new ItemStack(Material.ENCHANTED_BOOK); +// EnchantmentStorageMeta enchantMeta = (EnchantmentStorageMeta) book.getItemMeta(); +// +// boolean downgraded = false; +// int arcaneFailureCount = 0; +// +// for (Entry enchant : enchants.entrySet()) { +// +// int enchantLevel = enchant.getValue(); +// +// if(!ExperienceConfig.getInstance().allowUnsafeEnchantments()) { +// if(enchantLevel > enchant.getKey().getMaxLevel()) { +// enchantLevel = enchant.getKey().getMaxLevel(); +// } +// } +// +// if (!Salvage.arcaneSalvageEnchantLoss +// || Permissions.hasSalvageEnchantBypassPerk(player) +// || RandomChanceUtil.checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(getExtractFullEnchantChance(), getPlayer(), SubSkillType.SALVAGE_ARCANE_SALVAGE))) { +// enchantMeta.addStoredEnchant(enchant.getKey(), enchantLevel, true); +// } +// else if (enchantLevel > 1 +// && Salvage.arcaneSalvageDowngrades +// && RandomChanceUtil.checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(getExtractPartialEnchantChance(), getPlayer(), SubSkillType.SALVAGE_ARCANE_SALVAGE))) { +// enchantMeta.addStoredEnchant(enchant.getKey(), enchantLevel - 1, true); +// downgraded = true; +// } else { +// arcaneFailureCount++; +// } +// } +// +// if(failedAllEnchants(arcaneFailureCount, enchants.entrySet().size())) +// { +// NotificationManager.sendPlayerInformationChatOnly(player, "Salvage.Skills.ArcaneFailed"); +// return null; +// } else if(downgraded) +// { +// NotificationManager.sendPlayerInformationChatOnly(player, "Salvage.Skills.ArcanePartial"); +// } +// +// book.setItemMeta(enchantMeta); +// return book; +// } +// +// private boolean failedAllEnchants(int arcaneFailureCount, int size) { +// return arcaneFailureCount == size; +// } +// +// /** +// * Check if the player has tried to use an Anvil before. +// * @param actualize +// * +// * @return true if the player has confirmed using an Anvil +// */ +// public boolean checkConfirmation(boolean actualize) { +// Player player = getPlayer(); +// long lastUse = getLastAnvilUse(); +// +// if (!SkillUtils.cooldownExpired(lastUse, 3) || !Config.getInstance().getSalvageConfirmRequired()) { +// return true; +// } +// +// if (!actualize) { +// return false; +// } +// +// actualizeLastAnvilUse(); +// +// NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Skills.ConfirmOrCancel", LocaleLoader.getString("Salvage.Pretty.Name")); +// +// return false; +// } +// +// /* +// * Salvage Anvil Placement +// */ +// +// public boolean getPlacedAnvil() { +// return placedAnvil; +// } +// +// public void togglePlacedAnvil() { +// placedAnvil = !placedAnvil; +// } +// +// /* +// * Salvage Anvil Usage +// */ +// +// public int getLastAnvilUse() { +// return lastClick; +// } +// +// public void setLastAnvilUse(int value) { +// lastClick = value; +// } +// +// public void actualizeLastAnvilUse() { +// lastClick = (int) (System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR); +// } +//} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/listeners/BlockListener.java b/mcmmo-core/src/main/java/com/gmail/nossr50/listeners/BlockListener.java index 260e2a925..231a068ad 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/listeners/BlockListener.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/listeners/BlockListener.java @@ -397,27 +397,24 @@ public class BlockListener implements Listener { return; } + McMMOPlayer mcMMOPlayer = pluginRef.getUserManager().getPlayer(player); BlockState blockState = event.getBlock().getState(); ItemStack heldItem = player.getInventory().getItemInMainHand(); - if (pluginRef.getDynamicSettingsManager().getSkillBehaviourManager().getHerbalismBehaviour().isRecentlyRegrown(blockState)) { - event.setCancelled(true); - return; - } if (pluginRef.getItemTools().isSword(heldItem)) { - HerbalismManager herbalismManager = pluginRef.getUserManager().getPlayer(player).getHerbalismManager(); + HerbalismManager herbalismManager = mcMMOPlayer.getHerbalismManager(); - if (herbalismManager.canUseHylianLuck()) { - if (herbalismManager.processHylianLuck(blockState)) { - blockState.update(true); - event.setCancelled(true); - } else if (blockState.getType() == Material.FLOWER_POT) { - blockState.setType(Material.AIR); - blockState.update(true); - event.setCancelled(true); + if (herbalismManager.canUseHylianLuck()) { + if (herbalismManager.processHylianLuck(blockState)) { + blockState.update(true); + event.setCancelled(true); + } else if (blockState.getType() == Material.FLOWER_POT) { + blockState.setType(Material.AIR); + blockState.update(true); + event.setCancelled(true); + } } - } } /*else if (!heldItem.containsEnchantment(Enchantment.SILK_TOUCH)) { SmeltingManager smeltingManager = pluginRef.getUserManager().getPlayer(player).getSmeltingManager(); diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/listeners/EntityListener.java b/mcmmo-core/src/main/java/com/gmail/nossr50/listeners/EntityListener.java index 7e340f313..4cd1a5bb2 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/listeners/EntityListener.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/listeners/EntityListener.java @@ -352,12 +352,15 @@ public class EntityListener implements Listener { } //Deflect checks - UnarmedManager unarmedManager = pluginRef.getUserManager().getPlayer(defendingPlayer).getUnarmedManager(); + final McMMOPlayer mcMMOPlayer = pluginRef.getUserManager().getPlayer(defendingPlayer); + if (mcMMOPlayer != null) { + UnarmedManager unarmedManager = mcMMOPlayer.getUnarmedManager(); - if (unarmedManager.canDeflect()) { - if(unarmedManager.deflectCheck()) { - event.setCancelled(true); - return; + if (unarmedManager.canDeflect()) { + if (unarmedManager.deflectCheck()) { + event.setCancelled(true); + return; + } } } } else { diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java b/mcmmo-core/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java index 554a1e225..1a2adcc2e 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java @@ -900,4 +900,18 @@ public class PlayerListener implements Listener { } } } + +// @EventHandler(priority = EventPriority.LOWEST) +// public void onDebugPlayerInteract(PlayerInteractEvent event) { +// if(pluginRef.getUserManager().getPlayer(event.getPlayer()) != null) { +// McMMOPlayer mcMMOPlayer = pluginRef.getUserManager().getPlayer(event.getPlayer()); +// if(mcMMOPlayer.isDebugMode()) { +// switch(event.getAction()) { +// case LEFT_CLICK_AIR: +// case LEFT_CLICK_BLOCK: +// pluginRef.getNbtManager().debugNBTInMainHandItem(event.getPlayer()); +// } +// } +// } +// } } diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/locale/LocaleManager.java b/mcmmo-core/src/main/java/com/gmail/nossr50/locale/LocaleManager.java index 6b93cc074..aeec612ce 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/locale/LocaleManager.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/locale/LocaleManager.java @@ -124,7 +124,7 @@ public final class LocaleManager { } } - private static String addColors(String input) { + public static String addColors(String input) { input = input.replaceAll("\\Q[[BLACK]]\\E", ChatColor.BLACK.toString()); input = input.replaceAll("\\Q[[DARK_BLUE]]\\E", ChatColor.DARK_BLUE.toString()); input = input.replaceAll("\\Q[[DARK_GREEN]]\\E", ChatColor.DARK_GREEN.toString()); diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/mcMMO.java b/mcmmo-core/src/main/java/com/gmail/nossr50/mcMMO.java index 417051061..04306004d 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/mcMMO.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/mcMMO.java @@ -10,10 +10,11 @@ import com.gmail.nossr50.config.playerleveling.ConfigLeveling; import com.gmail.nossr50.config.scoreboard.ConfigScoreboard; import com.gmail.nossr50.core.DynamicSettingsManager; import com.gmail.nossr50.core.MaterialMapStore; +import com.gmail.nossr50.core.PlatformManager; import com.gmail.nossr50.database.DatabaseManager; import com.gmail.nossr50.database.DatabaseManagerFactory; import com.gmail.nossr50.datatypes.skills.subskills.acrobatics.Roll; -import com.gmail.nossr50.listeners.*; +import com.gmail.nossr50.listeners.InteractionManager; import com.gmail.nossr50.locale.LocaleManager; import com.gmail.nossr50.mcmmo.api.McMMOApi; import com.gmail.nossr50.mcmmo.api.platform.PlatformProvider; @@ -34,20 +35,17 @@ import com.gmail.nossr50.util.blockmeta.chunkmeta.ChunkManagerFactory; import com.gmail.nossr50.util.commands.CommandRegistrationManager; import com.gmail.nossr50.util.commands.CommandTools; import com.gmail.nossr50.util.experience.FormulaManager; +import com.gmail.nossr50.util.nbt.NBTManager; import com.gmail.nossr50.util.player.NotificationManager; import com.gmail.nossr50.util.player.PlayerLevelTools; import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.random.RandomChanceTools; import com.gmail.nossr50.util.scoreboards.ScoreboardManager; -import com.gmail.nossr50.util.skills.CombatTools; -import com.gmail.nossr50.util.skills.PerkUtils; -import com.gmail.nossr50.util.skills.RankTools; -import com.gmail.nossr50.util.skills.SkillTools; +import com.gmail.nossr50.util.skills.*; import com.gmail.nossr50.util.sounds.SoundManager; import com.gmail.nossr50.worldguard.WorldGuardManager; import com.gmail.nossr50.worldguard.WorldGuardUtils; import net.shatteredlands.shatt.backup.ZipLibrary; - import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.NamespacedKey; @@ -56,7 +54,6 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.Recipe; import org.bukkit.inventory.ShapelessRecipe; import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.plugin.PluginManager; import java.io.File; import java.io.IOException; @@ -73,7 +70,7 @@ public class mcMMO implements McMMOApi { private FormulaManager formulaManager; private NotificationManager notificationManager; private CommandRegistrationManager commandRegistrationManager; -// private NBTManager nbtManager; + private NBTManager nbtManager; private PartyManager partyManager; private LocaleManager localeManager; private ChatManager chatManager; @@ -82,9 +79,11 @@ public class mcMMO implements McMMOApi { private ScoreboardManager scoreboardManager; private SoundManager soundManager; private HardcoreManager hardcoreManager; + private PlatformManager platformManager; private WorldGuardManager worldGuardManager; /* Not-Managers but my naming scheme sucks */ + private ParticleEffectUtils particleEffectUtils; private DatabaseManagerFactory databaseManagerFactory; private ChunkManagerFactory chunkManagerFactory; private CommandTools commandTools; @@ -186,9 +185,10 @@ public class mcMMO implements McMMOApi { scheduleTasks(); commandRegistrationManager = new CommandRegistrationManager(this); + commandRegistrationManager.registerACFCommands(); commandRegistrationManager.registerCommands(); -// nbtManager = new NBTManager(); + nbtManager = new NBTManager(); //Init Chunk Manager Factory chunkManagerFactory = new ChunkManagerFactory(this); @@ -263,6 +263,9 @@ public class mcMMO implements McMMOApi { //Init PerkUtils perkUtils = new PerkUtils(this); + + //Init particle effect utils + particleEffectUtils = new ParticleEffectUtils(this); } private String getVersion() { @@ -763,4 +766,16 @@ public class mcMMO implements McMMOApi { public PerkUtils getPerkUtils() { return perkUtils; } + + public NBTManager getNbtManager() { + return nbtManager; + } + + public PlatformManager getPlatformManager() { + return platformManager; + } + + public ParticleEffectUtils getParticleEffectUtils() { + return particleEffectUtils; + } } diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/runnables/skills/BleedTimerTask.java b/mcmmo-core/src/main/java/com/gmail/nossr50/runnables/skills/BleedTimerTask.java index 1fc5b8920..1ce9d0e17 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/runnables/skills/BleedTimerTask.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/runnables/skills/BleedTimerTask.java @@ -3,7 +3,6 @@ package com.gmail.nossr50.runnables.skills; import com.gmail.nossr50.datatypes.interactions.NotificationType; import com.gmail.nossr50.datatypes.skills.BleedContainer; import com.gmail.nossr50.mcMMO; -import com.gmail.nossr50.util.skills.ParticleEffectUtils; import com.gmail.nossr50.util.sounds.SoundType; import org.bukkit.Bukkit; import org.bukkit.entity.LivingEntity; @@ -172,7 +171,7 @@ public class BleedTimerTask extends BukkitRunnable { //Play Bleed Sound pluginRef.getSoundManager().worldSendSound(target.getWorld(), target.getLocation(), SoundType.BLEED); - ParticleEffectUtils.playBleedEffect(target); + pluginRef.getParticleEffectUtils().playBleedEffect(target); } //Lower Bleed Ticks diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/runnables/skills/DelayedCropReplant.java b/mcmmo-core/src/main/java/com/gmail/nossr50/runnables/skills/DelayedCropReplant.java new file mode 100644 index 000000000..eb7456b6e --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/runnables/skills/DelayedCropReplant.java @@ -0,0 +1,100 @@ +package com.gmail.nossr50.runnables.skills; + +import com.gmail.nossr50.core.MetadataConstants; +import com.gmail.nossr50.datatypes.meta.RecentlyReplantedCropMeta; +import com.gmail.nossr50.mcMMO; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.block.data.Ageable; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.scheduler.BukkitRunnable; + +public class DelayedCropReplant extends BukkitRunnable { + + private final int desiredCropAge; + private final Location cropLocation; + private final Material cropMaterial; + private boolean wasImmaturePlant; + private final BlockBreakEvent blockBreakEvent; + private final mcMMO pluginRef; + + /** + * Replants a crop after a delay setting the age to desiredCropAge + * @param cropState target {@link BlockState} + * @param desiredCropAge desired age of the crop + */ + public DelayedCropReplant(mcMMO pluginRef, BlockBreakEvent blockBreakEvent, BlockState cropState, int desiredCropAge, boolean wasImmaturePlant) { + this.pluginRef = pluginRef; + //The plant was either immature or something cancelled the event, therefor we need to treat it differently + this.blockBreakEvent = blockBreakEvent; + this.wasImmaturePlant = wasImmaturePlant; + this.cropMaterial = cropState.getType(); + this.desiredCropAge = desiredCropAge; + this.cropLocation = cropState.getLocation(); + } + + @Override + public void run() { + Block cropBlock = cropLocation.getBlock(); + BlockState currentState = cropBlock.getState(); + + //Remove the metadata marking the block as recently replanted + new markPlantAsOld(blockBreakEvent.getBlock().getLocation()).runTaskLater(pluginRef, 10); + + if(blockBreakEvent.isCancelled()) { + wasImmaturePlant = true; + } + + //Two kinds of air in Minecraft + if(currentState.getType().equals(cropMaterial) || currentState.getType().equals(Material.AIR) || currentState.getType().equals(Material.CAVE_AIR)) { +// if(currentState.getBlock().getRelative(BlockFace.DOWN)) + //The space is not currently occupied by a block so we can fill it + cropBlock.setType(cropMaterial); + + //Get new state (necessary?) + BlockState newState = cropBlock.getState(); +// newState.update(); + + Ageable ageable = (Ageable) newState.getBlockData(); + + //Crop age should always be 0 if the plant was immature + if(wasImmaturePlant) { + ageable.setAge(0); + } else { + //Otherwise make the plant the desired age + ageable.setAge(desiredCropAge); + } + + //Age the crop + newState.setBlockData(ageable); + newState.update(true); + + //Play an effect + pluginRef.getParticleEffectUtils().playGreenThumbEffect(cropLocation); + + } + + } + + private class markPlantAsOld extends BukkitRunnable { + + private final Location cropLoc; + + public markPlantAsOld(Location cropLoc) { + this.cropLoc = cropLoc; + } + + @Override + public void run() { + Block cropBlock = cropLoc.getBlock(); + + if(cropBlock.getMetadata(MetadataConstants.REPLANT_META_KEY).size() > 0) { + cropBlock.setMetadata(MetadataConstants.REPLANT_META_KEY, new RecentlyReplantedCropMeta(pluginRef, false)); + pluginRef.getParticleEffectUtils().playFluxEffect(cropLocation); + } + } + } + +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java b/mcmmo-core/src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java index 874074c6f..98c9e045d 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java @@ -10,7 +10,6 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType; import com.gmail.nossr50.datatypes.skills.behaviours.AcrobaticsBehaviour; import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.skills.SkillManager; -import com.gmail.nossr50.util.skills.ParticleEffectUtils; import com.gmail.nossr50.util.skills.SkillActivationType; import org.bukkit.Location; import org.bukkit.entity.Entity; @@ -87,7 +86,7 @@ public class AcrobaticsManager extends SkillManager { Player player = getPlayer(); if (!isFatal(modifiedDamage) && pluginRef.getRandomChanceTools().isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.ACROBATICS_DODGE, player)) { - ParticleEffectUtils.playDodgeEffect(player); + pluginRef.getParticleEffectUtils().playDodgeEffect(player); if (mcMMOPlayer.useChatNotifications()) { pluginRef.getNotificationManager().sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Acrobatics.Combat.Proc"); diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/skills/axes/AxesManager.java b/mcmmo-core/src/main/java/com/gmail/nossr50/skills/axes/AxesManager.java index 54daa70d9..5250c2820 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/skills/axes/AxesManager.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/skills/axes/AxesManager.java @@ -9,7 +9,6 @@ import com.gmail.nossr50.datatypes.skills.ToolType; import com.gmail.nossr50.datatypes.skills.behaviours.AxesBehaviour; import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.skills.SkillManager; -import com.gmail.nossr50.util.skills.ParticleEffectUtils; import com.gmail.nossr50.util.skills.SkillActivationType; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; @@ -143,7 +142,7 @@ public class AxesManager extends SkillManager { Player player = getPlayer(); - ParticleEffectUtils.playGreaterImpactEffect(target); + pluginRef.getParticleEffectUtils().playGreaterImpactEffect(target); target.setVelocity(player.getLocation().getDirection().normalize().multiply(pluginRef.getConfigManager().getConfigAxes().getGreaterImpactKnockBackModifier())); if (mcMMOPlayer.useChatNotifications()) { diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/skills/herbalism/HerbalismManager.java b/mcmmo-core/src/main/java/com/gmail/nossr50/skills/herbalism/HerbalismManager.java index bac25c936..0d903a210 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/skills/herbalism/HerbalismManager.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/skills/herbalism/HerbalismManager.java @@ -5,6 +5,7 @@ import com.gmail.nossr50.datatypes.BlockSnapshot; import com.gmail.nossr50.datatypes.experience.XPGainReason; import com.gmail.nossr50.datatypes.experience.XPGainSource; import com.gmail.nossr50.datatypes.interactions.NotificationType; +import com.gmail.nossr50.datatypes.meta.RecentlyReplantedCropMeta; import com.gmail.nossr50.datatypes.player.BukkitMMOPlayer; import com.gmail.nossr50.datatypes.skills.PrimarySkillType; import com.gmail.nossr50.datatypes.skills.SubSkillType; @@ -12,11 +13,12 @@ import com.gmail.nossr50.datatypes.skills.SuperAbilityType; import com.gmail.nossr50.datatypes.skills.ToolType; import com.gmail.nossr50.datatypes.skills.behaviours.HerbalismBehaviour; import com.gmail.nossr50.mcMMO; +import com.gmail.nossr50.runnables.skills.DelayedCropReplant; import com.gmail.nossr50.runnables.skills.DelayedHerbalismXPCheckTask; -import com.gmail.nossr50.runnables.skills.HerbalismBlockUpdaterTask; import com.gmail.nossr50.skills.SkillManager; import com.gmail.nossr50.util.StringUtils; import com.gmail.nossr50.util.skills.SkillActivationType; +import com.gmail.nossr50.util.sounds.SoundType; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -27,7 +29,6 @@ import org.bukkit.entity.Player; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; -import org.bukkit.metadata.FixedMetadataValue; import java.util.ArrayList; import java.util.Collection; @@ -134,6 +135,23 @@ public class HerbalismManager extends SkillManager { return; } + //Check if the plant was recently replanted + if(blockBreakEvent.getBlock().getBlockData() instanceof Ageable) { + Ageable ageableCrop = (Ageable) blockBreakEvent.getBlock().getBlockData(); + + if(blockBreakEvent.getBlock().getMetadata(MetadataConstants.REPLANT_META_KEY).size() >= 1) { + if(blockBreakEvent.getBlock().getMetadata(MetadataConstants.REPLANT_META_KEY).get(0).asBoolean()) { + if(isAgeableMature(ageableCrop)) { + blockBreakEvent.getBlock().removeMetadata(MetadataConstants.REPLANT_META_KEY, pluginRef); + } else { + //Crop is recently replanted to back out of destroying it + blockBreakEvent.setCancelled(true); + return; + } + } + } + } + /* * There are single-block plants and multi-block plants in Minecraft * In order to give out proper rewards, we need to collect all blocks that would be broken from this event @@ -142,6 +160,9 @@ public class HerbalismManager extends SkillManager { //Grab all broken blocks HashSet brokenBlocks = getBrokenHerbalismBlocks(blockBreakEvent); + if(brokenBlocks.size() == 0) + return; + //Handle rewards, xp, ability interactions, etc processHerbalismOnBlocksBroken(blockBreakEvent, brokenBlocks); } @@ -153,10 +174,24 @@ public class HerbalismManager extends SkillManager { */ private void processHerbalismOnBlocksBroken(BlockBreakEvent blockBreakEvent, HashSet brokenPlants) { BlockState originalBreak = blockBreakEvent.getBlock().getState(); + boolean greenThumbActivated = false; //TODO: The design of Green Terra needs to change, this is a mess if(pluginRef.getPermissionTools().greenThumbPlant(getPlayer(), originalBreak.getType())) { - processGreenThumbPlants(originalBreak, isGreenTerraActive()); + if(!getPlayer().isSneaking()) { + greenThumbActivated = processGreenThumbPlants(originalBreak, blockBreakEvent, isGreenTerraActive()); + } + + } + + //When replanting a immature crop we cancel the block break event and back out + if(greenThumbActivated) { + if(originalBreak.getBlock().getBlockData() instanceof Ageable) { + Ageable ageableCrop = (Ageable) originalBreak.getBlock().getBlockData(); + if(!isAgeableMature(ageableCrop)) { + return; + } + } } /* @@ -339,9 +374,11 @@ public class HerbalismManager extends SkillManager { //Calculate XP if(plantData instanceof Ageable) { Ageable plantAgeable = (Ageable) plantData; + if(isAgeableMature(plantAgeable) || isBizarreAgeable(plantData)) { xpToReward += pluginRef.getDynamicSettingsManager().getExperienceManager().getHerbalismXp(brokenBlockNewState.getType()); } + } else { xpToReward += pluginRef.getDynamicSettingsManager().getExperienceManager().getHerbalismXp(brokenPlantBlock.getType()); } @@ -437,8 +474,7 @@ public class HerbalismManager extends SkillManager { } private HashSet getBrokenChorusBlocks(BlockState originalBreak) { - HashSet traversedBlocks = grabChorusTreeBrokenBlocksRecursive(originalBreak.getBlock(), new HashSet<>()); - return traversedBlocks; + return grabChorusTreeBrokenBlocksRecursive(originalBreak.getBlock(), new HashSet<>()); } private HashSet grabChorusTreeBrokenBlocksRecursive(Block currentBlock, HashSet traversed) { @@ -565,6 +601,7 @@ public class HerbalismManager extends SkillManager { * @param blockState The {@link BlockState} to check ability activation for * @return true if the ability was successful, false otherwise */ + //TODO: Fix hylian luck? Do we give a #*$%? public boolean processHylianLuck(BlockState blockState) { // if (!pluginRef.getRandomChanceTools().isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.HERBALISM_HYLIAN_LUCK, getPlayer())) { // return false; @@ -631,15 +668,38 @@ public class HerbalismManager extends SkillManager { return herbalismBehaviour.convertShroomThumb(blockState); } + /** + * Starts the delayed replant task and turns + * @param desiredCropAge the desired age of the crop + * @param blockBreakEvent the {@link BlockBreakEvent} this crop was involved in + * @param cropState the {@link BlockState} of the crop + */ + private void startReplantTask(int desiredCropAge, BlockBreakEvent blockBreakEvent, BlockState cropState, boolean isImmature) { + //Mark the plant as recently replanted to avoid accidental breakage + new DelayedCropReplant(pluginRef, blockBreakEvent, cropState, desiredCropAge, isImmature).runTaskLater(pluginRef, 20 * 2); + blockBreakEvent.getBlock().setMetadata(MetadataConstants.REPLANT_META_KEY, new RecentlyReplantedCropMeta(pluginRef, true)); + } + /** * Process the Green Thumb ability for plants. * * @param blockState The {@link BlockState} to check ability activation for * @param greenTerra boolean to determine if greenTerra is active or not */ - private void processGreenThumbPlants(BlockState blockState, boolean greenTerra) { - if (!pluginRef.getBlockTools().isFullyGrown(blockState)) - return; + private boolean processGreenThumbPlants(BlockState blockState, BlockBreakEvent blockBreakEvent, boolean greenTerra) { + if(!pluginRef.getItemTools().isHoe(blockBreakEvent.getPlayer().getInventory().getItemInMainHand())) { + return false; + } + + BlockData blockData = blockState.getBlockData(); + + if (!(blockData instanceof Ageable)) { + return false; + } + + Ageable ageable = (Ageable) blockData; + + //If the ageable is NOT mature and the player is NOT using a hoe, abort Player player = getPlayer(); PlayerInventory playerInventory = player.getInventory(); @@ -671,36 +731,49 @@ public class HerbalismManager extends SkillManager { break; default: - return; + return false; } ItemStack seedStack = new ItemStack(seed); if (!greenTerra && !pluginRef.getRandomChanceTools().checkRandomChanceExecutionSuccess(player, SubSkillType.HERBALISM_GREEN_THUMB)) { - return; + return false; } - if (!processGrowingPlants(blockState, greenTerra)) { - return; + + if (!playerInventory.containsAtLeast(seedStack, 1)) { + return false; } - if (!pluginRef.getItemTools().isHoe(getPlayer().getInventory().getItemInMainHand())) { - if (!playerInventory.containsAtLeast(seedStack, 1)) { - return; - } - - playerInventory.removeItem(seedStack); - player.updateInventory(); // Needed until replacement available + if (!processGrowingPlants(blockState, ageable, blockBreakEvent, greenTerra)) { + return false; } - new HerbalismBlockUpdaterTask(blockState).runTaskLater(pluginRef, 0); + playerInventory.removeItem(seedStack); + player.updateInventory(); // Needed until replacement available + //Play sound + pluginRef.getSoundManager().sendSound(player, player.getLocation(), SoundType.ITEM_CONSUMED); + return true; +// new HerbalismBlockUpdaterTask(blockState).runTaskLater(mcMMO.p, 0); } - private boolean processGrowingPlants(BlockState blockState, boolean greenTerra) { - int greenThumbStage = getGreenThumbStage(); + private boolean processGrowingPlants(BlockState blockState, Ageable ageable, BlockBreakEvent blockBreakEvent, boolean greenTerra) { + //This check is needed + if(isBizarreAgeable(ageable)) { + return false; + } - blockState.setMetadata(MetadataConstants.GREEN_THUMB_METAKEY, new FixedMetadataValue(pluginRef, (int) (System.currentTimeMillis() / pluginRef.getMiscTools().TIME_CONVERSION_FACTOR))); - Ageable crops = (Ageable) blockState.getBlockData(); + int finalAge = 0; + int greenThumbStage = getGreenThumbStage(greenTerra); + + //Immature plants will start over at 0 + if(!isAgeableMature(ageable)) { +// blockBreakEvent.setCancelled(true); + startReplantTask(0, blockBreakEvent, blockState, true); +// blockState.setType(Material.AIR); + blockBreakEvent.setDropItems(false); + return true; + } switch (blockState.getType()) { @@ -708,42 +781,47 @@ public class HerbalismManager extends SkillManager { case CARROTS: case WHEAT: - if (greenTerra) { - crops.setAge(3); - } else { - crops.setAge(greenThumbStage); - } + finalAge = getGreenThumbStage(greenTerra); break; case BEETROOTS: case NETHER_WART: if (greenTerra || greenThumbStage > 2) { - crops.setAge(2); - } else if (greenThumbStage == 2) { - crops.setAge(1); - } else { - crops.setAge(0); + finalAge = 2; + } + else if (greenThumbStage == 2) { + finalAge = 1; + } + else { + finalAge = 0; } break; case COCOA: - if (greenTerra || getGreenThumbStage() > 1) { - crops.setAge(1); - } else { - crops.setAge(0); + if (getGreenThumbStage(greenTerra) >= 2) { + finalAge = 1; + } + else { + finalAge = 0; } break; default: return false; } - blockState.setBlockData(crops); + + //Start the delayed replant + startReplantTask(finalAge, blockBreakEvent, blockState, false); return true; } - private int getGreenThumbStage() { + private int getGreenThumbStage(boolean greenTerraActive) { + if(greenTerraActive) + return Math.min(pluginRef.getRankTools().getHighestRank(SubSkillType.HERBALISM_GREEN_THUMB), + pluginRef.getRankTools().getRank(getPlayer(), SubSkillType.HERBALISM_GREEN_THUMB) + 1); + return pluginRef.getRankTools().getRank(getPlayer(), SubSkillType.HERBALISM_GREEN_THUMB); } } diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/skills/taming/TamingManager.java b/mcmmo-core/src/main/java/com/gmail/nossr50/skills/taming/TamingManager.java index e4f099f7c..8f0a1b0c3 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/skills/taming/TamingManager.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/skills/taming/TamingManager.java @@ -13,7 +13,6 @@ import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.skills.SkillManager; import com.gmail.nossr50.util.StringUtils; import com.gmail.nossr50.util.random.RandomChanceSkillStatic; -import com.gmail.nossr50.util.skills.ParticleEffectUtils; import com.gmail.nossr50.util.skills.SkillActivationType; import com.gmail.nossr50.util.sounds.SoundType; import org.bukkit.Location; @@ -208,7 +207,7 @@ public class TamingManager extends SkillManager { if(!pluginRef.getRandomChanceTools().checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(pluginRef, pluginRef.getDynamicSettingsManager().getSkillPropertiesManager().getStaticChance(SubSkillType.TAMING_PUMMEL), getPlayer(), SubSkillType.TAMING_PUMMEL))) return; - ParticleEffectUtils.playGreaterImpactEffect(target); + pluginRef.getParticleEffectUtils().playGreaterImpactEffect(target); target.setVelocity(wolf.getLocation().getDirection().normalize().multiply(1.5D)); if (target instanceof Player) { @@ -381,7 +380,7 @@ public class TamingManager extends SkillManager { callOfWildEntity.setCustomName(pluginRef.getLocaleManager().getString("Taming.Summon.Name.Format", getPlayer().getName(), StringUtils.getPrettyEntityTypeString(entityType))); //Particle effect - ParticleEffectUtils.playCallOfTheWildEffect(callOfWildEntity); + pluginRef.getParticleEffectUtils().playCallOfTheWildEffect(callOfWildEntity); } private void spawnHorse(Location spawnLocation) { @@ -408,7 +407,7 @@ public class TamingManager extends SkillManager { callOfWildEntity.setCustomName(pluginRef.getLocaleManager().getString("Taming.Summon.Name.Format", getPlayer().getName(), StringUtils.getPrettyEntityTypeString(EntityType.HORSE))); //Particle effect - ParticleEffectUtils.playCallOfTheWildEffect(callOfWildEntity); + pluginRef.getParticleEffectUtils().playCallOfTheWildEffect(callOfWildEntity); } private void setBaseCOTWEntityProperties(LivingEntity callOfWildEntity) { diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/skills/taming/TrackedTamingEntity.java b/mcmmo-core/src/main/java/com/gmail/nossr50/skills/taming/TrackedTamingEntity.java index 1dfb82fdf..d440d1917 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/skills/taming/TrackedTamingEntity.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/skills/taming/TrackedTamingEntity.java @@ -2,7 +2,6 @@ package com.gmail.nossr50.skills.taming; import com.gmail.nossr50.datatypes.skills.subskills.taming.CallOfTheWildType; import com.gmail.nossr50.mcMMO; -import com.gmail.nossr50.util.skills.ParticleEffectUtils; import org.bukkit.Location; import org.bukkit.Sound; import org.bukkit.entity.LivingEntity; @@ -39,7 +38,7 @@ public class TrackedTamingEntity extends BukkitRunnable { if (livingEntity.isValid()) { Location location = livingEntity.getLocation(); location.getWorld().playSound(location, Sound.BLOCK_FIRE_EXTINGUISH, 0.8F, 0.8F); - ParticleEffectUtils.playCallOfTheWildEffect(livingEntity); + pluginRef.getParticleEffectUtils().playCallOfTheWildEffect(livingEntity); pluginRef.getCombatTools().dealDamage(livingEntity, livingEntity.getMaxHealth(), EntityDamageEvent.DamageCause.SUICIDE, livingEntity); if(tamingManagerRef != null) diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/text/TextManager.java b/mcmmo-core/src/main/java/com/gmail/nossr50/text/TextManager.java new file mode 100644 index 000000000..c4d74afd9 --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/text/TextManager.java @@ -0,0 +1,105 @@ +package com.gmail.nossr50.text; + +import com.gmail.nossr50.mcMMO; +import net.kyori.text.TextComponent; +import net.kyori.text.adapter.bukkit.TextAdapter; +import net.kyori.text.serializer.gson.GsonComponentSerializer; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * Handles some boiler plate related to kyori powered text library + */ +public class TextManager { + public static final char COLOR_CHAR = 'ยง'; + private mcMMO pluginRef; + + public TextManager(mcMMO pluginRef) { + this.pluginRef = pluginRef; + } + + /** + * Send a message to multiple recipients + * @param commandSenders target recipients + * @param textComponent the {@link TextComponent} to send + */ + public void sendMessage(List commandSenders, TextComponent textComponent) { + for(CommandSender commandSender : commandSenders) { + sendMessage(commandSender, textComponent); + } + } + + /** + * Serializes and sends a text message to a specific recipient + * @param commandSender target recipient + * @param textComponent the {@link TextComponent} to serialize and send + */ + public void sendMessage(CommandSender commandSender, TextComponent textComponent) { + String json = GsonComponentSerializer.INSTANCE.serialize(textComponent); + TextAdapter.sendMessage(commandSender, textComponent); + } + + /** + * Sends a message to a single recipient with the (mcMMO) watermark at the beginning of the message + * @param commandSender target recipient + * @param textComponent the {@link TextComponent} to watermark and send + */ + public void sendMessageWatermarked(CommandSender commandSender, TextComponent textComponent) { + TextComponent waterMarkedComponent = buildWaterMarked(textComponent); + + sendMessage(commandSender, waterMarkedComponent); + } + + /** + * Sends a message to a list of recipients with the (mcMMO) watermark at the beginning of the message + * @param commandSenders target recipients + * @param textComponent the {@link TextComponent} to watermark and send + */ + public void sendMessageWatermarked(List commandSenders, TextComponent textComponent) { + TextComponent waterMarkedComponent = buildWaterMarked(textComponent); + + for(CommandSender commandSender : commandSenders) { + sendMessage(commandSender, waterMarkedComponent); + } + } + + /** + * Builds a watermarked version of a text component + * @param textComponent target component to watermark + * @return a new {@link TextComponent} with the (mcMMO) watermark at the beginning and the contents of {@link TextComponent} appended afterwards + */ + @NotNull + private TextComponent buildWaterMarked(TextComponent textComponent) { + return TextComponent.builder().content(pluginRef.getLocaleManager().getString("mcMMO.Template.Prefix")).append(textComponent).build(); + } + + /** + * Dissects a string and builds a {@link TextComponent} out of it. + * Results are cached to avoid needless operations in the future + * @param legacyText target text to transform + */ + private TextComponent transformLegacyTexts(String legacyText) { + //TODO: Cache results + TextComponent.Builder builder = TextComponent.builder(); + + for(int i = 0; i < legacyText.toCharArray().length; i++) { + char c = legacyText.charAt(i); + + //Found color character + if(c == COLOR_CHAR) { + if(i+1 >= legacyText.toCharArray().length) { + //No color code because we're at the end of the string + builder.append(String.valueOf(c)); + } else { + //TODO: finish + } + } else { + //Not a color character + } + } + return builder.build(); + } + +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/util/commands/CommandRegistrationManager.java b/mcmmo-core/src/main/java/com/gmail/nossr50/util/commands/CommandRegistrationManager.java index 8fc2f31a7..dc42788b0 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/util/commands/CommandRegistrationManager.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/util/commands/CommandRegistrationManager.java @@ -1,6 +1,8 @@ package com.gmail.nossr50.util.commands; +import co.aikar.commands.PaperCommandManager; import com.gmail.nossr50.commands.*; +import com.gmail.nossr50.commands.admin.NBTToolsCommand; import com.gmail.nossr50.commands.admin.PlayerDebugCommand; import com.gmail.nossr50.commands.admin.ReloadLocaleCommand; import com.gmail.nossr50.commands.chat.AdminChatCommand; @@ -27,13 +29,70 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; +//TODO: Properly rewrite ACF integration later public final class CommandRegistrationManager { private final mcMMO pluginRef; private String permissionsMessage; + //NOTE: Does not actually require paper, will work for bukkit + private PaperCommandManager commandManager; public CommandRegistrationManager(mcMMO pluginRef) { this.pluginRef = pluginRef; permissionsMessage = pluginRef.getLocaleManager().getString("mcMMO.NoPermission"); + commandManager = new PaperCommandManager(pluginRef); + } + + /** + * Register ACF Commands + */ + //TODO: Properly rewrite ACF integration later + public void registerACFCommands() { + //Register ACF Commands + registerNBTToolsCommand(); + registerMmoDebugCommand(); + } + + /** + * Register exception handlers for the ACF commands + */ + //TODO: Properly rewrite ACF integration later + private void registerExceptionHandlers() { + registerDefaultExceptionHandler(); + } + + /** + * Register default exception handler + */ + //TODO: Properly rewrite ACF integration later + private void registerDefaultExceptionHandler() { + commandManager.setDefaultExceptionHandler((command, registeredCommand, sender, args, t) -> { + pluginRef.getLogger().warning("Error occurred while executing command " + command.getName()); + return false; + }); + } + + /** + * Register contexts for ACF + */ + //TODO: Properly rewrite ACF integration later + private void registerContexts() { + + } + + /** + * Register the NBT Tools command + */ + //TODO: Properly rewrite ACF integration later + private void registerNBTToolsCommand() { + commandManager.registerCommand(new NBTToolsCommand()); + } + + /** + * Register the MMO Debug command + */ + //TODO: Properly rewrite ACF integration later + private void registerMmoDebugCommand() { + commandManager.registerCommand(new PlayerDebugCommand()); } private void registerSkillCommands() { @@ -153,16 +212,6 @@ public final class CommandRegistrationManager { command.setExecutor(new MmoInfoCommand(pluginRef)); } - - private void registerMmoDebugCommand() { - PluginCommand command = pluginRef.getCommand("mmodebug"); - command.setDescription(pluginRef.getLocaleManager().getString("Commands.Description.mmodebug")); - command.setPermission(null); //No perm required to save support headaches - command.setPermissionMessage(permissionsMessage); - command.setUsage(pluginRef.getLocaleManager().getString("Commands.Usage.0", "mmodebug")); - command.setExecutor(new PlayerDebugCommand(pluginRef)); - } - private void registerMcChatSpyCommand() { PluginCommand command = pluginRef.getCommand("mcchatspy"); command.setDescription(pluginRef.getLocaleManager().getString("Commands.Description.mcchatspy")); @@ -427,7 +476,6 @@ public final class CommandRegistrationManager { public void registerCommands() { // Generic Commands registerMmoInfoCommand(); - registerMmoDebugCommand(); registerMcabilityCommand(); registerMcgodCommand(); registerMcChatSpyCommand(); diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/util/nbt/NBTFactory.java b/mcmmo-core/src/main/java/com/gmail/nossr50/util/nbt/NBTFactory.java new file mode 100644 index 000000000..208a7e658 --- /dev/null +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/util/nbt/NBTFactory.java @@ -0,0 +1,71 @@ +package com.gmail.nossr50.util.nbt; + +import com.gmail.nossr50.core.nbt.NBTByte; +import net.minecraft.server.v1_14_R1.NBTTagByte; + +public class NBTFactory { + //TODO: Finish + /** + * Converts NMS NBT types into our own NBT type representation + * @param nmsNBT target NMS Compound + * @return NMS Representation of our NBT + */ +// public NBTCompound asNBT(net.minecraft.server.v1_14_R1.NBTTagCompound nmsNBT) { +// NBTCompound nbtCompound = new NBTCompound(""); +// +// //Traverse the NMS Map +// for(String key : nmsNBT.getKeys()) { +// +// } +// } + + //TODO: Finish +// /** +// * Convert our NBT type into the NMS NBT Type equivalent +// * @param nbtCompound target nbt compound +// * @return NMS NBT copy of our NBT type +// */ +// public net.minecraft.server.v1_14_R1.NBTTagCompound asNMSCopy(NBTCompound nbtCompound) { +// +// } + + /** + * Create a new NMS NBT tag compound with only 1 tag compound named "tag" + * @return new NMS NBT tag compound + */ + private net.minecraft.server.v1_14_R1.NBTTagCompound makeNewNMSNBT() { + net.minecraft.server.v1_14_R1.NBTTagCompound nbtTagCompound = new net.minecraft.server.v1_14_R1.NBTTagCompound(); + + //Add the 'tag' compound where arbitrary data persists + nbtTagCompound.set("tag", new net.minecraft.server.v1_14_R1.NBTTagCompound()); + return nbtTagCompound; + } + + //TODO: Finish +// private NBTCompound deepCopy(NBTCompound target, String key, net.minecraft.server.v1_14_R1.NBTBase nbtBase) { +// switch (nbtBase.getTypeId()) { +// case 0: +// return new NBTCompound(); +// } +// } + + /** + * Create a NBTByte representation of NBTTagByte (NMS Type) + * @param nmsNBTByte target NMS NBTTagByte + * @return NBTByte representation of the targeted NMS nbt-type + */ + private NBTByte asNBTByte(NBTTagByte nmsNBTByte) { + NBTByte nbtByte = new NBTByte(nmsNBTByte.asByte()); + return nbtByte; + } + + /** + * Create a NBTTagByte (NMS Type) from our NBTByte representation + * @param nbtByte target NBTByte + * @return NBTTagByte copy of our NBTByte representation + */ + private NBTTagByte asNBTTagByte(NBTByte nbtByte) { + NBTTagByte nbtTagByte = new NBTTagByte(nbtByte.getValue()); + return nbtTagByte; + } +} diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/util/nbt/NBTManager.java b/mcmmo-core/src/main/java/com/gmail/nossr50/util/nbt/NBTManager.java index e620486b2..d9d749916 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/util/nbt/NBTManager.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/util/nbt/NBTManager.java @@ -1,17 +1,22 @@ package com.gmail.nossr50.util.nbt; -import net.minecraft.server.v1_14_R1.NBTBase; +import com.gmail.nossr50.core.nbt.NBTBase; import net.minecraft.server.v1_14_R1.NBTList; import net.minecraft.server.v1_14_R1.NBTTagCompound; -import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack; import org.bukkit.craftbukkit.v1_14_R1.util.CraftNBTTagConfigSerializer; +import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; public class NBTManager { - private static final String CRAFT_META_ITEM_CLASS_PATH = "org.bukkit.craftbukkit.inventory.CraftMetaItem"; + private final String CRAFT_META_ITEM_CLASS_PATH = "org.bukkit.craftbukkit.inventory.CraftMetaItem"; private Class craftMetaItemClass; public NBTManager() { @@ -19,21 +24,133 @@ public class NBTManager { } private void init() { +// try { +// Class craftMetaItemClass = Class.forName(CRAFT_META_ITEM_CLASS_PATH); //for type comparisons +// } catch (ClassNotFoundException e) { +// e.printStackTrace(); +// } + } + + /** + * Used for testing NBT stuff, will be deleted later + * @param player target player + */ + //TODO: DELETE + //TODO: DELETE + //TODO: DELETE + //TODO: DELETE + //TODO: DELETE + //TODO: DELETE + //TODO: DELETE + //TODO: DELETE + //TODO: DELETE + //TODO: DELETE + //TODO: DELETE + //TODO: DELETE + //TODO: DELETE + public void debugNBTInMainHandItem(Player player) { + player.sendMessage("Starting NBT Debug Dump..."); + + ItemStack itemStack = player.getInventory().getItemInMainHand(); + player.sendMessage("Checking NBT for "+itemStack.toString()); + + player.sendMessage("Total NBT Entries: "+getNBTCopy(player.getInventory().getItemInMainHand()).getKeys().size()); + printNBT(player.getInventory().getItemInMainHand(), player); + player.sendMessage("-- END OF NBT REPORT --"); + + player.sendMessage("Attempting to add NBT key named - Herp"); + addFloatNBT(player.getInventory().getItemInMainHand(), "herp", 13.37F); + player.updateInventory(); + + player.sendMessage("(After HERP) Total NBT Entries: "+getNBTCopy(player.getInventory().getItemInMainHand()).getKeys().size()); + printNBT(player.getInventory().getItemInMainHand(), player); + player.sendMessage("-- END OF NBT REPORT --"); + + player.sendMessage("Attempting to save NBT data..."); + player.updateInventory(); + } + + /** + * Gets the NMS.ItemStack Copy of a Bukkit.ItemStack + * @param itemStack target bukkit ItemStack + * @return the NMS.ItemStack "copy" of the Bukkit ItemStack + */ + public net.minecraft.server.v1_14_R1.ItemStack getNMSItemStack(ItemStack itemStack) { + return CraftItemStack.asNMSCopy(itemStack); + } + + /** + * Copies the NBT off an ItemStack and adds a tag compound if it doesn't exist + * @param itemStack target ItemStack + * @return the NBT copy of an ItemStack + */ + @NonNull + public NBTTagCompound getNBTCopy(ItemStack itemStack) { + net.minecraft.server.v1_14_R1.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack); + NBTTagCompound freshNBTCopy = nmsItemStack.save(new NBTTagCompound()); + + if(!freshNBTCopy.hasKeyOfType("tag", 10)) { + freshNBTCopy.set("tag", new NBTTagCompound()); + } + + return freshNBTCopy; + } + + /** + * Adds a Float Value to an ItemStack's NBT + * @param itemStack target ItemStack + * @param key the key for the new NBT float kv pair + * @param value the value of the new NBT float kv pair + */ + public void addFloatNBT(ItemStack itemStack, String key, float value) { + //NBT Copied off Item + net.minecraft.server.v1_14_R1.ItemStack nmsIS = getNMSItemStack(itemStack); + NBTTagCompound freshNBTCopy = getNBTCopy(itemStack); + + //New Float NBT Value + NBTTagCompound updatedNBT = new NBTTagCompound(); + updatedNBT.setFloat(key, value); + + //Merge + mergeToTagCompound(freshNBTCopy, updatedNBT); + + //Invoke load() time + applyNBT(nmsIS, freshNBTCopy); + + //Apply Item Meta (Not sure if needed) + CraftItemStack craftItemStack = CraftItemStack.asCraftMirror(nmsIS); + itemStack.setItemMeta(craftItemStack.getItemMeta()); + } + + /** + * Merges the modification compound into the target compound's tag NBT node + * @param targetCompound target NBT to merge into + * @param modificationCompound data to merge + */ + public void mergeToTagCompound(NBTTagCompound targetCompound, NBTTagCompound modificationCompound) { + NBTTagCompound tagCompound = (NBTTagCompound) targetCompound.get("tag"); + tagCompound.a(modificationCompound); + } + + /** + * Applies NBT to an NMS.ItemStack + * @param nmsItemStack target NMS.ItemStack + * @param nbtTagCompound the new NBT data for the NMS.ItemStack + */ + public void applyNBT(net.minecraft.server.v1_14_R1.ItemStack nmsItemStack, NBTTagCompound nbtTagCompound) { + try { - Class craftMetaItemClass = Class.forName(CRAFT_META_ITEM_CLASS_PATH); //for type comparisons - } catch (ClassNotFoundException e) { + Class clazz = Class.forName("net.minecraft.server.v1_14_R1.ItemStack"); + Class[] methodParameters = new Class[]{ NBTTagCompound.class }; + Method loadMethod = clazz.getDeclaredMethod("load", methodParameters); + loadMethod.setAccessible(true); + loadMethod.invoke(nmsItemStack, nbtTagCompound); + } catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { e.printStackTrace(); } } - public static NBTTagCompound getNBT(ItemStack itemStack) { - Bukkit.broadcastMessage("Checking NBT for "+itemStack.toString()); - net.minecraft.server.v1_14_R1.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack); - NBTTagCompound rootTag = nmsItemStack.getTag(); - return rootTag; - } - - public static NBTBase constructNBT(String nbtString) { + public net.minecraft.server.v1_14_R1.NBTBase constructNBT(String nbtString) { try { return CraftNBTTagConfigSerializer.deserialize(nbtString); } catch (Exception e) { @@ -43,13 +160,46 @@ public class NBTManager { } } - public static void printNBT(ItemStack itemStack) { - for(String key : getNBT(itemStack).getKeys()) { - Bukkit.broadcastMessage("NBT Key found: "+key); - } + /** + * Prints all the NBT KV pairs on an ItemStack + * @param itemStack target ItemStack + * @param player target player to send the message to + */ + public void printNBT(ItemStack itemStack, Player player) { + NBTTagCompound tagCompoundCopy = getNBTCopy(itemStack); + printNBT(tagCompoundCopy, player); } - public static boolean hasNBT(NBTBase nbt, NBTTagCompound otherNbt) { + private void printNBT(NBTTagCompound nbtTagCompound, Player player) { + for(String key : nbtTagCompound.getKeys()) { + player.sendMessage(""); + + net.minecraft.server.v1_14_R1.NBTBase targetTag = nbtTagCompound.get(key); + + //Recursively print contents + if(targetTag instanceof NBTTagCompound) { + NBTTagCompound childTagCompound = nbtTagCompound.getCompound(key); + if(childTagCompound != null) { + player.sendMessage(ChatColor.BLUE + "NBT named " + ChatColor.GOLD + key + ChatColor.BLUE + " is a tag compound, printing contents..."); + printNBT(childTagCompound, player); + player.sendMessage(ChatColor.BLUE + "Exiting "+ key); + continue; + } + } + + player.sendMessage(ChatColor.GOLD + "Tag Key: " + ChatColor.RESET + key); + + if(targetTag == null) { + player.sendMessage(ChatColor.RED + "Tag is null!"); + continue; + } + + player.sendMessage(ChatColor.GREEN + "Tag Value: " + ChatColor.RESET + targetTag.asString()); + } + + } + + public boolean hasNBT(NBTBase nbt, NBTTagCompound otherNbt) { if(nbt instanceof NBTList) { } else { diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/util/player/UserManager.java b/mcmmo-core/src/main/java/com/gmail/nossr50/util/player/UserManager.java index 822b0f0ea..33bd49648 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/util/player/UserManager.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/util/player/UserManager.java @@ -8,6 +8,7 @@ import org.bukkit.OfflinePlayer; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.metadata.FixedMetadataValue; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collection; @@ -51,9 +52,11 @@ public final class UserManager { public void remove(Player player) { BukkitMMOPlayer mcMMOPlayer = getPlayer(player); player.removeMetadata(MetadataConstants.PLAYER_DATA_METAKEY, pluginRef); - mcMMOPlayer.cleanup(); - if(playerDataSet != null && playerDataSet.contains(mcMMOPlayer)) { + if(mcMMOPlayer != null) + mcMMOPlayer.cleanup(); + + if(playerDataSet != null) { playerDataSet.remove(mcMMOPlayer); //Clear sync save tracking } } @@ -114,10 +117,12 @@ public final class UserManager { * @param playerName The name of the player whose McMMOPlayer to retrieve * @return the player's McMMOPlayer object */ + @Nullable public BukkitMMOPlayer getPlayer(String playerName) { return retrieveMcMMOPlayer(playerName, false); } + @Nullable public BukkitMMOPlayer getOfflinePlayer(OfflinePlayer player) { if (player instanceof Player) { return getPlayer((Player) player); @@ -136,6 +141,7 @@ public final class UserManager { * @param player target player * @return McMMOPlayer object for this player, null if Player has not been loaded */ + @Nullable public BukkitMMOPlayer getPlayer(Player player) { //Avoid Array Index out of bounds if (player != null && player.hasMetadata(MetadataConstants.PLAYER_DATA_METAKEY)) @@ -144,6 +150,7 @@ public final class UserManager { return null; } + @Nullable private BukkitMMOPlayer retrieveMcMMOPlayer(String playerName, boolean offlineValid) { Player player = pluginRef.getServer().getPlayerExact(playerName); diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/util/skills/CombatTools.java b/mcmmo-core/src/main/java/com/gmail/nossr50/util/skills/CombatTools.java index 70f475328..448e63354 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/util/skills/CombatTools.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/util/skills/CombatTools.java @@ -222,7 +222,7 @@ public final class CombatTools { } - private void processArcheryCombat(LivingEntity target, Player player, EntityDamageByEntityEvent event, Arrow arrow) { + private void processArcheryCombat(LivingEntity target, Player player, EntityDamageByEntityEvent event, Projectile arrow) { double initialDamage = event.getDamage(); BukkitMMOPlayer mcMMOPlayer = pluginRef.getUserManager().getPlayer(player); @@ -376,8 +376,9 @@ public final class CombatTools { processTamingCombat(target, master, wolf, event); } } - } else if (entityType == EntityType.ARROW) { - Arrow arrow = (Arrow) damager; + } + else if (entityType == EntityType.ARROW || entityType == EntityType.SPECTRAL_ARROW) { + Projectile arrow = (Projectile) damager; ProjectileSource projectileSource = arrow.getShooter(); if (projectileSource instanceof Player && pluginRef.getSkillTools().canCombatSkillsTrigger(PrimarySkillType.ARCHERY, target)) { @@ -407,11 +408,9 @@ public final class CombatTools { if (metadataValue.size() <= 0) return; - if (metadataValue != null) { - OldName oldName = (OldName) metadataValue.get(0); - entity.setCustomName(oldName.asString()); - entity.setCustomNameVisible(false); - } + OldName oldName = (OldName) metadataValue.get(0); + entity.setCustomName(oldName.asString()); + entity.setCustomNameVisible(false); } diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/util/skills/ParticleEffectUtils.java b/mcmmo-core/src/main/java/com/gmail/nossr50/util/skills/ParticleEffectUtils.java index 3199f45b2..caea0504d 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/util/skills/ParticleEffectUtils.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/util/skills/ParticleEffectUtils.java @@ -1,5 +1,7 @@ package com.gmail.nossr50.util.skills; +import com.gmail.nossr50.mcMMO; +import com.gmail.nossr50.util.sounds.SoundType; import org.bukkit.Effect; import org.bukkit.Location; import org.bukkit.Material; @@ -11,10 +13,19 @@ import org.bukkit.entity.Player; public final class ParticleEffectUtils { - private ParticleEffectUtils() { + private final mcMMO pluginRef; + + public ParticleEffectUtils(mcMMO pluginRef) { + this.pluginRef = pluginRef; } - public static void playBleedEffect(LivingEntity livingEntity) { + public void playGreenThumbEffect(Location location) { + World world = location.getWorld(); + playSmokeEffect(location); + pluginRef.getSoundManager().worldSendSoundMaxPitch(world, location, SoundType.POP); + } + + public void playBleedEffect(LivingEntity livingEntity) { /*if (!MainConfig.getInstance().getBleedEffectEnabled()) { return; }*/ @@ -22,15 +33,15 @@ public final class ParticleEffectUtils { livingEntity.getWorld().playEffect(livingEntity.getEyeLocation(), Effect.STEP_SOUND, Material.REDSTONE_WIRE); } - public static void playDodgeEffect(Player player) { + public void playDodgeEffect(Player player) { /*if (!MainConfig.getInstance().getDodgeEffectEnabled()) { return; }*/ - playSmokeEffect(player); + playSmokeEffect(player.getLocation()); } - public static void playFluxEffect(Location location) { + public void playFluxEffect(Location location) { /*if (!MainConfig.getInstance().getFluxEffectEnabled()) { return; }*/ @@ -38,9 +49,8 @@ public final class ParticleEffectUtils { location.getWorld().playEffect(location, Effect.MOBSPAWNER_FLAMES, 1); } - public static void playSmokeEffect(LivingEntity livingEntity) { - Location location = livingEntity.getEyeLocation(); - World world = livingEntity.getWorld(); + public void playSmokeEffect(Location location) { + World world = location.getWorld(); // Have to do it this way, because not all block directions are valid for smoke world.playEffect(location, Effect.SMOKE, BlockFace.SOUTH_EAST); @@ -54,7 +64,7 @@ public final class ParticleEffectUtils { world.playEffect(location, Effect.SMOKE, BlockFace.NORTH_WEST); } - public static void playGreaterImpactEffect(LivingEntity livingEntity) { + public void playGreaterImpactEffect(LivingEntity livingEntity) { /*if (!MainConfig.getInstance().getGreaterImpactEffectEnabled()) { return; }*/ @@ -64,7 +74,7 @@ public final class ParticleEffectUtils { livingEntity.getWorld().createExplosion(location.getX(), location.getY(), location.getZ(), 0F, false, false); } - public static void playCallOfTheWildEffect(LivingEntity livingEntity) { + public void playCallOfTheWildEffect(LivingEntity livingEntity) { /*if (!MainConfig.getInstance().getCallOfTheWildEffectEnabled()) { return; }*/ @@ -87,7 +97,7 @@ public final class ParticleEffectUtils { firework.setFireworkMeta(fireworkMeta); }*/ - private static boolean hasHeadRoom(Player player) { + private boolean hasHeadRoom(Player player) { boolean hasHeadRoom = true; Block headBlock = player.getEyeLocation().getBlock(); diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/util/sounds/SoundManager.java b/mcmmo-core/src/main/java/com/gmail/nossr50/util/sounds/SoundManager.java index 580b8f7af..0ab956ed3 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/util/sounds/SoundManager.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/util/sounds/SoundManager.java @@ -43,6 +43,11 @@ public class SoundManager { world.playSound(location, getSound(soundType), getVolume(soundType), getPitch(soundType)); } + public void worldSendSoundMaxPitch(World world, Location location, SoundType soundType) { + if(pluginRef.getConfigManager().getConfigSound().isSoundEnabled(soundType)) + world.playSound(location, getSound(soundType), getVolume(soundType), 2.0F); + } + /** * All volume is multiplied by the master volume to get its final value * @@ -95,6 +100,8 @@ public class SoundManager { return Sound.ENTITY_ENDER_EYE_DEATH; case GLASS: return Sound.BLOCK_GLASS_BREAK; + case ITEM_CONSUMED: + return Sound.ITEM_BOTTLE_EMPTY; default: return null; } diff --git a/mcmmo-core/src/main/java/com/gmail/nossr50/util/sounds/SoundType.java b/mcmmo-core/src/main/java/com/gmail/nossr50/util/sounds/SoundType.java index f1eacd550..517d45cd1 100644 --- a/mcmmo-core/src/main/java/com/gmail/nossr50/util/sounds/SoundType.java +++ b/mcmmo-core/src/main/java/com/gmail/nossr50/util/sounds/SoundType.java @@ -15,6 +15,7 @@ public enum SoundType { ABILITY_ACTIVATED_BERSERK, BLEED, GLASS, + ITEM_CONSUMED, TIRED; public boolean usesCustomPitch() { diff --git a/mcmmo-core/src/main/resources/com/gmail/nossr50/locale/locale_en_US.properties b/mcmmo-core/src/main/resources/com/gmail/nossr50/locale/locale_en_US.properties index 1b65e1511..ae0bf6205 100644 --- a/mcmmo-core/src/main/resources/com/gmail/nossr50/locale/locale_en_US.properties +++ b/mcmmo-core/src/main/resources/com/gmail/nossr50/locale/locale_en_US.properties @@ -268,7 +268,7 @@ Herbalism.Ability.Lower=[[GRAY]]You lower your Hoe. Herbalism.Ability.Ready=[[DARK_AQUA]]You [[GOLD]]ready[[DARK_AQUA]] your Hoe. Herbalism.Ability.ShroomThumb.Fail=**SHROOM THUMB FAIL** Herbalism.SubSkill.GreenTerra.Name=Green Terra -Herbalism.SubSkill.GreenTerra.Description=Spread the Terra, 3x Drops +Herbalism.SubSkill.GreenTerra.Description=Spread the Terra, 3x Drops, Boosts Green Thumb Herbalism.SubSkill.GreenTerra.Stat=Green Terra Duration Herbalism.SubSkill.GreenThumb.Name=Green Thumb Herbalism.SubSkill.GreenThumb.Description=Auto-Plants crops when harvesting diff --git a/mcmmo-core/src/main/resources/sounds.yml b/mcmmo-core/src/main/resources/sounds.yml index 837559568..f705b7d24 100644 --- a/mcmmo-core/src/main/resources/sounds.yml +++ b/mcmmo-core/src/main/resources/sounds.yml @@ -4,6 +4,10 @@ Sounds: # 1.0 = Max volume # 0.0 = No Volume MasterVolume: 1.0 + ITEM_CONSUMED: + Enable: true + Volume: 1.0 + Pitch: 1.0 GLASS: Enable: true Volume: 1.0