package de.flo56958.minetinker.modifiers.types; import de.flo56958.minetinker.MineTinker; import de.flo56958.minetinker.data.ToolType; import de.flo56958.minetinker.modifiers.Modifier; import de.flo56958.minetinker.utils.ChatWriter; import de.flo56958.minetinker.utils.ConfigurationManager; import de.flo56958.minetinker.utils.LanguageManager; import org.bukkit.*; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerToggleSneakEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.Damageable; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.util.Vector; import java.io.File; import java.util.*; public class Propelling extends Modifier implements Listener { private static Propelling instance; private int durabilityLoss; private double speedPerLevel; private boolean sound; private boolean particles; private boolean considerReinforced; private boolean useLessDurability; private int cooldownInSeconds; private final HashMap<String, Long> cooldownTracker = new HashMap<>(); private Propelling() { super(MineTinker.getPlugin()); customModelData = 10_028; } public static Propelling instance() { synchronized (Propelling.class) { if (instance == null) { instance = new Propelling(); } } return instance; } @Override public String getKey() { return "Propelling"; } @Override public List<ToolType> getAllowedTools() { return Arrays.asList(ToolType.ELYTRA, ToolType.TRIDENT); } @Override public List<Enchantment> getAppliedEnchantments() { return Collections.singletonList(Enchantment.RIPTIDE); } @Override public void reload() { FileConfiguration config = getConfig(); config.options().copyDefaults(true); config.addDefault("Allowed", true); config.addDefault("Color", "%GOLD%"); config.addDefault("MaxLevel", 3); config.addDefault("SlotCost", 1); config.addDefault("CooldownInSeconds", 5); config.addDefault("Elytra.DurabilityLoss", 10); config.addDefault("Elytra.SpeedPerLevel", 0.05); config.addDefault("Elytra.Sound", true); config.addDefault("Elytra.Particles", true); config.addDefault("ConsiderReinforced", true); //should Reinforced (Unbreaking) be considered config.addDefault("ReinforcedUseLessDurability", true); //should Reinforced lessen the durability damage or if false chance to dont use durability at all config.addDefault("EnchantCost", 25); config.addDefault("Enchantable", true); config.addDefault("Recipe.Enabled", false); ConfigurationManager.saveConfig(config); ConfigurationManager.loadConfig("Modifiers" + File.separator, getFileName()); init(Material.FIREWORK_STAR); this.durabilityLoss = config.getInt("Elytra.DurabilityLoss", 10); this.speedPerLevel = config.getDouble("Elytra.SpeedPerLevel", 0.05); this.considerReinforced = config.getBoolean("ConsiderReinforced", true); this.useLessDurability = config.getBoolean("ReinforcedUseLessDurability", true); this.cooldownInSeconds = config.getInt("CooldownInSeconds", 5); this.sound = config.getBoolean("Elytra.Sound", true); this.particles = config.getBoolean("Elytra.Particles", true); } @Override public boolean applyMod(Player player, ItemStack tool, boolean isCommand) { ItemMeta meta = tool.getItemMeta(); if (meta != null) { if (ToolType.TRIDENT.contains(tool.getType())) { meta.addEnchant(Enchantment.RIPTIDE, modManager.getModLevel(tool, this), true); } //Elytra does not get an enchantment tool.setItemMeta(meta); } return true; } @EventHandler(ignoreCancelled = true) public void onElytraSneak(PlayerToggleSneakEvent event) { Player player = event.getPlayer(); if (event.isSneaking()) { return; } if (!player.isGliding()) { return; } if (!player.hasPermission("minetinker.modifiers.propelling.use")) { return; } ItemStack elytra = player.getInventory().getChestplate(); if (elytra == null) { return; } if (!(modManager.isArmorViable(elytra) && ToolType.ELYTRA.contains(elytra.getType()))) { return; } if (!modManager.hasMod(elytra, this)) { return; } if (cooldownInSeconds > 0) { long time = System.currentTimeMillis(); Long playerTime = this.cooldownTracker.get(player.getUniqueId().toString()); if (playerTime != null) { if (time - playerTime < this.cooldownInSeconds * 1000) { ChatWriter.logModifier(player, event, this, elytra, "Cooldown"); ChatWriter.sendActionBar(player, this.getName() + ": " + LanguageManager.getString("Alert.OnCooldown", player)); return; } else { this.cooldownTracker.remove(player.getUniqueId().toString()); } } } int maxDamage = elytra.getType().getMaxDurability(); ItemMeta meta = elytra.getItemMeta(); if (meta instanceof Damageable && !meta.isUnbreakable() && (player.getGameMode() == GameMode.SURVIVAL || player.getGameMode() == GameMode.ADVENTURE)) { Damageable dam = (Damageable) meta; int loss = durabilityLoss; if (considerReinforced) { int level = modManager.getModLevel(elytra, Reinforced.instance()); if (useLessDurability) { loss = (int) Math.round(durabilityLoss * (1.0 / (level + 1))); } else { int durabilityChance = 60 + (40 / (level + 1)); if (new Random().nextInt(100) > durabilityChance) { loss = 0; } } } if (maxDamage <= dam.getDamage() + loss + 1) { player.playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 0.5F, 0.5F); return; } dam.setDamage(dam.getDamage() + loss); elytra.setItemMeta(meta); } int level = modManager.getModLevel(elytra, this); Location loc = player.getLocation(); Vector dir = loc.getDirection().normalize(); player.setVelocity(player.getVelocity().add(dir.multiply(1 + speedPerLevel * level))); if (particles && loc.getWorld() != null) { loc.getWorld().spawnParticle(Particle.CLOUD, loc, 30, 0.5F, 0.5F, 0.5F, 0.0F); } if (sound) player.getWorld().playSound(loc, Sound.ENTITY_ENDER_DRAGON_FLAP, 0.5F, 0.5F); if (cooldownInSeconds > 0) { this.cooldownTracker.put(player.getUniqueId().toString(), System.currentTimeMillis()); } ChatWriter.logModifier(player, event, this, elytra); } }