mirror of
https://github.com/JEFF-Media-GbR/BetterTridents.git
synced 2025-01-14 19:31:47 +01:00
2.0.0 release
This commit is contained in:
parent
2fa8a67436
commit
bb813d746b
10
CHANGELOG.md
10
CHANGELOG.md
@ -1,2 +1,12 @@
|
||||
## 2.0.0
|
||||
- Renamed plugin to "BetterTridents"
|
||||
- Added new mechanics and config options:
|
||||
- Bedrock impaling: Impaling enchantment behaves like in Bedrock (it damages ALL mobs touching water, not only ocean mobs). Default: Enabled
|
||||
- Bedrock drop chance: Raises the drop chance for tridents to the bedrock value (25% for every drowned yielding a trident + 4% per looting level) Default: Enabled
|
||||
- Return to offhand: Tridents thrown from the offhand will also return to the offhand when picking them up. Default: Enabled
|
||||
- Disable loyalty portals: Prohibit tridents with Loyalty to travel through portals to avoid losing them. Default: Enabled
|
||||
- Added automatic config updater
|
||||
- Added reload command (/bettertridents, permission bettertridents.reload)
|
||||
|
||||
## 1.1.0
|
||||
- Added UpdateChecker and bStats
|
10
pom.xml
10
pom.xml
@ -4,13 +4,13 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>de.jeff_media</groupId>
|
||||
<name>NoTridentVoid</name>
|
||||
<artifactId>NoTridentVoid</artifactId>
|
||||
<version>1.1.0</version>
|
||||
<name>BetterTridents</name>
|
||||
<artifactId>BetterTridents</artifactId>
|
||||
<version>2.0.0</version>
|
||||
|
||||
<properties>
|
||||
<spigot.prefix>${project.name}</spigot.prefix>
|
||||
<spigot.main>${project.groupId}.notridentvoid.Main</spigot.main>
|
||||
<spigot.main>${project.groupId}.bettertridents.Main</spigot.main>
|
||||
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
@ -45,7 +45,7 @@
|
||||
<!-- Replace "your.package" with your plugin's package name -->
|
||||
<relocation>
|
||||
<pattern>de.jeff_media.updatechecker</pattern>
|
||||
<shadedPattern>de.jeff_media.notridentvoid.updatechecker</shadedPattern>
|
||||
<shadedPattern>de.jeff_media.bettertridents.updatechecker</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.bstats</pattern>
|
||||
|
@ -1,7 +1,9 @@
|
||||
package de.jeff_media.notridentvoid;
|
||||
package de.jeff_media.bettertridents;
|
||||
|
||||
import de.jeff_media.notridentvoid.config.Config;
|
||||
import de.jeff_media.notridentvoid.listeners.ProjectileListener;
|
||||
import de.jeff_media.bettertridents.commands.ReloadCommand;
|
||||
import de.jeff_media.bettertridents.config.Config;
|
||||
import de.jeff_media.bettertridents.config.ConfigUpdater;
|
||||
import de.jeff_media.bettertridents.listeners.*;
|
||||
import de.jeff_media.updatechecker.UpdateChecker;
|
||||
import de.jeff_media.updatechecker.UserAgentBuilder;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
@ -11,6 +13,7 @@ import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Trident;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
|
||||
@ -20,22 +23,41 @@ public class Main extends JavaPlugin {
|
||||
private final ArrayList<UUID> tridents = new ArrayList<>();
|
||||
public static final Material SAFETY_MATERIAL = Material.BARRIER;
|
||||
public static NamespacedKey LOYALTY_TAG;
|
||||
public static NamespacedKey IMPALING_TAG;
|
||||
public static NamespacedKey OFFHAND_TAG;
|
||||
|
||||
public static Main getInstance() {
|
||||
return instance;
|
||||
}
|
||||
private boolean debug = false;
|
||||
|
||||
public void debug(String text) {
|
||||
if(debug) getLogger().warning("[DEBUG] " + text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
instance = this;
|
||||
LOYALTY_TAG = new NamespacedKey(this, "loyalty");
|
||||
IMPALING_TAG = new NamespacedKey(this, "impaling");
|
||||
OFFHAND_TAG = new NamespacedKey(this, "offhand");
|
||||
reload();
|
||||
Bukkit.getPluginManager().registerEvents(new ProjectileListener(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new VoidListener(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new DropListener(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new ImpalingListener(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new OffhandListener(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new TridentThrowListener(), this);
|
||||
getCommand("bettertridents").setExecutor(new ReloadCommand());
|
||||
@SuppressWarnings("unused") Metrics metrics = new Metrics(this, 11460);
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
if(!new File(getDataFolder(), "config.yml").exists()) {
|
||||
saveDefaultConfig();
|
||||
}
|
||||
reloadConfig();
|
||||
new Config();
|
||||
ConfigUpdater.updateConfig();
|
||||
UpdateChecker.init(this, "https://api.jeff-media.de/notridentvoid/latest-version.txt")
|
||||
.setDonationLink("https://paypal.me/mfnalex")
|
||||
.setDownloadLink(92656)
|
||||
@ -47,17 +69,21 @@ public class Main extends JavaPlugin {
|
||||
} else if(getConfig().getString(Config.CHECK_FOR_UPDATES).equalsIgnoreCase("on-startup")) {
|
||||
UpdateChecker.getInstance().checkNow();
|
||||
}
|
||||
debug = getConfig().getBoolean(Config.DEBUG);
|
||||
if(debug) {
|
||||
getLogger().warning("Debug mode enabled - this may affect performance.");
|
||||
}
|
||||
}
|
||||
|
||||
public void register(Trident trident) {
|
||||
public void setLoyal(Trident trident) {
|
||||
tridents.add(trident.getUniqueId());
|
||||
}
|
||||
|
||||
public boolean isRegistered(Trident trident) {
|
||||
public boolean isLoyal(Trident trident) {
|
||||
return tridents.contains(trident.getUniqueId());
|
||||
}
|
||||
|
||||
public void unregister(Trident trident) {
|
||||
public void removeLoyal(Trident trident) {
|
||||
tridents.remove(trident.getUniqueId());
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package de.jeff_media.bettertridents.commands;
|
||||
|
||||
import de.jeff_media.bettertridents.Main;
|
||||
import de.jeff_media.bettertridents.config.Permissions;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ReloadCommand implements CommandExecutor {
|
||||
|
||||
private final Main main = Main.getInstance();
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
|
||||
|
||||
if(!sender.hasPermission(Permissions.RELOAD)) {
|
||||
sender.sendMessage(command.getPermissionMessage());
|
||||
return true;
|
||||
}
|
||||
|
||||
main.reload();
|
||||
sender.sendMessage(ChatColor.DARK_GREEN + main.getDescription().getName() + " v" + main.getDescription().getVersion() + ChatColor.GREEN + " has been reloaded.");
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package de.jeff_media.bettertridents.config;
|
||||
|
||||
import de.jeff_media.bettertridents.Main;
|
||||
|
||||
public class Config {
|
||||
|
||||
private final Main main = Main.getInstance();
|
||||
|
||||
public static final String BEDROCK_IMPALING = "bedrock-impaling";
|
||||
public static final String CONFIG_PLUGIN_VERSION = "plugin-version";
|
||||
public static final String VOID_SAVING = "void-saving";
|
||||
public static final String CONFIG_VERSION = "config-version";
|
||||
public static final String CHECK_FOR_UPDATES = "check-for-updates";
|
||||
public static final String UPDATE_CHECK_INTERVAL = "update-check-interval";
|
||||
public static final String DROP_BEDROCK_CHANCE = "bedrock-drop-chance";
|
||||
public static final String RETURN_TO_OFFHAND = "return-to-offhand";
|
||||
public static final String DISABLE_LOYALTY_PORTALS = "disable-loyalty-portals";
|
||||
public static final String DEBUG = "debug";
|
||||
|
||||
public Config() {
|
||||
addDefault(VOID_SAVING, true);
|
||||
addDefault(DROP_BEDROCK_CHANCE, true);
|
||||
addDefault(CHECK_FOR_UPDATES, "true");
|
||||
addDefault(UPDATE_CHECK_INTERVAL, 4);
|
||||
addDefault(BEDROCK_IMPALING, true);
|
||||
addDefault(RETURN_TO_OFFHAND, true);
|
||||
addDefault(DISABLE_LOYALTY_PORTALS, true);
|
||||
addDefault(DEBUG, false);
|
||||
}
|
||||
|
||||
private void addDefault(String node, Object value) {
|
||||
main.getConfig().addDefault(node, value);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,208 @@
|
||||
package de.jeff_media.bettertridents.config;
|
||||
|
||||
import de.jeff_media.bettertridents.Main;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Updates the config file. When a new config file is shipped with AngelChest, it will save the new
|
||||
* file and replace all default values with the values that were set in the old config file.
|
||||
*/
|
||||
public final class ConfigUpdater {
|
||||
|
||||
// Lines STARTING WITH these names will be treated as String lists
|
||||
private static final String[] LINES_CONTAINING_STRING_LISTS = {};
|
||||
// Lines STARTING WITH these names will never get the old value applied
|
||||
private static final String[] LINES_IGNORED = {"config-version:", "plugin-version:"};
|
||||
// Lines STARTING WITH these names will get no quotes although they would match one of the lists below
|
||||
private static final String[] CONFLICTING_NODES_NEEDING_NO_QUOTES = {};
|
||||
// Lines STARTING WITH these names will get their values wrapped in double quotes
|
||||
private static final String[] NODES_NEEDING_DOUBLE_QUOTES = {};
|
||||
// Lines STARTING WITH these names will get their values wrapped in single quotes
|
||||
private static final String[] NODES_NEEDING_SINGLE_QUOTES = {};
|
||||
|
||||
private static void backupCurrentConfig(final Main main) {
|
||||
final File oldFile = new File(getFilePath(main, "config.yml"));
|
||||
final File newFile = new File(getFilePath(main, "config-backup-" + main.getConfig().getString(Config.CONFIG_PLUGIN_VERSION) + ".yml"));
|
||||
if (newFile.exists()) newFile.delete();
|
||||
if (oldFile.getAbsoluteFile().renameTo(newFile.getAbsoluteFile())) {
|
||||
main.debug("Could not rename " + oldFile.getAbsolutePath() + " to " + newFile.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For debugging the config updater only
|
||||
*/
|
||||
private static void debug(final Logger logger, final String message) {
|
||||
if (false) {
|
||||
logger.warning(message);
|
||||
}
|
||||
}
|
||||
|
||||
private static String getFilePath(final Main main, final String fileName) {
|
||||
return main.getDataFolder() + File.separator + fileName;
|
||||
}
|
||||
|
||||
private static List<String> getNewConfigAsArrayList(final Main main) {
|
||||
final List<String> lines;
|
||||
try {
|
||||
lines = Files.readAllLines(Paths.get(getFilePath(main, "config.yml")), StandardCharsets.UTF_8);
|
||||
return lines;
|
||||
} catch (final IOException ioException) {
|
||||
ioException.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the config version of the currently installed AngelChest default config
|
||||
*
|
||||
* @return default config version
|
||||
*/
|
||||
private static long getNewConfigVersion() {
|
||||
final InputStream in = Main.getInstance().getClass().getResourceAsStream("/config-version.txt");
|
||||
final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
|
||||
try {
|
||||
return Long.parseLong(reader.readLine());
|
||||
} catch (final IOException ioException) {
|
||||
ioException.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a String representing the correct quotes to use for this key's value
|
||||
*
|
||||
* @param line line/key to get the quotes for
|
||||
* @return double quote, single quote or empty string, according to the key name
|
||||
*/
|
||||
private static String getQuotes(final String line) {
|
||||
for(final String test : CONFLICTING_NODES_NEEDING_NO_QUOTES) {
|
||||
if(line.startsWith(test)) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
for (final String test : NODES_NEEDING_DOUBLE_QUOTES) {
|
||||
if (line.startsWith(test)) {
|
||||
return "\"";
|
||||
}
|
||||
}
|
||||
for (final String test : NODES_NEEDING_SINGLE_QUOTES) {
|
||||
if (line.startsWith(test)) {
|
||||
return "'";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static boolean lineContainsIgnoredNode(final String line) {
|
||||
for (final String test : LINES_IGNORED) {
|
||||
if (line.startsWith(test)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean lineIsStringList(final String line) {
|
||||
for (final String test : LINES_CONTAINING_STRING_LISTS) {
|
||||
if (line.startsWith(test)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void saveArrayListToConfig(final Main main, final List<String> lines) {
|
||||
try {
|
||||
final BufferedWriter fw = Files.newBufferedWriter(new File(getFilePath(main, "config.yml")).toPath(), StandardCharsets.UTF_8);
|
||||
for (final String line : lines) {
|
||||
fw.write(line + System.lineSeparator());
|
||||
}
|
||||
fw.close();
|
||||
} catch (final IOException ioException) {
|
||||
ioException.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to update the config
|
||||
*/
|
||||
public static void updateConfig() {
|
||||
final Main main = Main.getInstance();
|
||||
final Logger logger = main.getLogger();
|
||||
debug(logger, "Newest config version = " + getNewConfigVersion());
|
||||
debug(logger, "Current config version = " + main.getConfig().getLong(Config.CONFIG_VERSION));
|
||||
if (main.getConfig().getLong(Config.CONFIG_VERSION) >= getNewConfigVersion()) {
|
||||
debug(logger, "The config currently used has an equal or newer version than the one shipped with this release.");
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info("===========================================");
|
||||
logger.info("You are using an outdated config file.");
|
||||
logger.info("Your config file will now be updated to the");
|
||||
logger.info("newest version. You changes will be kept.");
|
||||
logger.info("===========================================");
|
||||
|
||||
backupCurrentConfig(main);
|
||||
main.saveDefaultConfig();
|
||||
|
||||
final Set<String> oldConfigNodes = main.getConfig().getKeys(false);
|
||||
final ArrayList<String> newConfig = new ArrayList<>();
|
||||
|
||||
// Iterate through ALL lines from the new default config
|
||||
for (final String defaultLine : getNewConfigAsArrayList(main)) {
|
||||
|
||||
String updatedLine = defaultLine;
|
||||
|
||||
/*if (Daddy.allows(Features.GENERIC)) {
|
||||
if (updatedLine.startsWith("# PREMIUM FEATURE: ONLY AVAILABLE IN AngelChestPlus!")) {
|
||||
updatedLine = null;
|
||||
}
|
||||
} else*/
|
||||
if (defaultLine.startsWith("-") || defaultLine.startsWith(" -") || defaultLine.startsWith(" -")) {
|
||||
debug(logger, "Not including default String list entry: " + defaultLine);
|
||||
updatedLine = null;
|
||||
} else if (lineContainsIgnoredNode(defaultLine)) {
|
||||
debug(logger, "Not updating this line: " + defaultLine);
|
||||
} else if (lineIsStringList(defaultLine)) {
|
||||
updatedLine = null;
|
||||
newConfig.add(defaultLine);
|
||||
final String node = defaultLine.split(":")[0];
|
||||
for (final String entry : main.getConfig().getStringList(node)) {
|
||||
newConfig.add("- " + entry);
|
||||
}
|
||||
} else {
|
||||
for (final String node : oldConfigNodes) {
|
||||
// Iterate through all keys from the old config file.
|
||||
if (defaultLine.startsWith(node + ":")) {
|
||||
// This key from the old file matches this line from the new file! Updating...
|
||||
final String quotes = getQuotes(node);
|
||||
String value = main.getConfig().get(node).toString();
|
||||
|
||||
// The hologram text needs special escaping for the newline symbols
|
||||
if (node.equals("hologram-text")) {
|
||||
value = value.replaceAll("\n", "\\\\n");
|
||||
}
|
||||
|
||||
updatedLine = node + ": " + quotes + value + quotes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (updatedLine != null) {
|
||||
newConfig.add(updatedLine);
|
||||
}
|
||||
}
|
||||
|
||||
saveArrayListToConfig(main, newConfig);
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package de.jeff_media.bettertridents.config;
|
||||
|
||||
public class Permissions {
|
||||
public static final String SAVE_VOID = "bettertridents.savevoid";
|
||||
public static final String RELOAD = "bettertridents.reload";
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package de.jeff_media.bettertridents.listeners;
|
||||
|
||||
import de.jeff_media.bettertridents.Main;
|
||||
import de.jeff_media.bettertridents.config.Config;
|
||||
import de.jeff_media.bettertridents.utils.EnchantmentUtils;
|
||||
import org.bukkit.GameRule;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Drowned;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.Damageable;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class DropListener implements Listener {
|
||||
|
||||
private final Main main = Main.getInstance();
|
||||
final Random random = new Random();
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
private void onKillDrowned(EntityDeathEvent event) {
|
||||
if (!main.getConfig().getBoolean(Config.DROP_BEDROCK_CHANCE)) return;
|
||||
if (!(event.getEntity().getLastDamageCause() instanceof EntityDamageByEntityEvent)) return;
|
||||
EntityDamageByEntityEvent damageEvent = (EntityDamageByEntityEvent) event.getEntity().getLastDamageCause();
|
||||
if (damageEvent.getDamager().getType() != EntityType.PLAYER) return;
|
||||
Player lastDamager = (Player) damageEvent.getDamager();
|
||||
int fortune = EnchantmentUtils.getLevelFromTrident(lastDamager, Enchantment.LOOT_BONUS_MOBS);
|
||||
if (!(event.getEntity() instanceof Drowned)) return;
|
||||
|
||||
Drowned drowned = (Drowned) event.getEntity();
|
||||
if (!drowned.getWorld().getGameRuleValue(GameRule.DO_MOB_LOOT)) return;
|
||||
if (drowned.getEquipment().getItemInMainHand().getType() != Material.TRIDENT) return;
|
||||
|
||||
for (ItemStack drop : event.getDrops()) {
|
||||
if (drop.getType() == Material.TRIDENT) return;
|
||||
}
|
||||
|
||||
main.debug("Using bedrock drop chance...");
|
||||
|
||||
int chance = random.nextInt(100);
|
||||
main.debug("Drop chance: " + chance);
|
||||
if (chance > 25 + (4 * fortune)) return;
|
||||
ItemStack trident = new ItemStack(Material.TRIDENT);
|
||||
Damageable meta = (Damageable) trident.getItemMeta();
|
||||
meta.setDamage(random.nextInt(248) + 1);
|
||||
trident.setItemMeta((ItemMeta) meta);
|
||||
event.getDrops().add(trident);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
package de.jeff_media.bettertridents.listeners;
|
||||
|
||||
import de.jeff_media.bettertridents.Main;
|
||||
import de.jeff_media.bettertridents.config.Config;
|
||||
import de.jeff_media.bettertridents.utils.EnchantmentUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class ImpalingListener implements Listener {
|
||||
|
||||
private final Main main = Main.getInstance();
|
||||
|
||||
private final Random random = new Random();
|
||||
|
||||
private static boolean isAquatic(EntityType type) {
|
||||
switch (type) {
|
||||
case DOLPHIN:
|
||||
case GUARDIAN:
|
||||
case ELDER_GUARDIAN:
|
||||
case SQUID:
|
||||
case TURTLE:
|
||||
case COD:
|
||||
case SALMON:
|
||||
case PUFFERFISH:
|
||||
case TROPICAL_FISH:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isInRain(Entity entity) {
|
||||
World world = entity.getWorld();
|
||||
if (!world.hasStorm()) return false;
|
||||
Location min = entity.getBoundingBox().getMin().toLocation(world);
|
||||
Location max = entity.getBoundingBox().getMax().toLocation(world);
|
||||
for (int x = min.getBlockX(); x <= max.getBlockX(); x++) {
|
||||
for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) {
|
||||
Block highest = world.getHighestBlockAt(x, z);
|
||||
if (highest == null || highest.getType().isAir()) return true;
|
||||
if (highest.getY() < entity.getLocation().getY()) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isInWater(Entity entity) {
|
||||
World world = entity.getWorld();
|
||||
Location min = entity.getBoundingBox().getMin().toLocation(entity.getWorld());
|
||||
Location max = entity.getBoundingBox().getMax().toLocation(entity.getWorld());
|
||||
for (int x = min.getBlockX(); x <= max.getBlockX(); x++) {
|
||||
for (int y = min.getBlockY(); y <= max.getBlockY(); y++) {
|
||||
for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) {
|
||||
if (world.getBlockAt(x, y, z).getType() == Material.WATER) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void displayEnchantedHit(Entity entity) {
|
||||
for (int i = 0; i < 16 * 3; i++) {
|
||||
double d = (this.random.nextFloat() * 2.0F - 1.0F);
|
||||
double e = (this.random.nextFloat() * 2.0F - 1.0F);
|
||||
double f = (this.random.nextFloat() * 2.0F - 1.0F);
|
||||
if (Math.sqrt(d) + Math.sqrt(e) + Math.sqrt(f) <= 1.0D) {
|
||||
Location loc = entity.getLocation().clone();
|
||||
loc.add((entity.getWidth() * (d / 4.0D)),
|
||||
(entity.getHeight() * (0.5D + e / 4.0D)),
|
||||
(entity.getWidth() * (f / 4.0D)));
|
||||
loc.getWorld().spawnParticle(Particle.CRIT_MAGIC, loc, 0, d, e + 0.2D, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
private void onHitByImpaling(EntityDamageByEntityEvent event) {
|
||||
if (!main.getConfig().getBoolean(Config.BEDROCK_IMPALING)) return;
|
||||
|
||||
Entity entity = event.getEntity();
|
||||
int impaling = 0;
|
||||
if (event.getDamager().getType() == EntityType.TRIDENT) {
|
||||
impaling = EnchantmentUtils.getImpaling((Trident) event.getDamager());
|
||||
} else if (event.getDamager().getType() == EntityType.PLAYER) {
|
||||
impaling = ((Player) event.getDamager()).getInventory().getItemInMainHand().getEnchantmentLevel(Enchantment.IMPALING);
|
||||
}
|
||||
|
||||
if (impaling > 0) {
|
||||
if (!isAquatic(entity.getType()) && (isInRain(entity) || isInWater(entity))) {
|
||||
event.setDamage(event.getDamage() + (2.5 * impaling));
|
||||
main.debug("Adjusting Impaling damage: adding " + 2.5*impaling + " damage");
|
||||
displayEnchantedHit(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package de.jeff_media.bettertridents.listeners;
|
||||
|
||||
import de.jeff_media.bettertridents.Main;
|
||||
import de.jeff_media.bettertridents.config.Config;
|
||||
import de.jeff_media.bettertridents.tasks.MoveToOffhand;
|
||||
import de.jeff_media.bettertridents.utils.EnchantmentUtils;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Trident;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerPickupArrowEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class OffhandListener implements Listener {
|
||||
|
||||
private final Main main = Main.getInstance();
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
private void onPickupTrident(PlayerPickupArrowEvent event) {
|
||||
main.debug("onPickupTrident");
|
||||
if (!main.getConfig().getBoolean(Config.RETURN_TO_OFFHAND)) return;
|
||||
if (!(event.getArrow() instanceof Trident)) return;
|
||||
Trident trident = (Trident) event.getArrow();
|
||||
if(!EnchantmentUtils.isOffhandThrown(trident)) {
|
||||
main.debug("This trident wasn't thrown from the offhand.");
|
||||
return;
|
||||
}
|
||||
Player player = event.getPlayer();
|
||||
if (player.getInventory().getItemInOffHand().getType() != Material.AIR) return;
|
||||
|
||||
ItemStack tridentItem = event.getItem().getItemStack().clone();
|
||||
|
||||
main.debug("Starting offhand task...");
|
||||
new MoveToOffhand(player, tridentItem).runTask(main);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,28 @@
|
||||
package de.jeff_media.bettertridents.listeners;
|
||||
|
||||
import de.jeff_media.bettertridents.Main;
|
||||
import de.jeff_media.bettertridents.config.Config;
|
||||
import de.jeff_media.bettertridents.utils.EnchantmentUtils;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Trident;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityPortalEvent;
|
||||
|
||||
public class PortalListener implements Listener {
|
||||
|
||||
private final Main main = Main.getInstance();
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onTridentEnterPortal(EntityPortalEvent event) {
|
||||
if(!main.getConfig().getBoolean(Config.DISABLE_LOYALTY_PORTALS)) return;
|
||||
if(event.getEntityType() != EntityType.TRIDENT) return;
|
||||
Trident trident = (Trident) event.getEntity();
|
||||
if(EnchantmentUtils.getLoyalty(trident)>0) {
|
||||
main.debug("Prevented loyalty trident from travelling through portqal");
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package de.jeff_media.bettertridents.listeners;
|
||||
|
||||
import de.jeff_media.bettertridents.Main;
|
||||
import de.jeff_media.bettertridents.utils.EnchantmentUtils;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Trident;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.ProjectileLaunchEvent;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
public class TridentThrowListener implements Listener {
|
||||
|
||||
private final Main main = Main.getInstance();
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onTridentThrow(ProjectileLaunchEvent event) {
|
||||
if (event.getEntityType() != EntityType.TRIDENT) return;
|
||||
main.debug("Trident throw Listener: ProjectileLaunchEvent");
|
||||
|
||||
Trident trident = (Trident) event.getEntity();
|
||||
if (!(trident.getShooter() instanceof Player)) {
|
||||
main.debug("This trident wasn't thrown by a player.");
|
||||
return;
|
||||
}
|
||||
Player player = (Player) trident.getShooter();
|
||||
|
||||
// Impaling
|
||||
int impaling = EnchantmentUtils.getLevelFromTrident(player, Enchantment.IMPALING);
|
||||
main.debug("Applying impaling level " + impaling);
|
||||
EnchantmentUtils.registerImpaling((Trident) event.getEntity(), impaling);
|
||||
|
||||
// Loyalty
|
||||
int loyalty = EnchantmentUtils.getLevelFromTrident(player, Enchantment.LOYALTY);
|
||||
main.debug("Applying loyalty level " + loyalty);
|
||||
EnchantmentUtils.registerLoyalty((Trident) event.getEntity(), loyalty);
|
||||
|
||||
// Offhand
|
||||
if (player.getInventory().getItemInMainHand().getType() == Material.TRIDENT) return;
|
||||
if (player.getInventory().getItemInOffHand().getType() != Material.TRIDENT) return;
|
||||
trident.getPersistentDataContainer().set(Main.OFFHAND_TAG, PersistentDataType.BYTE, (byte) 1);
|
||||
main.debug("This trident was thrown by the offhand.");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package de.jeff_media.bettertridents.listeners;
|
||||
|
||||
import de.jeff_media.bettertridents.Main;
|
||||
import de.jeff_media.bettertridents.config.Config;
|
||||
import de.jeff_media.bettertridents.tasks.WatchTrident;
|
||||
import de.jeff_media.bettertridents.utils.EnchantmentUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Trident;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.ProjectileLaunchEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class VoidListener implements Listener {
|
||||
|
||||
private final Main main = Main.getInstance();
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onThrowTrident(ProjectileLaunchEvent event) {
|
||||
main.debug("VoidListener");
|
||||
if (event.getEntityType() != EntityType.TRIDENT) {
|
||||
main.debug("Not a trident");
|
||||
return;
|
||||
}
|
||||
Trident trident = (Trident) event.getEntity();
|
||||
//if (main.isLoyal(trident)) return;
|
||||
if (!(trident.getShooter() instanceof Player)) {
|
||||
main.debug("Not shot by player");
|
||||
return;
|
||||
}
|
||||
Player player = (Player) trident.getShooter();
|
||||
ItemStack tridentItem = null;
|
||||
if (player.getInventory().getItemInOffHand() != null) {
|
||||
if (player.getInventory().getItemInOffHand().getType() == Material.TRIDENT) {
|
||||
tridentItem = player.getInventory().getItemInOffHand();
|
||||
}
|
||||
}
|
||||
if (player.getInventory().getItemInMainHand() != null) {
|
||||
if (player.getInventory().getItemInMainHand().getType() == Material.TRIDENT) {
|
||||
tridentItem = player.getInventory().getItemInMainHand();
|
||||
}
|
||||
}
|
||||
if (tridentItem == null) {
|
||||
main.debug("tridentItem not found");
|
||||
return;
|
||||
}
|
||||
if (!EnchantmentUtils.hasLoyalty(tridentItem)) {
|
||||
main.debug("No loyalty");
|
||||
return;
|
||||
}
|
||||
if(!main.getConfig().getBoolean(Config.VOID_SAVING)) {
|
||||
main.debug("Void Saving disabled");
|
||||
return;
|
||||
}
|
||||
main.setLoyal(trident);
|
||||
main.debug("New task: WatchTrident");
|
||||
new WatchTrident(trident).runTaskTimer(main,1,1);
|
||||
Bukkit.getScheduler().runTaskLater(main,() ->main.removeLoyal(trident),1200);
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package de.jeff_media.bettertridents.tasks;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
public class MoveToOffhand extends BukkitRunnable {
|
||||
private final Player player;
|
||||
private final ItemStack tridentItem;
|
||||
|
||||
public MoveToOffhand(Player player, ItemStack tridentItem) {
|
||||
this.player = player;
|
||||
this.tridentItem = tridentItem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (ItemStack item : player.getInventory()) {
|
||||
if (item != null && item.equals(tridentItem)) {
|
||||
player.getInventory().remove(item);
|
||||
player.getInventory().setItemInOffHand(item.clone());
|
||||
break;
|
||||
}
|
||||
}
|
||||
player.updateInventory();
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package de.jeff_media.notridentvoid.tasks;
|
||||
package de.jeff_media.bettertridents.tasks;
|
||||
|
||||
import de.jeff_media.notridentvoid.Main;
|
||||
import de.jeff_media.bettertridents.Main;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
@ -1,6 +1,6 @@
|
||||
package de.jeff_media.notridentvoid.tasks;
|
||||
package de.jeff_media.bettertridents.tasks;
|
||||
|
||||
import de.jeff_media.notridentvoid.Main;
|
||||
import de.jeff_media.bettertridents.Main;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Trident;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
@ -37,7 +37,7 @@ public class WatchTrident extends BukkitRunnable {
|
||||
}
|
||||
|
||||
nextLocation.getBlock().setType(Main.SAFETY_MATERIAL);
|
||||
|
||||
Main.getInstance().debug("New Task: RemoveBarrier");
|
||||
new RemoveBarrier(trident, nextLocation.getBlock()).runTaskTimer(Main.getInstance(), 1, 1);
|
||||
cancel();
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package de.jeff_media.bettertridents.utils;
|
||||
|
||||
import de.jeff_media.bettertridents.Main;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Trident;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
public class EnchantmentUtils {
|
||||
|
||||
public static int getLevelFromTrident(Player player, Enchantment enchantment) {
|
||||
ItemStack item = player.getInventory().getItemInMainHand();
|
||||
if(item.getType()!= Material.TRIDENT) {
|
||||
item = player.getInventory().getItemInOffHand();
|
||||
}
|
||||
if(item.getType()!=Material.TRIDENT) return 0;
|
||||
if (!item.hasItemMeta()) return 0;
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if (meta.hasEnchant(enchantment)) {
|
||||
return meta.getEnchantLevel(enchantment);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int getImpaling(Trident trident) {
|
||||
return trident.getPersistentDataContainer().getOrDefault(Main.IMPALING_TAG, PersistentDataType.INTEGER, 0);
|
||||
}
|
||||
|
||||
public static void registerImpaling(Trident trident, int level) {
|
||||
if(level == 0) return;
|
||||
trident.getPersistentDataContainer().set(Main.IMPALING_TAG, PersistentDataType.INTEGER, level);
|
||||
}
|
||||
|
||||
public static int getLoyalty(Trident trident) {
|
||||
return trident.getPersistentDataContainer().getOrDefault(Main.LOYALTY_TAG, PersistentDataType.INTEGER, 0);
|
||||
}
|
||||
|
||||
public static void registerLoyalty(Trident trident, int level) {
|
||||
if(level == 0) return;
|
||||
trident.getPersistentDataContainer().set(Main.LOYALTY_TAG, PersistentDataType.INTEGER, level);
|
||||
}
|
||||
|
||||
public static boolean isOffhandThrown(Trident trident) {
|
||||
return trident.getPersistentDataContainer().has(Main.OFFHAND_TAG, PersistentDataType.BYTE);
|
||||
}
|
||||
|
||||
public static boolean hasLoyalty(ItemStack item) {
|
||||
if (!item.hasItemMeta()) return false;
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
return meta.hasEnchant(Enchantment.LOYALTY);
|
||||
}
|
||||
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package de.jeff_media.notridentvoid.config;
|
||||
|
||||
import de.jeff_media.notridentvoid.Main;
|
||||
|
||||
public class Config {
|
||||
|
||||
private final Main main = Main.getInstance();
|
||||
|
||||
public static final String VOID_SAVING = "void-saving";
|
||||
public static final String CHECK_FOR_UPDATES = "check-for-updates";
|
||||
public static final String UPDATE_CHECK_INTERVAL = "update-check-interval";
|
||||
|
||||
public Config() {
|
||||
addDefault(VOID_SAVING, true);
|
||||
}
|
||||
|
||||
private void addDefault(String node, Object value) {
|
||||
main.getConfig().set(node, value);
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package de.jeff_media.notridentvoid.config;
|
||||
|
||||
public class Permissions {
|
||||
public static final String NOTRIDENTVOID_USE = "notridentvoid.use";
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
package de.jeff_media.notridentvoid.listeners;
|
||||
|
||||
import de.jeff_media.notridentvoid.Main;
|
||||
import de.jeff_media.notridentvoid.config.Config;
|
||||
import de.jeff_media.notridentvoid.tasks.WatchTrident;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Trident;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.ProjectileLaunchEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
public class ProjectileListener implements Listener {
|
||||
|
||||
private final Main main = Main.getInstance();
|
||||
|
||||
private boolean hasLoyalty(ItemStack item) {
|
||||
if(!item.hasItemMeta()) return false;
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
return meta.hasEnchant(Enchantment.LOYALTY);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onShoot(ProjectileLaunchEvent event) {
|
||||
if(event.getEntityType() != EntityType.TRIDENT) return;
|
||||
Trident trident = (Trident) event.getEntity();
|
||||
if(main.isRegistered(trident)) return;
|
||||
//if(!hasLoyalty(trident)) return;
|
||||
if(!(trident.getShooter() instanceof Player)) return;
|
||||
Player player = (Player) trident.getShooter();
|
||||
ItemStack tridentItem = null;
|
||||
if(player.getInventory().getItemInOffHand() != null) {
|
||||
if(player.getInventory().getItemInOffHand().getType() == Material.TRIDENT) {
|
||||
tridentItem = player.getInventory().getItemInOffHand();
|
||||
}
|
||||
}
|
||||
if(player.getInventory().getItemInMainHand() != null) {
|
||||
if(player.getInventory().getItemInMainHand().getType() == Material.TRIDENT) {
|
||||
tridentItem = player.getInventory().getItemInMainHand();
|
||||
}
|
||||
}
|
||||
if(tridentItem == null) return;
|
||||
if(!hasLoyalty(tridentItem)) return;
|
||||
if(!main.getConfig().getBoolean(Config.VOID_SAVING)) return;
|
||||
main.register(trident);
|
||||
new WatchTrident(trident).runTaskTimer(main,1,1);
|
||||
Bukkit.getScheduler().runTaskLater(main,() ->main.unregister(trident),20);
|
||||
}
|
||||
}
|
1
src/main/resources/config-version.txt
Normal file
1
src/main/resources/config-version.txt
Normal file
@ -0,0 +1 @@
|
||||
${config.version}
|
@ -8,7 +8,7 @@
|
||||
# Permissions #
|
||||
###############
|
||||
|
||||
# notridentvoid.use
|
||||
# bettertridents.savevoid
|
||||
# Allows to use the "void-saving" feature
|
||||
# Default: true
|
||||
|
||||
@ -17,6 +17,22 @@
|
||||
# This is currently the only function of this plugin :P
|
||||
void-saving: true
|
||||
|
||||
# When enabled, the Impaling enchantment behaves like in Bedrock edition: it deals extra damage to mobs
|
||||
# touching water or rain.
|
||||
# In 1.17+, this is no longer needed ( https://minecraft.fandom.com/wiki/Java_Edition_Combat_Test_4 )
|
||||
bedrock-impaling: true
|
||||
|
||||
# When enabled, Drowned drop tridents as often as in Bedrock edition.
|
||||
# Default Java Edition drop chance: 8.5% (up to 11.5% with Looting 3) for all Drowned holding a trident
|
||||
# Bedrock Edition drop chance: 25% (up to 37% with Looting 3) for all Drowned holding a trident
|
||||
bedrock-drop-chance: true
|
||||
|
||||
# When enabled, tridents thrown from the offhand will go back to the offhand slot when picked up
|
||||
return-to-offhand: true
|
||||
|
||||
# When enabled, tridents enchanted with loyalty will be prevented from travelling through portals
|
||||
disable-loyalty-portals: true
|
||||
|
||||
# Should we check for updates?
|
||||
# When enabled, a message is printed in the console if a new version has
|
||||
# been found, and OPs will be notified when they join the server.
|
||||
@ -28,6 +44,9 @@ check-for-updates: true
|
||||
# When check-for-updates is true, AngelChest will check every X hours
|
||||
update-check-interval: 4
|
||||
|
||||
# Debug mode - you probably don't want this
|
||||
debug: false
|
||||
|
||||
# NEVER CHANGE THE VALUES BELOW!
|
||||
plugin-version: ${project.version}
|
||||
config-version: ${config.version}
|
@ -10,7 +10,19 @@ load: STARTUP
|
||||
awareness:
|
||||
- !@UTF8
|
||||
commands:
|
||||
bettertridents:
|
||||
description: Reloads the config file
|
||||
permission: bettertridents.reload
|
||||
usage: /<command>
|
||||
permissions:
|
||||
notridentvoid.use:
|
||||
bettertridents.*:
|
||||
description: Allows to use all BetterTridents features
|
||||
children:
|
||||
- bettertridents.savevoid
|
||||
default: op
|
||||
bettertridents.savevoid:
|
||||
description: Prevents tridents enchanted with loyalty to get lost in the void
|
||||
default: true
|
||||
default: true
|
||||
bettertridents.reload:
|
||||
description: Allows to reload the config file using /bettertridents
|
||||
default: op
|
Loading…
Reference in New Issue
Block a user