Updated the abilities to use constants to make balancing easier, might change it to config variables later.
This commit is contained in:
@@ -21,11 +21,15 @@ repositories {
|
||||
name = "sk89q-repo"
|
||||
url = "https://maven.enginehub.org/repo/"
|
||||
}
|
||||
maven {
|
||||
url = 'https://repo.extendedclip.com/content/repositories/placeholderapi/'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("io.papermc.paper:paper-api:1.21.5-R0.1-SNAPSHOT")
|
||||
compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.14-SNAPSHOT'
|
||||
compileOnly 'me.clip:placeholderapi:2.11.6'
|
||||
}
|
||||
|
||||
tasks {
|
||||
|
||||
@@ -29,10 +29,10 @@ public final class TrimServer extends JavaPlugin {
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
BlockDisplayRaytracer.cleanup();
|
||||
getLogger().info("Cleaning up...");
|
||||
manager.cleanup();
|
||||
getLogger().info("Saved all IO files.");
|
||||
manager.io.saveAll();
|
||||
getLogger().info("Saved all IO files.");
|
||||
}
|
||||
|
||||
public static TrimServer getInstance() {
|
||||
|
||||
@@ -5,15 +5,15 @@ import me.trouper.trimserver.TrimServer;
|
||||
import me.trouper.trimserver.data.IO;
|
||||
import me.trouper.trimserver.data.io.Config;
|
||||
import me.trouper.trimserver.data.io.Storage;
|
||||
import me.trouper.trimserver.utils.Text;
|
||||
import me.trouper.trimserver.utils.text.CustomBossBar;
|
||||
import me.trouper.trimserver.utils.text.Text;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
public interface Main {
|
||||
Main main = new Main() {
|
||||
};
|
||||
Main main = new Main() {};
|
||||
|
||||
Random random = new Random();
|
||||
|
||||
@@ -53,6 +53,10 @@ public interface Main {
|
||||
Text.sendMessage(Text.Pallet.WARNING, player, message, args);
|
||||
}
|
||||
|
||||
default void success(CommandSender player, String message, Object... args) {
|
||||
Text.sendMessage(Text.Pallet.SUCCESS, player, message, args);
|
||||
}
|
||||
|
||||
default void checkPre(boolean check, String msg, Object... args) {
|
||||
if (!check) {
|
||||
throw new IllegalArgumentException(msg.formatted(args));
|
||||
|
||||
@@ -1,43 +1,56 @@
|
||||
package me.trouper.trimserver.server;
|
||||
|
||||
import me.trouper.trimserver.TrimServer;
|
||||
import me.trouper.trimserver.data.IO;
|
||||
import me.trouper.trimserver.server.api.TrimPlaceholders;
|
||||
import me.trouper.trimserver.server.commands.AdminCommand;
|
||||
import me.trouper.trimserver.server.commands.InfoCommand;
|
||||
import me.trouper.trimserver.server.commands.TrustCommand;
|
||||
import me.trouper.trimserver.server.events.JoinEvent;
|
||||
import me.trouper.trimserver.server.events.SwapHandsEvent;
|
||||
import me.trouper.trimserver.server.events.TrustEvents;
|
||||
import me.trouper.trimserver.server.flags.AbilityFlag;
|
||||
import me.trouper.trimserver.server.events.*;
|
||||
import me.trouper.trimserver.server.api.AbilityFlag;
|
||||
import me.trouper.trimserver.server.systems.PollingBackend;
|
||||
import me.trouper.trimserver.server.systems.TrustBackend;
|
||||
import me.trouper.trimserver.server.systems.AbilityBackend;
|
||||
import me.trouper.trimserver.server.systems.abilities.trims.*;
|
||||
import me.trouper.trimserver.utils.text.CustomBossBar;
|
||||
import me.trouper.trimserver.utils.visual.BlockDisplayRaytracer;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public class Manager {
|
||||
public IO io;
|
||||
public AbilityBackend abilityBackend;
|
||||
public TrustBackend trustBackend;
|
||||
public PollingBackend pollingBackend;
|
||||
public AbilityFlag abilityFlag;
|
||||
|
||||
|
||||
public Manager() {
|
||||
io = new IO();
|
||||
abilityBackend = new AbilityBackend();
|
||||
trustBackend = new TrustBackend();
|
||||
pollingBackend = new PollingBackend();
|
||||
abilityFlag = new AbilityFlag();
|
||||
}
|
||||
|
||||
|
||||
public void init() {
|
||||
io.loadAll();
|
||||
cleanup();
|
||||
|
||||
registerAbilities();
|
||||
registerEvents();
|
||||
registerCommands();
|
||||
|
||||
BlockDisplayRaytracer.cleanup();
|
||||
registerPlaceholders();
|
||||
|
||||
abilityBackend.startTickingBars();
|
||||
abilityFlag.register();
|
||||
pollingBackend.startPolling();
|
||||
}
|
||||
|
||||
private void registerPlaceholders() {
|
||||
if (!Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) {
|
||||
TrimServer.getInstance().getLogger().info("Could not register PAPI Expansion!");
|
||||
return;
|
||||
}
|
||||
new TrimPlaceholders(TrimServer.getInstance()).register();
|
||||
}
|
||||
|
||||
private void registerCommands() {
|
||||
@@ -47,9 +60,11 @@ public class Manager {
|
||||
}
|
||||
|
||||
private void registerEvents() {
|
||||
new SwapHandsEvent().registerEvents();
|
||||
new AbilityUseEvent().registerEvents();
|
||||
new JoinEvent().registerEvents();
|
||||
new TrustEvents().registerEvents();
|
||||
new ItemUseEvent().registerEvents();
|
||||
new CraftEvents().registerEvents();
|
||||
}
|
||||
|
||||
private void registerAbilities() {
|
||||
@@ -72,4 +87,9 @@ public class Manager {
|
||||
abilityBackend.registerAbility(new WayfinderAbility()).registerEvents();
|
||||
abilityBackend.registerAbility(new WildAbility()).registerEvents();
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
BlockDisplayRaytracer.cleanup();
|
||||
CustomBossBar.removeAllBossBars();
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,10 @@
|
||||
package me.trouper.trimserver.server.flags;
|
||||
package me.trouper.trimserver.server.api;
|
||||
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.protection.flags.*;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagConflictException;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import com.sk89q.worldguard.session.handler.FlagValueChangeHandler;
|
||||
import me.trouper.trimserver.TrimServer;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class AbilityFlag {
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package me.trouper.trimserver.server.api;
|
||||
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import me.trouper.trimserver.TrimServer;
|
||||
import me.trouper.trimserver.server.systems.AbilityBackend;
|
||||
import me.trouper.trimserver.server.systems.abilities.AbstractAbility;
|
||||
import me.trouper.trimserver.utils.text.Text;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.inventory.meta.trim.TrimMaterial;
|
||||
|
||||
public class TrimPlaceholders extends PlaceholderExpansion {
|
||||
|
||||
public TrimPlaceholders(TrimServer instance) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthor() {
|
||||
return "obvWolf";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "trims";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return "1.0.0";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean persist() {
|
||||
return true; // This is required or else PlaceholderAPI will unregister the Expansion on reload
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onRequest(OfflinePlayer player, String params) {
|
||||
if (params.equalsIgnoreCase("active_pattern")){
|
||||
if (Bukkit.getPlayer(player.getUniqueId()) == null) return "Offline Player!";
|
||||
AbstractAbility ability = TrimServer.getInstance().getManager().abilityBackend.getAbility(player.getPlayer());
|
||||
if (ability == null) return "none";
|
||||
return ability.getPatternName();
|
||||
}
|
||||
|
||||
if (params.equalsIgnoreCase("active_material")) {
|
||||
if (Bukkit.getPlayer(player.getUniqueId()) == null) return "Offline Player!";
|
||||
TrimMaterial material = TrimServer.getInstance().getManager().abilityBackend.getMaterial(player.getPlayer());
|
||||
if (material == null) return "none";
|
||||
return Text.formatEnum(AbilityBackend.ValidMaterial.validate(material));
|
||||
}
|
||||
|
||||
if (params.equalsIgnoreCase("active_cooldown")) {
|
||||
if (Bukkit.getPlayer(player.getUniqueId()) == null) return "Offline Player!";
|
||||
TrimMaterial material = TrimServer.getInstance().getManager().abilityBackend.getMaterial(player.getPlayer());
|
||||
AbstractAbility ability = TrimServer.getInstance().getManager().abilityBackend.getAbility(player.getPlayer());
|
||||
double sec = TrimServer.getInstance().getManager().abilityBackend.getCooldowns().getCooldownSec(new AbilityBackend.AbilityCooldown(player.getUniqueId(),ability.getPattern(),material));
|
||||
if (sec <= 0) return "ready";
|
||||
return sec + "s";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
package me.trouper.trimserver.server.commands;
|
||||
|
||||
|
||||
import io.papermc.paper.registry.keys.TrimPatternKeys;
|
||||
import me.trouper.trimserver.server.systems.AbilityBackend;
|
||||
import me.trouper.trimserver.utils.SoundPlayer;
|
||||
import me.trouper.trimserver.utils.Text;
|
||||
import me.trouper.trimserver.utils.text.Text;
|
||||
import me.trouper.trimserver.utils.commands.Args;
|
||||
import me.trouper.trimserver.utils.commands.CommandRegistry;
|
||||
import me.trouper.trimserver.utils.commands.Permission;
|
||||
@@ -18,7 +17,6 @@ import org.bukkit.*;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Display;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -29,8 +27,6 @@ import org.bukkit.inventory.meta.trim.TrimMaterial;
|
||||
import org.bukkit.inventory.meta.trim.TrimPattern;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@CommandRegistry(value = "trims",permission = @Permission("trims.admin"),printStackTrace = true)
|
||||
public class AdminCommand implements QuickCommand {
|
||||
@@ -45,6 +41,7 @@ public class AdminCommand implements QuickCommand {
|
||||
case "reload" -> handleReload(commandSender,args);
|
||||
case "try" -> handleTry(commandSender,args);
|
||||
case "test" -> handleTest(commandSender,args);
|
||||
case "give" -> handleGive(commandSender,args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,9 +90,38 @@ public class AdminCommand implements QuickCommand {
|
||||
)
|
||||
)
|
||||
)
|
||||
).then(
|
||||
b.arg("give")
|
||||
.then(b.arg("consumable")
|
||||
.then(
|
||||
b.argEnum(AbilityBackend.ValidPattern.class)
|
||||
.then(
|
||||
b.argEnum(AbilityBackend.ValidMaterial.class)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
private void handleGive(CommandSender commandSender, Args args) {
|
||||
switch (args.get(1).toString()) {
|
||||
case "consumable" -> {
|
||||
if (!(commandSender instanceof Player p)) {
|
||||
error(commandSender,"This sub-command is player only.");
|
||||
return;
|
||||
}
|
||||
AbilityBackend.ValidPattern pattern = args.get(2).toEnum(AbilityBackend.ValidPattern.class);
|
||||
AbilityBackend.ValidMaterial material = args.get(3).toEnum(AbilityBackend.ValidMaterial.class);
|
||||
|
||||
p.getInventory().addItem(main.man().abilityBackend.createConsumableAbility(pattern,material));
|
||||
success(commandSender,"Given you a consumable {0} material {1} consumable trim.",Text.formatEnum(material),Text.formatEnum(pattern));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void handleTest(CommandSender commandSender, Args args) {
|
||||
switch (args.get(1).toString()) {
|
||||
case "vector" -> {
|
||||
|
||||
@@ -2,7 +2,7 @@ package me.trouper.trimserver.server.commands;
|
||||
|
||||
import me.trouper.trimserver.TrimServer;
|
||||
import me.trouper.trimserver.server.systems.AbilityBackend;
|
||||
import me.trouper.trimserver.utils.Text;
|
||||
import me.trouper.trimserver.utils.text.Text;
|
||||
import me.trouper.trimserver.utils.commands.Args;
|
||||
import me.trouper.trimserver.utils.commands.CommandRegistry;
|
||||
import me.trouper.trimserver.utils.commands.QuickCommand;
|
||||
@@ -10,7 +10,7 @@ import me.trouper.trimserver.utils.commands.completions.CompletionBuilder;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
@CommandRegistry(value = "info")
|
||||
@CommandRegistry(value = "triminfo")
|
||||
public class InfoCommand implements QuickCommand {
|
||||
@Override
|
||||
public void dispatchCommand(CommandSender commandSender, Command command, String s, Args args) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package me.trouper.trimserver.server.commands;
|
||||
|
||||
|
||||
import me.trouper.trimserver.utils.Text;
|
||||
import me.trouper.trimserver.utils.text.Text;
|
||||
import me.trouper.trimserver.utils.commands.Args;
|
||||
import me.trouper.trimserver.utils.commands.CommandRegistry;
|
||||
import me.trouper.trimserver.utils.commands.QuickCommand;
|
||||
|
||||
@@ -5,7 +5,7 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
|
||||
|
||||
public class SwapHandsEvent implements QuickListener, Main {
|
||||
public class AbilityUseEvent implements QuickListener, Main {
|
||||
|
||||
@EventHandler
|
||||
public void onSwap(PlayerSwapHandItemsEvent e) {
|
||||
@@ -0,0 +1,24 @@
|
||||
package me.trouper.trimserver.server.events;
|
||||
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.block.CrafterCraftEvent;
|
||||
import org.bukkit.event.inventory.CraftItemEvent;
|
||||
import org.bukkit.event.inventory.PrepareSmithingEvent;
|
||||
import org.bukkit.inventory.ItemCraftResult;
|
||||
|
||||
public class CraftEvents implements QuickListener {
|
||||
@EventHandler
|
||||
public void onCraft(CraftItemEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onCraft(CrafterCraftEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onCraft(PrepareSmithingEvent e) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package me.trouper.trimserver.server.events;
|
||||
|
||||
import me.trouper.trimserver.server.systems.AbilityBackend;
|
||||
import me.trouper.trimserver.server.systems.abilities.AbstractAbility;
|
||||
import me.trouper.trimserver.server.systems.abilities.MaterialInfo;
|
||||
import me.trouper.trimserver.utils.text.Text;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class ItemUseEvent implements QuickListener {
|
||||
|
||||
@EventHandler
|
||||
public void onClick(PlayerInteractEvent e) {
|
||||
if (!e.getAction().equals(Action.RIGHT_CLICK_AIR) && !e.getAction().equals(Action.RIGHT_CLICK_BLOCK)) return;
|
||||
ItemStack i = e.getItem();
|
||||
Player p = e.getPlayer();
|
||||
if (i == null) return;
|
||||
AbilityBackend.ValidPattern pattern = main.man().abilityBackend.getConsumablePattern(i);
|
||||
AbilityBackend.ValidMaterial material = main.man().abilityBackend.getConsumableMaterial(i);
|
||||
if (pattern == null || material == null) return;
|
||||
|
||||
AbilityBackend.AbilityCooldown cooldownKey = new AbilityBackend.AbilityCooldown(p.getUniqueId(),pattern.getCanonical(),material.getCanonical());
|
||||
if (main.man().abilityBackend.getCooldowns().isOnCooldown(cooldownKey)) {
|
||||
error(p,"This ability is on cooldown for {0} seconds!",main.man().abilityBackend.getCooldowns().getCooldownSec(cooldownKey));
|
||||
p.setCooldown(i, (int) (20*main.man().abilityBackend.getCooldowns().getCooldownSec(cooldownKey)));
|
||||
return;
|
||||
}
|
||||
|
||||
AbstractAbility ability = main.man().abilityBackend.getAbility(pattern.getCanonical());
|
||||
MaterialInfo info = ability.getAbilityInfo(material.getCanonical());
|
||||
|
||||
ability.dispatchAbility(material,p);
|
||||
main.man().abilityBackend.getCooldowns().setCooldown(cooldownKey,info.cooldownTicks() * 50L);
|
||||
p.setCooldown(i, info.cooldownTicks());
|
||||
i.setAmount(i.getAmount() - 1);
|
||||
|
||||
success(p,"You have used the {0} ability for the {1} trim!", Text.formatEnum(material),Text.formatEnum(pattern));
|
||||
}
|
||||
}
|
||||
@@ -4,30 +4,34 @@ import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.regions.RegionContainer;
|
||||
import com.sk89q.worldguard.protection.regions.RegionQuery;
|
||||
import io.papermc.paper.registry.RegistryAccess;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.registry.keys.TrimPatternKeys;
|
||||
import me.trouper.trimserver.server.Main;
|
||||
import me.trouper.trimserver.server.flags.AbilityFlag;
|
||||
import me.trouper.trimserver.server.api.AbilityFlag;
|
||||
import me.trouper.trimserver.server.systems.abilities.MaterialInfo;
|
||||
import me.trouper.trimserver.server.systems.abilities.AbstractAbility;
|
||||
import me.trouper.trimserver.utils.Text;
|
||||
import me.trouper.trimserver.utils.text.Text;
|
||||
import me.trouper.trimserver.utils.misc.Cooldown;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.Bukkit;
|
||||
import net.kyori.adventure.text.format.TextDecoration;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.bukkit.inventory.meta.ArmorMeta;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.trim.ArmorTrim;
|
||||
import org.bukkit.inventory.meta.trim.TrimMaterial;
|
||||
import org.bukkit.inventory.meta.trim.TrimPattern;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
@@ -35,10 +39,119 @@ import java.util.logging.Level;
|
||||
public class AbilityBackend implements Main {
|
||||
public final Map<TrimPattern, AbstractAbility> registeredAbilities = new HashMap<>();
|
||||
|
||||
private record AbilityCooldown(UUID who, TrimPattern pattern, TrimMaterial material) {};
|
||||
public Cooldown<AbilityCooldown> getCooldowns() {
|
||||
return onCooldown;
|
||||
}
|
||||
|
||||
public record AbilityCooldown(UUID who, TrimPattern pattern, TrimMaterial material) {};
|
||||
|
||||
private final Cooldown<AbilityCooldown> onCooldown = new Cooldown<>();
|
||||
|
||||
/**
|
||||
* Creates a consumable ability token item with specified trim material and pattern.
|
||||
* This item can be used to grant a single-use ability.
|
||||
*
|
||||
* @param material The ValidMaterial for the ability token.
|
||||
* @param pattern The ValidPattern for the ability token.
|
||||
* @return An ItemStack representing the consumable ability token, or null if material/pattern is invalid.
|
||||
*/
|
||||
public ItemStack createConsumableAbility(ValidPattern pattern, ValidMaterial material) {
|
||||
if (material == null || pattern == null) {
|
||||
main.getPlugin().getLogger().warning("Attempted to create a consumable token with null material or pattern.");
|
||||
return null;
|
||||
}
|
||||
|
||||
ItemStack token = new ItemStack(pattern.getMaterial(), 1);
|
||||
ItemMeta meta = token.getItemMeta();
|
||||
|
||||
if (meta == null) {
|
||||
main.getPlugin().getLogger().severe("Failed to get ItemMeta for ability token.");
|
||||
return null;
|
||||
}
|
||||
|
||||
NamespacedKey materialKey = new NamespacedKey(main.getPlugin(), "consumable_trim_material");
|
||||
NamespacedKey patternKey = new NamespacedKey(main.getPlugin(), "consumable_trim_pattern");
|
||||
|
||||
PersistentDataContainer pdc = meta.getPersistentDataContainer();
|
||||
pdc.set(materialKey, PersistentDataType.STRING, material.name());
|
||||
pdc.set(patternKey, PersistentDataType.STRING, pattern.name());
|
||||
|
||||
meta.displayName(
|
||||
Text.color("&7Ability Token &8-&2&l " + Text.formatEnum(material)).decoration(TextDecoration.ITALIC,false)
|
||||
);
|
||||
|
||||
List<Component> lore = new ArrayList<>(List.of(
|
||||
Text.color("&8&l| &7A &csingle-use &7ability token.").decoration(TextDecoration.ITALIC, false),
|
||||
Text.color("&8&l| &7Pattern: &4" + Text.formatEnum(pattern)).decoration(TextDecoration.ITALIC, false),
|
||||
Text.color("&8&l| &7Material: &4" + Text.formatEnum(material)).decoration(TextDecoration.ITALIC, false),
|
||||
Text.color("&8&l|").decoration(TextDecoration.ITALIC,false),
|
||||
Text.color("&8&l| &cConsumable").decoration(TextDecoration.ITALIC, false)
|
||||
));
|
||||
meta.addEnchant(Enchantment.MENDING,1,true);
|
||||
meta.addItemFlags(ItemFlag.HIDE_ARMOR_TRIM,ItemFlag.HIDE_ATTRIBUTES,ItemFlag.HIDE_ENCHANTS);
|
||||
|
||||
meta.lore(lore);
|
||||
|
||||
token.setItemMeta(meta);
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the ValidMaterial stored in a consumable ability token's persistent data.
|
||||
*
|
||||
* @param itemStack The ItemStack to check.
|
||||
* @return The ValidMaterial if found, otherwise null.
|
||||
*/
|
||||
public ValidMaterial getConsumableMaterial(ItemStack itemStack) {
|
||||
if (itemStack == null || itemStack.getType() == Material.AIR || !itemStack.hasItemMeta()) {
|
||||
return null;
|
||||
}
|
||||
ItemMeta meta = itemStack.getItemMeta();
|
||||
if (meta == null) return null;
|
||||
|
||||
NamespacedKey materialKey = new NamespacedKey(main.getPlugin(), "consumable_trim_material");
|
||||
PersistentDataContainer pdc = meta.getPersistentDataContainer();
|
||||
|
||||
if (pdc.has(materialKey, PersistentDataType.STRING)) {
|
||||
String materialName = pdc.get(materialKey, PersistentDataType.STRING);
|
||||
try {
|
||||
return ValidMaterial.valueOf(materialName.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
main.getPlugin().getLogger().warning("Invalid material string found on consumable: " + materialName);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the ValidPattern stored in a consumable ability token's persistent data.
|
||||
*
|
||||
* @param itemStack The ItemStack to check.
|
||||
* @return The ValidPattern if found, otherwise null.
|
||||
*/
|
||||
public ValidPattern getConsumablePattern(ItemStack itemStack) {
|
||||
if (itemStack == null || itemStack.getType() == Material.AIR || !itemStack.hasItemMeta()) {
|
||||
return null;
|
||||
}
|
||||
ItemMeta meta = itemStack.getItemMeta();
|
||||
if (meta == null) return null;
|
||||
|
||||
NamespacedKey patternKey = new NamespacedKey(main.getPlugin(), "consumable_trim_pattern");
|
||||
PersistentDataContainer pdc = meta.getPersistentDataContainer();
|
||||
|
||||
if (pdc.has(patternKey, PersistentDataType.STRING)) {
|
||||
String patternName = pdc.get(patternKey, PersistentDataType.STRING);
|
||||
try {
|
||||
return ValidPattern.valueOf(patternName.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
main.getPlugin().getLogger().warning("Invalid pattern string found on consumable: " + patternName);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of registered ability pattern names as strings.
|
||||
* @return a list containing the string keys of the registered trim patterns.
|
||||
@@ -91,7 +204,11 @@ public class AbilityBackend implements Main {
|
||||
}
|
||||
|
||||
public TrimMaterial getMaterial(Player player) {
|
||||
return getArmorInfo(player).getValidMaterial().getCanonical();
|
||||
ArmorInfo info = getArmorInfo(player);
|
||||
if (info == null) return null;
|
||||
ValidMaterial material = getArmorInfo(player).getValidMaterial();
|
||||
if (material == null) return null;
|
||||
return material.getCanonical();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,7 +289,7 @@ public class AbilityBackend implements Main {
|
||||
|
||||
|
||||
try {
|
||||
boolean applyCooldown = abilityAllowed(player, player.getLocation()) && ability.dispatchAbility(info.getValidMaterial().getCanonical(), player);
|
||||
boolean applyCooldown = abilityAllowed(player, player.getLocation()) && ability.dispatchAbility(info.getValidMaterial(), player);
|
||||
|
||||
if (cooldownTicks > 0 && applyCooldown) onCooldown.addCooldown(cooldownKey, (long) cooldownTicks * 50L);
|
||||
|
||||
@@ -183,52 +300,6 @@ public class AbilityBackend implements Main {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins ticking player's action bars.
|
||||
*/
|
||||
public void startTickingBars() {
|
||||
Bukkit.getScheduler().runTaskTimer(main.getPlugin(),(task)->{
|
||||
for (Player player : Bukkit.getServer().getOnlinePlayers()) {
|
||||
tickActionBar(player);
|
||||
}
|
||||
},0,20);
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays the cooldown and info action bar for a player.
|
||||
* @param player the player to send actionbar to.
|
||||
*/
|
||||
public void tickActionBar(Player player) {
|
||||
AbstractAbility ability = getAbility(player);
|
||||
TrimMaterial material = getMaterial(player);
|
||||
if (ability == null || material == null) return;
|
||||
TrimPattern pattern = ability.getPattern();
|
||||
MaterialInfo materialInfo = ability.getAbilityInfo(material);
|
||||
|
||||
AbilityCooldown cooldownKey = new AbilityCooldown(player.getUniqueId(), pattern, material);
|
||||
int cooldownTicks = (materialInfo != null) ? materialInfo.cooldownTicks() : 0;
|
||||
|
||||
Component bar = Component.text("");
|
||||
|
||||
if (onCooldown.isOnCooldown(cooldownKey)) {
|
||||
long remainingMillis = onCooldown.getCooldown(cooldownKey);
|
||||
long totalDurationMillis = (long) cooldownTicks * 50L;
|
||||
long elapsedMillis = totalDurationMillis - remainingMillis;
|
||||
|
||||
elapsedMillis = Math.max(0, elapsedMillis);
|
||||
elapsedMillis = Math.min(totalDurationMillis, elapsedMillis);
|
||||
|
||||
bar = bar.append(Component.text("Ability Recharging: ", NamedTextColor.WHITE))
|
||||
.append(Text.color(Text.generateProgressBar(20, (int)totalDurationMillis, (int)elapsedMillis)));
|
||||
} else {
|
||||
bar = bar.append(Component.text("Ability Ready", NamedTextColor.namedColor(0x00FFAA)));
|
||||
}
|
||||
|
||||
bar = bar.append(Text.formatArgs(Text.Pallet.INFO," /info {0} for usage",Text.formatEnum(ValidPattern.validate(pattern))));
|
||||
|
||||
player.sendActionBar(bar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the formatted Component information message for a specific trim pattern's ability.
|
||||
* Includes overall pattern info and grouped material variant details.
|
||||
@@ -326,29 +397,35 @@ public class AbilityBackend implements Main {
|
||||
}
|
||||
|
||||
public enum ValidPattern {
|
||||
BOLT(TrimPattern.BOLT),
|
||||
COAST(TrimPattern.COAST),
|
||||
DUNE(TrimPattern.DUNE),
|
||||
EYE(TrimPattern.EYE),
|
||||
FLOW(TrimPattern.FLOW),
|
||||
HOST(TrimPattern.HOST),
|
||||
RAISER(TrimPattern.RAISER),
|
||||
RIB(TrimPattern.RIB),
|
||||
SENTRY(TrimPattern.SENTRY),
|
||||
SHAPER(TrimPattern.SHAPER),
|
||||
SILENCE(TrimPattern.SILENCE),
|
||||
SNOUT(TrimPattern.SNOUT),
|
||||
SPIRE(TrimPattern.SPIRE),
|
||||
TIDE(TrimPattern.TIDE),
|
||||
VEX(TrimPattern.VEX),
|
||||
WARD(TrimPattern.WARD),
|
||||
WAYFINDER(TrimPattern.WAYFINDER),
|
||||
WILD(TrimPattern.WILD);
|
||||
BOLT(TrimPattern.BOLT, Material.BOLT_ARMOR_TRIM_SMITHING_TEMPLATE),
|
||||
COAST(TrimPattern.COAST, Material.COAST_ARMOR_TRIM_SMITHING_TEMPLATE),
|
||||
DUNE(TrimPattern.DUNE, Material.DUNE_ARMOR_TRIM_SMITHING_TEMPLATE),
|
||||
EYE(TrimPattern.EYE, Material.EYE_ARMOR_TRIM_SMITHING_TEMPLATE),
|
||||
FLOW(TrimPattern.FLOW, Material.FLOW_ARMOR_TRIM_SMITHING_TEMPLATE),
|
||||
HOST(TrimPattern.HOST, Material.HOST_ARMOR_TRIM_SMITHING_TEMPLATE),
|
||||
RAISER(TrimPattern.RAISER, Material.RAISER_ARMOR_TRIM_SMITHING_TEMPLATE),
|
||||
RIB(TrimPattern.RIB, Material.RIB_ARMOR_TRIM_SMITHING_TEMPLATE),
|
||||
SENTRY(TrimPattern.SENTRY, Material.SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE),
|
||||
SHAPER(TrimPattern.SHAPER, Material.SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE),
|
||||
SILENCE(TrimPattern.SILENCE, Material.SILENCE_ARMOR_TRIM_SMITHING_TEMPLATE),
|
||||
SNOUT(TrimPattern.SNOUT, Material.SNOUT_ARMOR_TRIM_SMITHING_TEMPLATE),
|
||||
SPIRE(TrimPattern.SPIRE, Material.SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE),
|
||||
TIDE(TrimPattern.TIDE, Material.TIDE_ARMOR_TRIM_SMITHING_TEMPLATE),
|
||||
VEX(TrimPattern.VEX, Material.VEX_ARMOR_TRIM_SMITHING_TEMPLATE),
|
||||
WARD(TrimPattern.WARD, Material.WARD_ARMOR_TRIM_SMITHING_TEMPLATE),
|
||||
WAYFINDER(TrimPattern.WAYFINDER, Material.WAYFINDER_ARMOR_TRIM_SMITHING_TEMPLATE),
|
||||
WILD(TrimPattern.WILD, Material.WILD_ARMOR_TRIM_SMITHING_TEMPLATE);
|
||||
|
||||
private final TrimPattern canonical;
|
||||
private final Material material;
|
||||
|
||||
ValidPattern(TrimPattern canonical) {
|
||||
ValidPattern(TrimPattern canonical, Material material) {
|
||||
this.canonical = canonical;
|
||||
this.material = material;
|
||||
}
|
||||
|
||||
public Material getMaterial() {
|
||||
return material;
|
||||
}
|
||||
|
||||
public TrimPattern getCanonical() {
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package me.trouper.trimserver.server.systems;
|
||||
|
||||
import me.trouper.trimserver.server.Main;
|
||||
import me.trouper.trimserver.server.systems.abilities.AbstractAbility;
|
||||
import me.trouper.trimserver.server.systems.abilities.MaterialInfo;
|
||||
import me.trouper.trimserver.utils.text.Text;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.meta.trim.TrimMaterial;
|
||||
import org.bukkit.inventory.meta.trim.TrimPattern;
|
||||
|
||||
public class PollingBackend implements Main {
|
||||
/**
|
||||
* Begins per-player polling
|
||||
*/
|
||||
public void startPolling() {
|
||||
Bukkit.getScheduler().runTaskTimer(main.getPlugin(),(task)->{
|
||||
for (Player player : Bukkit.getServer().getOnlinePlayers()) {
|
||||
tickActionBar(player);
|
||||
tickPlaceholders(player);
|
||||
}
|
||||
},0,20);
|
||||
}
|
||||
|
||||
public void tickPlaceholders(Player player) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays the cooldown and info action bar for a player.
|
||||
* @param player the player to send actionbar to.
|
||||
*/
|
||||
public void tickActionBar(Player player) {
|
||||
AbstractAbility ability = main.man().abilityBackend.getAbility(player);
|
||||
TrimMaterial material = main.man().abilityBackend.getMaterial(player);
|
||||
if (ability == null || material == null) return;
|
||||
TrimPattern pattern = ability.getPattern();
|
||||
MaterialInfo materialInfo = ability.getAbilityInfo(material);
|
||||
|
||||
AbilityBackend.AbilityCooldown cooldownKey = new AbilityBackend.AbilityCooldown(player.getUniqueId(), pattern, material);
|
||||
int cooldownTicks = (materialInfo != null) ? materialInfo.cooldownTicks() : 0;
|
||||
|
||||
Component bar = Component.text("");
|
||||
|
||||
if (main.man().abilityBackend.getCooldowns().isOnCooldown(cooldownKey)) {
|
||||
long remainingMillis = main.man().abilityBackend.getCooldowns().getCooldown(cooldownKey);
|
||||
long totalDurationMillis = (long) cooldownTicks * 50L;
|
||||
long elapsedMillis = totalDurationMillis - remainingMillis;
|
||||
|
||||
elapsedMillis = Math.max(0, elapsedMillis);
|
||||
elapsedMillis = Math.min(totalDurationMillis, elapsedMillis);
|
||||
|
||||
bar = bar.append(Component.text("Ability Recharging: ", NamedTextColor.WHITE))
|
||||
.append(Text.color(Text.generateProgressBar(20, (int)totalDurationMillis, (int)elapsedMillis)));
|
||||
} else {
|
||||
bar = bar.append(Component.text("Ability Ready", NamedTextColor.namedColor(0x00FFAA)));
|
||||
}
|
||||
|
||||
bar = bar.append(Text.formatArgs(Text.Pallet.INFO," /info {0} for usage",Text.formatEnum(AbilityBackend.ValidPattern.validate(pattern))));
|
||||
|
||||
player.sendActionBar(bar);
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,8 @@ import io.papermc.paper.registry.RegistryAccess;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import me.trouper.trimserver.server.Main;
|
||||
import me.trouper.trimserver.server.events.QuickListener;
|
||||
import me.trouper.trimserver.utils.Text;
|
||||
import me.trouper.trimserver.server.systems.AbilityBackend;
|
||||
import me.trouper.trimserver.utils.text.Text;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -101,25 +102,20 @@ public abstract class AbstractAbility implements Main, QuickListener {
|
||||
* @return true if the ability was successfully executed and should apply cooldown,
|
||||
* false if the ability failed or otherwise shouldn't trigger cooldown.
|
||||
*/
|
||||
public final boolean dispatchAbility(TrimMaterial material, Player player) {
|
||||
String methodName = getMethodNameForMaterial(material);
|
||||
if (methodName == null) {
|
||||
main.getPlugin().getLogger().warning("Attempted to dispatch for unknown material: " + main.getRegistryAccess().getRegistry(RegistryKey.TRIM_MATERIAL).getKey(material).getKey());
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
Method abilityMethod = this.getClass().getMethod(methodName, Player.class);
|
||||
Object result = abilityMethod.invoke(this, player);
|
||||
return (result instanceof Boolean) ? (Boolean) result : true;
|
||||
} catch (NoSuchMethodException e) {
|
||||
main.getPlugin().getLogger().warning("Method " + methodName + " not found in " + this.getClass().getSimpleName() + " for dispatch.");
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
main.getPlugin().getLogger().severe("Error dispatching ability method " + methodName + " for pattern " + getPatternName() + ": " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
public final boolean dispatchAbility(AbilityBackend.ValidMaterial material, Player player) {
|
||||
return switch (material) {
|
||||
case AMETHYST -> amethystAbility(player);
|
||||
case COPPER -> copperAbility(player);
|
||||
case DIAMOND -> diamondAbility(player);
|
||||
case EMERALD -> emeraldAbility(player);
|
||||
case GOLD -> goldAbility(player);
|
||||
case IRON -> ironAbility(player);
|
||||
case LAPIS -> lapisAbility(player);
|
||||
case NETHERITE -> netheriteAbility(player);
|
||||
case QUARTZ -> quartzAbility(player);
|
||||
case REDSTONE -> redstoneAbility(player);
|
||||
case RESIN -> resinAbility(player);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package me.trouper.trimserver.server.systems.abilities;
|
||||
|
||||
import me.trouper.trimserver.utils.Text;
|
||||
import me.trouper.trimserver.utils.text.Text;
|
||||
import me.trouper.trimserver.utils.Verbose;
|
||||
import me.trouper.trimserver.utils.visual.BlockDisplayRaytracer;
|
||||
import org.bukkit.*;
|
||||
@@ -38,7 +38,7 @@ public class WormEvent {
|
||||
private static final Material WORM_TEETH_MATERIAL = Material.DRIPSTONE_BLOCK;
|
||||
private static final int TICKS_PER_SECOND = 5; // Standard Minecraft ticks per second
|
||||
private static final double TEETH_CLOSE_FACTOR = 1; // How far teeth move inwards (fraction of radius, 0.0 to 1.0)
|
||||
private static final double DAMAGE_AMOUNT = 19; // Damage dealt by the worm's bite
|
||||
private static final double DAMAGE_AMOUNT = 90; // Damage dealt by the worm's bite
|
||||
private static final float BITE_SOUND_VOLUME = 2.0f;
|
||||
private static final float BITE_SOUND_PITCH_GROWL = 0.5f;
|
||||
private static final float BITE_SOUND_PITCH_GRIND = 0.1f;
|
||||
|
||||
@@ -6,14 +6,13 @@ import me.trouper.trimserver.server.systems.abilities.AbstractAbility;
|
||||
import me.trouper.trimserver.server.systems.abilities.PatternInfo;
|
||||
import me.trouper.trimserver.utils.SoundPlayer;
|
||||
import me.trouper.trimserver.utils.TargetingUtils;
|
||||
import me.trouper.trimserver.utils.Text;
|
||||
import me.trouper.trimserver.utils.text.Text;
|
||||
import me.trouper.trimserver.utils.visual.BlockDisplayRaytracer;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.damage.DamageSource;
|
||||
import org.bukkit.damage.DamageType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.meta.trim.TrimPattern;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -22,11 +21,20 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@PatternInfo(name = "Bolt", description = "Summon a bolt of lightning at enemies. Includes Variants.")
|
||||
public class BoltAbility extends AbstractAbility implements Main {
|
||||
|
||||
public static final int NORMAL_COOLDOWN = 20 * 10;
|
||||
public static final double NORMAL_DAMAGE = 10;
|
||||
|
||||
public static final int RESIN_COOLDOWN = 20 * 5;
|
||||
public static final double RESIN_DAMAGE = 7;
|
||||
|
||||
public static final int NETHERITE_COOLDOWN = 20 * 15;
|
||||
public static final double NETHERITE_DAMAGE = 20;
|
||||
|
||||
public BoltAbility() {
|
||||
super(TrimPattern.BOLT);
|
||||
}
|
||||
|
||||
|
||||
public boolean strike(Player caster, int range, double damage, Material innerBlock, Material outerBlock) {
|
||||
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
|
||||
ShaperAbility shaper = (ShaperAbility) shaperInstance;
|
||||
@@ -36,7 +44,7 @@ public class BoltAbility extends AbstractAbility implements Main {
|
||||
main.man().abilityBackend.abilityAllowed(caster,target.getLocation()),(target) ->{
|
||||
drawLightning(caster.getEyeLocation(),target.getEyeLocation(),innerBlock,outerBlock);
|
||||
target.damage(damage,DamageSource.builder(DamageType.LIGHTNING_BOLT).withDamageLocation(caster.getEyeLocation()).withDirectEntity(caster).build());
|
||||
if (target instanceof Player t) Text.sendMessage(Text.Pallet.INFO,t,"You have been stunned by {0}'s Bolt!",caster.name());
|
||||
if (target instanceof Player t) Text.sendMessage(Text.Pallet.INFO,t,"You have been stunned by {0}'s Bolt!",caster.getName());
|
||||
|
||||
AtomicInteger counter = new AtomicInteger(0);
|
||||
Bukkit.getScheduler().runTaskTimer(main.getPlugin(),(task) -> {
|
||||
@@ -96,69 +104,69 @@ public class BoltAbility extends AbstractAbility implements Main {
|
||||
BlockDisplayRaytracer.trace(blockOuter, current, end, thicknessOut, stayTime, viewers);
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Amethyst Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 10 Damage", cooldownTicks = 20*10)
|
||||
@MaterialInfo(name = "Amethyst Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 10 Damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean amethystAbility(Player player) {
|
||||
return strike(player,20,10,Material.AMETHYST_BLOCK,Material.PURPLE_STAINED_GLASS);
|
||||
return strike(player,20,NORMAL_DAMAGE,Material.AMETHYST_BLOCK,Material.PURPLE_STAINED_GLASS);
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Copper Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 10 Damage", cooldownTicks = 20*10)
|
||||
@MaterialInfo(name = "Copper Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 10 Damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean copperAbility(Player player) {
|
||||
return strike(player,20,10,Material.ORANGE_TERRACOTTA,Material.ORANGE_STAINED_GLASS);
|
||||
return strike(player,20,NORMAL_DAMAGE,Material.ORANGE_TERRACOTTA,Material.ORANGE_STAINED_GLASS);
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Diamond Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 10 Damage", cooldownTicks = 20*10)
|
||||
@MaterialInfo(name = "Diamond Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 10 Damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean diamondAbility(Player player) {
|
||||
return strike(player,20,10,Material.LIGHT_BLUE_CONCRETE_POWDER,Material.LIGHT_BLUE_STAINED_GLASS);
|
||||
return strike(player,20,NORMAL_DAMAGE,Material.LIGHT_BLUE_CONCRETE_POWDER,Material.LIGHT_BLUE_STAINED_GLASS);
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Emerald ",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 10 Damage", cooldownTicks = 20*10)
|
||||
@MaterialInfo(name = "Emerald ",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 10 Damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean emeraldAbility(Player player) {
|
||||
return strike(player,20,10,Material.LIME_CONCRETE,Material.LIME_STAINED_GLASS);
|
||||
return strike(player,20,NORMAL_DAMAGE,Material.LIME_CONCRETE,Material.LIME_STAINED_GLASS);
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Gold Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 10 Damage", cooldownTicks = 20*10)
|
||||
@MaterialInfo(name = "Gold Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 10 Damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean goldAbility(Player player) {
|
||||
return strike(player,20,10,Material.YELLOW_CONCRETE_POWDER,Material.YELLOW_STAINED_GLASS);
|
||||
return strike(player,20,NORMAL_DAMAGE,Material.YELLOW_CONCRETE_POWDER,Material.YELLOW_STAINED_GLASS);
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Iron Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 10 Damage", cooldownTicks = 20*10)
|
||||
@MaterialInfo(name = "Iron Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 10 Damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean ironAbility(Player player) {
|
||||
return strike(player,20,10,Material.LIGHT_GRAY_WOOL,Material.LIGHT_GRAY_STAINED_GLASS);
|
||||
return strike(player,20,NORMAL_DAMAGE,Material.LIGHT_GRAY_WOOL,Material.LIGHT_GRAY_STAINED_GLASS);
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Lapis Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 10 Damage", cooldownTicks = 20*10)
|
||||
@MaterialInfo(name = "Lapis Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 10 Damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean lapisAbility(Player player) {
|
||||
return strike(player,20,10,Material.BLUE_CONCRETE,Material.BLUE_STAINED_GLASS);
|
||||
return strike(player,20,NORMAL_DAMAGE,Material.BLUE_CONCRETE,Material.BLUE_STAINED_GLASS);
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Netherite Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 15 Damage", cooldownTicks = 20*10)
|
||||
@MaterialInfo(name = "Netherite Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 15 Damage", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@Override
|
||||
public boolean netheriteAbility(Player player) {
|
||||
return strike(player,30,15,Material.BLACK_CONCRETE,Material.GRAY_STAINED_GLASS);
|
||||
return strike(player,30,NETHERITE_DAMAGE,Material.BLACK_CONCRETE,Material.GRAY_STAINED_GLASS);
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Quartz Bolt",description = "Shoots a bolt of overcharged lightning at your closest enemy within 20 blocks. Deals 15 Damage", cooldownTicks = 20*12)
|
||||
@MaterialInfo(name = "Quartz Bolt",description = "Shoots a bolt of overcharged lightning at your closest enemy within 20 blocks. Deals 15 Damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean quartzAbility(Player player) {
|
||||
return strike(player,20,10,Material.WHITE_CONCRETE,Material.WHITE_STAINED_GLASS);
|
||||
return strike(player,20,NORMAL_DAMAGE,Material.WHITE_CONCRETE,Material.WHITE_STAINED_GLASS);
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Redstone Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 10 Damage", cooldownTicks = 20*10)
|
||||
@MaterialInfo(name = "Redstone Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 10 Damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean redstoneAbility(Player player) {
|
||||
return strike(player,20,10,Material.RED_CONCRETE_POWDER,Material.RED_STAINED_GLASS);
|
||||
return strike(player,20,NORMAL_DAMAGE,Material.RED_CONCRETE_POWDER,Material.RED_STAINED_GLASS);
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Resin Bolt",description = "Shoots a bolt of resin lightning at your closest enemy within 20 blocks. Deals 7 Damage", cooldownTicks = 20*5)
|
||||
@MaterialInfo(name = "Resin Bolt",description = "Shoots a bolt of resin lightning at your closest enemy within 20 blocks. Deals 7 Damage", cooldownTicks = RESIN_COOLDOWN)
|
||||
@Override
|
||||
public boolean resinAbility(Player player) {
|
||||
return strike(player,20,7,Material.RESIN_BLOCK,Material.ORANGE_STAINED_GLASS);
|
||||
return strike(player,20,RESIN_DAMAGE,Material.RESIN_BLOCK,Material.ORANGE_STAINED_GLASS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import me.trouper.trimserver.server.systems.abilities.PatternInfo;
|
||||
import me.trouper.trimserver.server.systems.abilities.AbstractAbility;
|
||||
import me.trouper.trimserver.utils.SoundPlayer;
|
||||
import me.trouper.trimserver.utils.TargetingUtils;
|
||||
import me.trouper.trimserver.utils.text.CustomBossBar;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -25,32 +26,28 @@ public class CoastAbility extends AbstractAbility {
|
||||
|
||||
private final Map<UUID, BukkitTask> activeUndertoes = new ConcurrentHashMap<>();
|
||||
|
||||
private static final double BASE_UNDERTOE_RADIUS = 5.5;
|
||||
private static final int BASE_UNDERTOE_DURATION_TICKS = 10 * 20;
|
||||
private static final double BASE_PULL_STRENGTH = 0.18;
|
||||
private static final double BASE_DAMAGE_PER_SECOND = 2.0;
|
||||
private static final double NORMAL_RADIUS = 5.5;
|
||||
private static final int NORMAL_DURATION = 10 * 20;
|
||||
private static final double NORMAL_PULL_STRENGTH = 0.18;
|
||||
private static final double NORMAL_DAMAGE_PER_SECOND = 2.0;
|
||||
|
||||
// Cooldowns
|
||||
private static final int DEFAULT_COOLDOWN = 20 * 45;
|
||||
private static final int NETHERITE_COOLDOWN = 20 * 60;
|
||||
private static final int RESIN_COOLDOWN = 20 * 25;
|
||||
|
||||
// Netherite Modifiers
|
||||
private static final double NETHERITE_RADIUS_MULTIPLIER = 1.25;
|
||||
private static final double NETHERITE_DURATION_MULTIPLIER = 1.5;
|
||||
private static final double NETHERITE_DAMAGE_MULTIPLIER = 1.5;
|
||||
private static final double NETHERITE_PULL_MULTIPLIER = 1.3;
|
||||
private static final int NETHERITE_SLOWNESS_AMPLIFIER = 2;
|
||||
|
||||
|
||||
// Resin Modifiers
|
||||
private static final double RESIN_DAMAGE_MULTIPLIER = 0.8;
|
||||
|
||||
|
||||
public CoastAbility() {
|
||||
super(TrimPattern.COAST);
|
||||
}
|
||||
|
||||
private void createUndertoe(Player player, Material material) {
|
||||
private void createUndertoe(Player player, Material material, double radius, double pullStrength, double damagePerSecond, int duration) {
|
||||
UUID playerUUID = player.getUniqueId();
|
||||
|
||||
if (activeUndertoes.containsKey(playerUUID)) {
|
||||
@@ -73,30 +70,15 @@ public class CoastAbility extends AbstractAbility {
|
||||
|
||||
if (world == null) return;
|
||||
|
||||
double currentRadius = BASE_UNDERTOE_RADIUS;
|
||||
int currentDuration = BASE_UNDERTOE_DURATION_TICKS;
|
||||
double currentDamage = BASE_DAMAGE_PER_SECOND;
|
||||
double currentPullStrength = BASE_PULL_STRENGTH;
|
||||
int slownessAmplifier = 1;
|
||||
|
||||
if (material == Material.NETHERITE_BLOCK) {
|
||||
currentRadius *= NETHERITE_RADIUS_MULTIPLIER;
|
||||
currentDuration = (int) (currentDuration * NETHERITE_DURATION_MULTIPLIER);
|
||||
currentDamage *= NETHERITE_DAMAGE_MULTIPLIER;
|
||||
currentPullStrength *= NETHERITE_PULL_MULTIPLIER;
|
||||
slownessAmplifier = NETHERITE_SLOWNESS_AMPLIFIER;
|
||||
} else if (material == Material.RESIN_BLOCK) {
|
||||
currentDamage *= RESIN_DAMAGE_MULTIPLIER;
|
||||
}
|
||||
|
||||
new SoundPlayer(centerLocation, Sound.ENTITY_PLAYER_SPLASH_HIGH_SPEED, 1.2f, 0.8f).playWithin(30);
|
||||
new SoundPlayer(centerLocation, Sound.BLOCK_WATER_AMBIENT, 1.0f, 0.5f).playWithin(30);
|
||||
|
||||
final double finalRadius = currentRadius;
|
||||
final int finalDuration = currentDuration;
|
||||
final double finalDamage = currentDamage;
|
||||
final double finalPullStrength = currentPullStrength;
|
||||
final int finalSlownessAmplifier = slownessAmplifier;
|
||||
final double finalRadius = radius;
|
||||
final int finalDuration = duration;
|
||||
final double finalDamage = damagePerSecond;
|
||||
final double finalPullStrength = pullStrength;
|
||||
final int finalSlownessAmplifier = 1;
|
||||
CustomBossBar.showBossBar(main.getPlugin(),player,"Undertoe",finalDuration);
|
||||
|
||||
BukkitTask task = new BukkitRunnable() {
|
||||
int ticksElapsed = 0;
|
||||
@@ -184,77 +166,77 @@ public class CoastAbility extends AbstractAbility {
|
||||
@MaterialInfo(name = "Amethyst Undertoe", description = "A swirling vortex pulls and drowns foes.", cooldownTicks = DEFAULT_COOLDOWN)
|
||||
@Override
|
||||
public boolean amethystAbility(Player player) {
|
||||
createUndertoe(player, Material.AMETHYST_BLOCK);
|
||||
createUndertoe(player, Material.AMETHYST_BLOCK, NORMAL_RADIUS, NORMAL_PULL_STRENGTH, NORMAL_DAMAGE_PER_SECOND,NORMAL_DURATION);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Copper Undertoe", description = "A swirling vortex pulls and drowns foes.", cooldownTicks = DEFAULT_COOLDOWN)
|
||||
@Override
|
||||
public boolean copperAbility(Player player) {
|
||||
createUndertoe(player, Material.COPPER_BLOCK);
|
||||
createUndertoe(player, Material.AMETHYST_BLOCK, NORMAL_RADIUS, NORMAL_PULL_STRENGTH, NORMAL_DAMAGE_PER_SECOND,NORMAL_DURATION);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Diamond Undertoe", description = "A swirling vortex pulls and drowns foes.", cooldownTicks = DEFAULT_COOLDOWN)
|
||||
@Override
|
||||
public boolean diamondAbility(Player player) {
|
||||
createUndertoe(player, Material.DIAMOND_BLOCK);
|
||||
createUndertoe(player, Material.AMETHYST_BLOCK, NORMAL_RADIUS, NORMAL_PULL_STRENGTH, NORMAL_DAMAGE_PER_SECOND,NORMAL_DURATION);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Emerald Undertoe", description = "A swirling vortex pulls and drowns foes.", cooldownTicks = DEFAULT_COOLDOWN)
|
||||
@Override
|
||||
public boolean emeraldAbility(Player player) {
|
||||
createUndertoe(player, Material.EMERALD_BLOCK);
|
||||
createUndertoe(player, Material.AMETHYST_BLOCK, NORMAL_RADIUS, NORMAL_PULL_STRENGTH, NORMAL_DAMAGE_PER_SECOND,NORMAL_DURATION);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Gold Undertoe", description = "A swirling vortex pulls and drowns foes.", cooldownTicks = DEFAULT_COOLDOWN)
|
||||
@Override
|
||||
public boolean goldAbility(Player player) {
|
||||
createUndertoe(player, Material.GOLD_BLOCK);
|
||||
createUndertoe(player, Material.AMETHYST_BLOCK, NORMAL_RADIUS, NORMAL_PULL_STRENGTH, NORMAL_DAMAGE_PER_SECOND,NORMAL_DURATION);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Iron Undertoe", description = "A swirling vortex pulls and drowns foes.", cooldownTicks = DEFAULT_COOLDOWN)
|
||||
@Override
|
||||
public boolean ironAbility(Player player) {
|
||||
createUndertoe(player, Material.IRON_BLOCK);
|
||||
createUndertoe(player, Material.AMETHYST_BLOCK, NORMAL_RADIUS, NORMAL_PULL_STRENGTH, NORMAL_DAMAGE_PER_SECOND,NORMAL_DURATION);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Lapis Undertoe", description = "A swirling vortex pulls and drowns foes.", cooldownTicks = DEFAULT_COOLDOWN)
|
||||
@Override
|
||||
public boolean lapisAbility(Player player) {
|
||||
createUndertoe(player, Material.LAPIS_BLOCK);
|
||||
createUndertoe(player, Material.AMETHYST_BLOCK, NORMAL_RADIUS, NORMAL_PULL_STRENGTH, NORMAL_DAMAGE_PER_SECOND,NORMAL_DURATION);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Netherite Undertoe", description = "A larger, stronger, and longer-lasting vortex that fiercely pulls, damages, and disorients foes.", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@Override
|
||||
public boolean netheriteAbility(Player player) {
|
||||
createUndertoe(player, Material.NETHERITE_BLOCK);
|
||||
createUndertoe(player, Material.AMETHYST_BLOCK, NORMAL_RADIUS * NETHERITE_RADIUS_MULTIPLIER, NORMAL_PULL_STRENGTH * NETHERITE_PULL_MULTIPLIER, NORMAL_DAMAGE_PER_SECOND * NETHERITE_DAMAGE_MULTIPLIER, (int) (NORMAL_DURATION * NETHERITE_DURATION_MULTIPLIER));
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Quartz Undertoe", description = "A swirling vortex pulls and drowns foes.", cooldownTicks = DEFAULT_COOLDOWN)
|
||||
@Override
|
||||
public boolean quartzAbility(Player player) {
|
||||
createUndertoe(player, Material.QUARTZ_BLOCK);
|
||||
createUndertoe(player, Material.AMETHYST_BLOCK, NORMAL_RADIUS, NORMAL_PULL_STRENGTH, NORMAL_DAMAGE_PER_SECOND,NORMAL_DURATION);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Redstone Undertoe", description = "A swirling vortex pulls and drowns foes.", cooldownTicks = DEFAULT_COOLDOWN)
|
||||
@Override
|
||||
public boolean redstoneAbility(Player player) {
|
||||
createUndertoe(player, Material.REDSTONE_BLOCK);
|
||||
createUndertoe(player, Material.AMETHYST_BLOCK, NORMAL_RADIUS, NORMAL_PULL_STRENGTH, NORMAL_DAMAGE_PER_SECOND,NORMAL_DURATION);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Resin Undertoe", description = "A slightly weaker vortex that pulls and drowns foes, but recharges faster.", cooldownTicks = RESIN_COOLDOWN)
|
||||
@Override
|
||||
public boolean resinAbility(Player player) {
|
||||
createUndertoe(player, Material.RESIN_BLOCK);
|
||||
createUndertoe(player, Material.AMETHYST_BLOCK, NORMAL_RADIUS, NORMAL_PULL_STRENGTH, NORMAL_DAMAGE_PER_SECOND * RESIN_DAMAGE_MULTIPLIER,NORMAL_DURATION);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import me.trouper.trimserver.server.systems.abilities.PatternInfo;
|
||||
import me.trouper.trimserver.server.systems.abilities.WormEvent;
|
||||
import me.trouper.trimserver.utils.PlayerUtils;
|
||||
import me.trouper.trimserver.utils.TargetingUtils;
|
||||
import me.trouper.trimserver.utils.Text;
|
||||
import me.trouper.trimserver.utils.text.Text;
|
||||
import me.trouper.trimserver.utils.visual.DisplayUtils;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
@@ -25,11 +25,26 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
@PatternInfo(name = "Eye of Power", description = "Allows you to see players hidden with the host trim. Includes variants.")
|
||||
public class EyeAbility extends AbstractAbility {
|
||||
|
||||
public static final int NORMAL_COOLDOWN = 20 * 30;
|
||||
public static final int NORMAL_DURATION = 5;
|
||||
public static final double NORMAL_DAMAGE = 0.1;
|
||||
public static final double NORMAL_DAMAGE_FAIL_CHANCE = 0.75;
|
||||
|
||||
public static final int NETHERITE_COOLDOWN = 20 * 15;
|
||||
public static final int NETHERITE_DURATION = 10;
|
||||
public static final double NETHERITE_DAMAGE = 0.2;
|
||||
public static final double NETHERITE_DAMAGE_FAIL_CHANCE = 0.50;
|
||||
|
||||
public static final int RESIN_COOLDOWN = 20 * 10;
|
||||
public static final long RESIN_DURATION = 3;
|
||||
public static final double RESIN_DAMAGE = 0.1;
|
||||
public static final double RESIN_DAMAGE_FAIL_CHANCE = 0.80;
|
||||
|
||||
public EyeAbility() {
|
||||
super(TrimPattern.EYE);
|
||||
}
|
||||
|
||||
public void eyeLasers(Player player, Material beam,Material glow, long durationSeconds) {
|
||||
public void eyeLasers(Player player, Material beam,Material glow, long durationSeconds, double damagePerTick, double damageFailChance) {
|
||||
AtomicInteger timer = new AtomicInteger(0);
|
||||
Bukkit.getScheduler().runTaskTimer(main.getPlugin(),(task)->{
|
||||
if (timer.getAndIncrement() >= durationSeconds * 20) {
|
||||
@@ -42,11 +57,10 @@ public class EyeAbility extends AbstractAbility {
|
||||
Vector eyeCenter = headLocation.getDirection();
|
||||
Vector leftRight = new Vector(-eyeCenter.getZ(), 0, eyeCenter.getX()).normalize().multiply(0.2);
|
||||
|
||||
// Two eye locations
|
||||
Location leftEye = headLocation.clone().add(leftRight);
|
||||
Location rightEye = headLocation.clone().subtract(leftRight);
|
||||
|
||||
Location focus = laser(player,headLocation,eyeCenter,60);
|
||||
Location focus = laser(player,headLocation,eyeCenter,60,damagePerTick,damageFailChance);
|
||||
|
||||
BlockDisplayRaytracer.trace(beam,leftEye,focus,0.05,2);
|
||||
BlockDisplayRaytracer.trace(glow,leftEye,focus,0.1,2);
|
||||
@@ -56,7 +70,7 @@ public class EyeAbility extends AbstractAbility {
|
||||
},0,1);
|
||||
}
|
||||
|
||||
public Location laser(Player owner, Location start, Vector direction, double distance) {
|
||||
public Location laser(Player owner, Location start, Vector direction, double distance, double damagePerTick, double damageFailChance) {
|
||||
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
|
||||
ShaperAbility shaper = (ShaperAbility) shaperInstance;
|
||||
|
||||
@@ -73,13 +87,16 @@ public class EyeAbility extends AbstractAbility {
|
||||
if (!(entity instanceof LivingEntity liv) || shaper.activeShellTasks.containsKey(liv.getUniqueId())) return;
|
||||
hissSound.playWithin(30);
|
||||
|
||||
int tick = liv.getNoDamageTicks();
|
||||
int maxTick = liv.getMaximumNoDamageTicks();
|
||||
liv.setNoDamageTicks(0);
|
||||
liv.setMaximumNoDamageTicks(0);
|
||||
liv.damage(0.1,DamageSource.builder(DamageType.STING).withDamageLocation(owner.getLocation()).withDirectEntity(owner).build());
|
||||
liv.setNoDamageTicks(tick);
|
||||
liv.setMaximumNoDamageTicks(maxTick);
|
||||
if (random.nextDouble(1) >= damageFailChance) {
|
||||
int tick = liv.getNoDamageTicks();
|
||||
int maxTick = liv.getMaximumNoDamageTicks();
|
||||
|
||||
liv.setNoDamageTicks(0);
|
||||
liv.setMaximumNoDamageTicks(0);
|
||||
liv.damage(damagePerTick,DamageSource.builder(DamageType.STING).withDamageLocation(owner.getLocation()).withDirectEntity(owner).build());
|
||||
liv.setNoDamageTicks(tick);
|
||||
liv.setMaximumNoDamageTicks(maxTick);
|
||||
}
|
||||
|
||||
liv.setFireTicks(20);
|
||||
liv.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS,20,1,true,false,false));
|
||||
@@ -94,80 +111,80 @@ public class EyeAbility extends AbstractAbility {
|
||||
}).getLoc();
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Amethyst Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Amethyst Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean amethystAbility(Player player) {
|
||||
eyeLasers(player,Material.PURPLE_CONCRETE_POWDER,Material.MAGENTA_STAINED_GLASS,5);
|
||||
eyeLasers(player,Material.PURPLE_CONCRETE_POWDER,Material.MAGENTA_STAINED_GLASS,NORMAL_DURATION,NORMAL_DAMAGE,NORMAL_DAMAGE_FAIL_CHANCE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Copper Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Copper Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean copperAbility(Player player) {
|
||||
eyeLasers(player,Material.LIME_TERRACOTTA,Material.GREEN_STAINED_GLASS,5);
|
||||
eyeLasers(player,Material.LIME_TERRACOTTA,Material.GREEN_STAINED_GLASS,NORMAL_DURATION,NORMAL_DAMAGE,NORMAL_DAMAGE_FAIL_CHANCE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Diamond Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Diamond Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean diamondAbility(Player player) {
|
||||
eyeLasers(player,Material.LIGHT_BLUE_CONCRETE_POWDER,Material.LIGHT_BLUE_STAINED_GLASS,5);
|
||||
eyeLasers(player,Material.LIGHT_BLUE_CONCRETE_POWDER,Material.LIGHT_BLUE_STAINED_GLASS,NORMAL_DURATION,NORMAL_DAMAGE,NORMAL_DAMAGE_FAIL_CHANCE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Emerald Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Emerald Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean emeraldAbility(Player player) {
|
||||
eyeLasers(player,Material.LIME_CONCRETE_POWDER,Material.LIME_STAINED_GLASS,5);
|
||||
eyeLasers(player,Material.LIME_CONCRETE_POWDER,Material.LIME_STAINED_GLASS,NORMAL_DURATION,NORMAL_DAMAGE,NORMAL_DAMAGE_FAIL_CHANCE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Gold Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Gold Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean goldAbility(Player player) {
|
||||
eyeLasers(player,Material.YELLOW_TERRACOTTA,Material.YELLOW_STAINED_GLASS,5);
|
||||
eyeLasers(player,Material.YELLOW_TERRACOTTA,Material.YELLOW_STAINED_GLASS,NORMAL_DURATION,NORMAL_DAMAGE,NORMAL_DAMAGE_FAIL_CHANCE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Iron Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Iron Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean ironAbility(Player player) {
|
||||
eyeLasers(player,Material.LIGHT_GRAY_CONCRETE_POWDER,Material.LIGHT_GRAY_STAINED_GLASS,5);
|
||||
eyeLasers(player,Material.LIGHT_GRAY_CONCRETE_POWDER,Material.LIGHT_GRAY_STAINED_GLASS,NORMAL_DURATION,NORMAL_DAMAGE,NORMAL_DAMAGE_FAIL_CHANCE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Lapis Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Lapis Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean lapisAbility(Player player) {
|
||||
eyeLasers(player,Material.BLUE_CONCRETE,Material.BLUE_STAINED_GLASS,5);
|
||||
eyeLasers(player,Material.BLUE_CONCRETE,Material.BLUE_STAINED_GLASS,NORMAL_DURATION,NORMAL_DAMAGE,NORMAL_DAMAGE_FAIL_CHANCE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Netherite Laser beam", description = "Shoot lasers from the eye on the chestpiece for 10 seconds", cooldownTicks = 20 * 40)
|
||||
@MaterialInfo(name = "Netherite Laser beam", description = "Shoot lasers from the eye on the chestpiece for 10 seconds", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@Override
|
||||
public boolean netheriteAbility(Player player) {
|
||||
eyeLasers(player,Material.BLACK_CONCRETE,Material.BLACK_STAINED_GLASS,20);
|
||||
eyeLasers(player,Material.BLACK_CONCRETE,Material.BLACK_STAINED_GLASS,NETHERITE_DURATION,NETHERITE_DAMAGE,NETHERITE_DAMAGE_FAIL_CHANCE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Quartz Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Quartz Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean quartzAbility(Player player) {
|
||||
eyeLasers(player,Material.WHITE_CONCRETE_POWDER,Material.WHITE_STAINED_GLASS,5);
|
||||
eyeLasers(player,Material.WHITE_CONCRETE_POWDER,Material.WHITE_STAINED_GLASS,NORMAL_DURATION,NORMAL_DAMAGE,NORMAL_DAMAGE_FAIL_CHANCE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Redstone Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Redstone Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean redstoneAbility(Player player) {
|
||||
eyeLasers(player,Material.RED_CONCRETE,Material.RED_STAINED_GLASS,5);
|
||||
eyeLasers(player,Material.RED_CONCRETE,Material.RED_STAINED_GLASS,NORMAL_DURATION,NORMAL_DAMAGE,NORMAL_DAMAGE_FAIL_CHANCE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Resin Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Resin Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = RESIN_COOLDOWN)
|
||||
@Override
|
||||
public boolean resinAbility(Player player) {
|
||||
eyeLasers(player,Material.ORANGE_CONCRETE_POWDER,Material.ORANGE_STAINED_GLASS,5);
|
||||
eyeLasers(player,Material.ORANGE_CONCRETE_POWDER,Material.ORANGE_STAINED_GLASS,RESIN_DURATION,RESIN_DAMAGE,RESIN_DAMAGE_FAIL_CHANCE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@ import me.trouper.trimserver.server.systems.abilities.PatternInfo;
|
||||
import me.trouper.trimserver.server.systems.abilities.AbstractAbility;
|
||||
import me.trouper.trimserver.utils.SoundPlayer;
|
||||
import me.trouper.trimserver.utils.TargetingUtils;
|
||||
import me.trouper.trimserver.utils.Text;
|
||||
import me.trouper.trimserver.utils.text.CustomBossBar;
|
||||
import me.trouper.trimserver.utils.text.Text;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@@ -24,6 +25,22 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
@PatternInfo(name = "Wind Rider", description = "Summon a breeze to ride through the sky")
|
||||
public class FlowAbility extends AbstractAbility {
|
||||
|
||||
public static final int NORMAL_COOLDOWN = 20 * 50;
|
||||
public static final int NORMAL_DURATION = 30;
|
||||
public static final double NORMAL_HEALTH = 10;
|
||||
public static final double NORMAL_LAUNCH_STRENGTH = 1;
|
||||
|
||||
public static final int NETHERITE_COOLDOWN = 20 * 90;
|
||||
public static final int NETHERITE_DURATION = 45;
|
||||
public static final double NETHERITE_HEALTH = 20;
|
||||
public static final double NETHERITE_LAUNCH_STRENGTH = 2;
|
||||
|
||||
public static final int RESIN_COOLDOWN = 20 * 30;
|
||||
public static final int RESIN_DURATION = 20;
|
||||
public static final double RESIN_HEALTH = 5;
|
||||
public static final double RESIN_LAUNCH_STRENGTH = 0.7;
|
||||
|
||||
|
||||
private final Map<UUID, BukkitTask> activeRiders = new HashMap<>();
|
||||
private final Map<UUID, Breeze> activeBreezes = new HashMap<>();
|
||||
|
||||
@@ -31,7 +48,7 @@ public class FlowAbility extends AbstractAbility {
|
||||
super(TrimPattern.FLOW);
|
||||
}
|
||||
|
||||
private void spawnRideableBreeze(Player player, int duration, Material material) {
|
||||
private void spawnRideableBreeze(Player player, int duration, Material material, double launchStrength, double health) {
|
||||
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
|
||||
ShaperAbility shaper = (ShaperAbility) shaperInstance;
|
||||
|
||||
@@ -53,7 +70,7 @@ public class FlowAbility extends AbstractAbility {
|
||||
breeze.setCustomNameVisible(true);
|
||||
breeze.addPassenger(player);
|
||||
breeze.setAI(true);
|
||||
breeze.setInvulnerable(true);
|
||||
breeze.setHealth(health);
|
||||
breeze.addScoreboardTag("$/TrimServer/ Temp");
|
||||
|
||||
activeBreezes.put(player.getUniqueId(), breeze);
|
||||
@@ -62,6 +79,7 @@ public class FlowAbility extends AbstractAbility {
|
||||
world.spawnParticle(Particle.BLOCK_CRUMBLE, spawnLoc, 20, 0.5, 0.5, 0.5, 0.1, material.createBlockData());
|
||||
SoundPlayer summonSound = new SoundPlayer(spawnLoc, Sound.ENTITY_BREEZE_SHOOT, 1.0f, 0.8f);
|
||||
summonSound.playWithin(10);
|
||||
CustomBossBar.showBossBar(main.getPlugin(),player,"Wind Rider",duration * 20);
|
||||
|
||||
BukkitTask task = new BukkitRunnable() {
|
||||
final long endTime = System.currentTimeMillis() + (duration * 1000L);
|
||||
@@ -95,7 +113,7 @@ public class FlowAbility extends AbstractAbility {
|
||||
}
|
||||
|
||||
TargetingUtils.areaAffect(breeze.getLocation(),1.5,entity -> !entity.equals(player) && !main.man().trustBackend.trusts(player,entity) && !breeze.equals(entity) && !shaper.activeShellTasks.containsKey(entity.getUniqueId()),target->{
|
||||
launchEntity(target);
|
||||
launchEntity(target, launchStrength);
|
||||
world.spawnParticle(Particle.EXPLOSION, target.getLocation(), 10, 0.5, 0.5, 0.5, 0.1);
|
||||
});
|
||||
}
|
||||
@@ -126,8 +144,8 @@ public class FlowAbility extends AbstractAbility {
|
||||
});
|
||||
}
|
||||
|
||||
private void launchEntity(Entity target) {
|
||||
Vector launchVector = new Vector(0, 2, 0);
|
||||
private void launchEntity(Entity target, double strength) {
|
||||
Vector launchVector = new Vector(0, strength, 0);
|
||||
target.setVelocity(target.getVelocity().add(launchVector));
|
||||
|
||||
target.getWorld().spawnParticle(
|
||||
@@ -150,6 +168,8 @@ public class FlowAbility extends AbstractAbility {
|
||||
activeBreezes.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
CustomBossBar.removeBossBar(player);
|
||||
|
||||
Location loc = breeze.getLocation();
|
||||
breeze.getWorld().spawnParticle(Particle.CLOUD, loc, 50, 1, 1, 1, 0.2);
|
||||
SoundPlayer despawnSound = new SoundPlayer(loc, Sound.ENTITY_BREEZE_DEATH, 1.0f, 1.0f);
|
||||
@@ -179,80 +199,80 @@ public class FlowAbility extends AbstractAbility {
|
||||
}
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Amethyst Wind Rider", description = "Summon an amethyst-infused breeze to ride", cooldownTicks = 20 * 60)
|
||||
@MaterialInfo(name = "Amethyst Wind Rider", description = "Summon an amethyst-infused breeze to ride", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean amethystAbility(Player player) {
|
||||
spawnRideableBreeze(player, 30, Material.AMETHYST_BLOCK);
|
||||
spawnRideableBreeze(player, NORMAL_DURATION, Material.AMETHYST_BLOCK,NORMAL_LAUNCH_STRENGTH,NORMAL_HEALTH);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Copper Wind Rider", description = "Summon a copper-infused breeze to ride", cooldownTicks = 20 * 60)
|
||||
@MaterialInfo(name = "Copper Wind Rider", description = "Summon a copper-infused breeze to ride", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean copperAbility(Player player) {
|
||||
spawnRideableBreeze(player, 30, Material.COPPER_BLOCK);
|
||||
spawnRideableBreeze(player, NORMAL_DURATION, Material.COPPER_BLOCK,NORMAL_LAUNCH_STRENGTH,NORMAL_HEALTH);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Diamond Wind Rider", description = "Summon a diamond-infused breeze to ride", cooldownTicks = 20 * 60)
|
||||
@MaterialInfo(name = "Diamond Wind Rider", description = "Summon a diamond-infused breeze to ride", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean diamondAbility(Player player) {
|
||||
spawnRideableBreeze(player, 30, Material.DIAMOND_BLOCK);
|
||||
spawnRideableBreeze(player, NORMAL_DURATION, Material.DIAMOND_BLOCK,NORMAL_LAUNCH_STRENGTH,NORMAL_HEALTH);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Emerald Wind Rider", description = "Summon an emerald-infused breeze to ride", cooldownTicks = 20 * 60)
|
||||
@MaterialInfo(name = "Emerald Wind Rider", description = "Summon an emerald-infused breeze to ride", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean emeraldAbility(Player player) {
|
||||
spawnRideableBreeze(player, 30, Material.EMERALD_BLOCK);
|
||||
spawnRideableBreeze(player, NORMAL_DURATION, Material.EMERALD_BLOCK,NORMAL_LAUNCH_STRENGTH,NORMAL_HEALTH);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Gold Wind Rider", description = "Summon a gold-infused breeze to ride", cooldownTicks = 20 * 60)
|
||||
@MaterialInfo(name = "Gold Wind Rider", description = "Summon a gold-infused breeze to ride", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean goldAbility(Player player) {
|
||||
spawnRideableBreeze(player, 30, Material.GOLD_BLOCK);
|
||||
spawnRideableBreeze(player, NORMAL_DURATION, Material.GOLD_BLOCK,NORMAL_LAUNCH_STRENGTH,NORMAL_HEALTH);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Iron Wind Rider", description = "Summon an iron-infused breeze to ride", cooldownTicks = 20 * 60)
|
||||
@MaterialInfo(name = "Iron Wind Rider", description = "Summon an iron-infused breeze to ride", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean ironAbility(Player player) {
|
||||
spawnRideableBreeze(player, 30, Material.IRON_BLOCK);
|
||||
spawnRideableBreeze(player, NORMAL_DURATION, Material.IRON_BLOCK,NORMAL_LAUNCH_STRENGTH,NORMAL_HEALTH);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Lapis Wind Rider", description = "Summon a lapis-infused breeze to ride", cooldownTicks = 20 * 60)
|
||||
@MaterialInfo(name = "Lapis Wind Rider", description = "Summon a lapis-infused breeze to ride", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean lapisAbility(Player player) {
|
||||
spawnRideableBreeze(player, 30, Material.LAPIS_BLOCK);
|
||||
spawnRideableBreeze(player, NORMAL_DURATION, Material.LAPIS_BLOCK,NORMAL_LAUNCH_STRENGTH,NORMAL_HEALTH);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Netherite Wind Rider", description = "Summon a powerful netherite-infused breeze to ride", cooldownTicks = 20 * 90)
|
||||
@MaterialInfo(name = "Netherite Wind Rider", description = "Summon a powerful netherite-infused breeze to ride", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@Override
|
||||
public boolean netheriteAbility(Player player) {
|
||||
spawnRideableBreeze(player, 45, Material.NETHERITE_BLOCK);
|
||||
spawnRideableBreeze(player, NETHERITE_DURATION, Material.NETHERITE_BLOCK,NETHERITE_LAUNCH_STRENGTH,NETHERITE_HEALTH);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Quartz Wind Rider", description = "Summon a quartz-infused breeze to ride", cooldownTicks = 20 * 60)
|
||||
@MaterialInfo(name = "Quartz Wind Rider", description = "Summon a quartz-infused breeze to ride", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean quartzAbility(Player player) {
|
||||
spawnRideableBreeze(player, 30, Material.QUARTZ_BLOCK);
|
||||
spawnRideableBreeze(player, NORMAL_DURATION, Material.QUARTZ_BLOCK,NORMAL_LAUNCH_STRENGTH,NORMAL_HEALTH);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Redstone Wind Rider", description = "Summon a redstone-infused breeze to ride", cooldownTicks = 20 * 60)
|
||||
@MaterialInfo(name = "Redstone Wind Rider", description = "Summon a redstone-infused breeze to ride", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean redstoneAbility(Player player) {
|
||||
spawnRideableBreeze(player, 30, Material.REDSTONE_BLOCK);
|
||||
spawnRideableBreeze(player, NORMAL_DURATION, Material.REDSTONE_BLOCK,NORMAL_LAUNCH_STRENGTH,NORMAL_HEALTH);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Resin Wind Rider", description = "Summon a resin-infused breeze to ride", cooldownTicks = 20 * 60)
|
||||
@MaterialInfo(name = "Resin Wind Rider", description = "Summon a resin-infused breeze to ride", cooldownTicks = RESIN_COOLDOWN)
|
||||
@Override
|
||||
public boolean resinAbility(Player player) {
|
||||
spawnRideableBreeze(player, 30, Material.RESIN_BLOCK);
|
||||
spawnRideableBreeze(player, RESIN_DURATION, Material.RESIN_BLOCK,RESIN_LAUNCH_STRENGTH,RESIN_HEALTH);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -4,145 +4,176 @@ import me.trouper.trimserver.server.systems.abilities.MaterialInfo;
|
||||
import me.trouper.trimserver.server.systems.abilities.AbstractAbility;
|
||||
import me.trouper.trimserver.server.systems.abilities.PatternInfo;
|
||||
import me.trouper.trimserver.utils.SoundPlayer;
|
||||
import me.trouper.trimserver.utils.Text;
|
||||
import me.trouper.trimserver.utils.text.CustomBossBar;
|
||||
import me.trouper.trimserver.utils.text.Text;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.inventory.meta.trim.TrimPattern;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@PatternInfo(name = "The Host", description = "Disappear into the shadows like Gatsby.")
|
||||
@PatternInfo(name = "The Host", description = "And like that, he vanishes!")
|
||||
public class HostAbility extends AbstractAbility {
|
||||
|
||||
public static final int NORMAL_DURATION = 6;
|
||||
public static final int NORMAL_COOLDOWN = 20 * 30;
|
||||
|
||||
public static final int NETHERITE_DURATION = 15;
|
||||
public static final int NETHERITE_COOLDOWN = 20 * 20;
|
||||
|
||||
public static final int RESIN_DURATION = 5;
|
||||
public static final int RESIN_COOLDOWN = 20 * 15;
|
||||
|
||||
public HostAbility() {
|
||||
super(TrimPattern.HOST);
|
||||
}
|
||||
private final Set<UUID> hiddenPlayers = new HashSet<>();
|
||||
|
||||
public void makeInvisible(Player invis, long seconds) {
|
||||
AbstractAbility eyeInstance = main.man().abilityBackend.getAbility(TrimPattern.EYE);
|
||||
EyeAbility eye = (EyeAbility) eyeInstance;
|
||||
|
||||
invis.getLocation().getWorld().spawnParticle(Particle.EXPLOSION_EMITTER,invis.getLocation(),1,0,0,0);
|
||||
new SoundPlayer(invis.getLocation(),Sound.BLOCK_REDSTONE_TORCH_BURNOUT,10,0.5F);
|
||||
|
||||
invis.addScoreboardTag("$/TrimServer/ Invisible");
|
||||
hiddenPlayers.add(invis.getUniqueId());
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if (main.man().trustBackend.trusts(invis,player) || main.man().abilityBackend.getAbility(player).getPattern().equals(TrimPattern.EYE)) continue;
|
||||
AbstractAbility ability = main.man().abilityBackend.getAbility(player);
|
||||
if (main.man().trustBackend.trusts(invis,player) || (ability != null && ability.getPattern().equals(TrimPattern.EYE))) continue;
|
||||
player.hidePlayer(main.getPlugin(),invis);
|
||||
AtomicInteger timer = new AtomicInteger();
|
||||
Bukkit.getScheduler().runTaskTimer(main.getPlugin(),(task)->{
|
||||
if (timer.getAndIncrement() >= seconds) {
|
||||
if (!player.isOnline() || !invis.isOnline()) return;
|
||||
player.showPlayer(main.getPlugin(),invis);
|
||||
task.cancel();
|
||||
return;
|
||||
}
|
||||
invis.sendActionBar(Text.color("&aYou are hidden from other players!"));
|
||||
},0,20);
|
||||
|
||||
}
|
||||
|
||||
CustomBossBar.showBossBar(main.getPlugin(),invis,Text.color("&aYou are hidden from other players!"),20*(int)seconds);
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(main.getPlugin(),(task)->{
|
||||
show(invis);
|
||||
},seconds * 20);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDeath(PlayerDeathEvent e) {
|
||||
if (hiddenPlayers.contains(e.getPlayer().getUniqueId())) {
|
||||
show(e.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent e) {
|
||||
if (e.getPlayer().getScoreboardTags().contains("$/TrimServer/ Invisible")) {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
player.showPlayer(main.getPlugin(),e.getPlayer());
|
||||
}
|
||||
Player p = e.getPlayer();
|
||||
if (hiddenPlayers.contains(e.getPlayer().getUniqueId())) {
|
||||
show(e.getPlayer());
|
||||
return;
|
||||
}
|
||||
for (UUID hiddenPlayer : hiddenPlayers) {
|
||||
Player invis = Bukkit.getPlayer(hiddenPlayer);
|
||||
if (invis == null) return;
|
||||
AbstractAbility ability = main.man().abilityBackend.getAbility(p);
|
||||
if (main.man().trustBackend.trusts(invis,p) || (ability != null && ability.getPattern().equals(TrimPattern.EYE))) return;
|
||||
p.hidePlayer(main.getPlugin(),invis);
|
||||
}
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Amethyst ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = 20 * 30)
|
||||
private void show(Player p) {
|
||||
if (p == null) return;
|
||||
hiddenPlayers.remove(p.getUniqueId());
|
||||
p.sendActionBar(Text.color("&cYou are now visible again!"));
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
player.showPlayer(main.getPlugin(),p);
|
||||
}
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Amethyst ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean amethystAbility(Player player) {
|
||||
makeInvisible(player,20);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS,20*6,0,true,false,true));
|
||||
makeInvisible(player,NORMAL_DURATION);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS,NORMAL_DURATION * 20,0,true,false,true));
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Copper ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Copper ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean copperAbility(Player player) {
|
||||
makeInvisible(player,20);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS,20*6,0,true,false,true));
|
||||
makeInvisible(player,NORMAL_DURATION);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS,NORMAL_DURATION * 20,0,true,false,true));
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Diamond ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Diamond ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean diamondAbility(Player player) {
|
||||
makeInvisible(player,20);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS,20*6,0,true,false,true));
|
||||
makeInvisible(player,NORMAL_DURATION);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS,NORMAL_DURATION * 20,0,true,false,true));
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Emerald ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Emerald ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean emeraldAbility(Player player) {
|
||||
makeInvisible(player,20);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS,20*6,0,true,false,true));
|
||||
makeInvisible(player,NORMAL_DURATION);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS,NORMAL_DURATION * 20,0,true,false,true));
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Gold ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Gold ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean goldAbility(Player player) {
|
||||
makeInvisible(player,20);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS,20*6,0,true,false,true));
|
||||
makeInvisible(player,NORMAL_DURATION);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS,NORMAL_DURATION * 20,0,true,false,true));
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Iron ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Iron ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean ironAbility(Player player) {
|
||||
makeInvisible(player,20);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS,20*6,0,true,false,true));
|
||||
makeInvisible(player,NORMAL_DURATION);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS,NORMAL_DURATION * 20,0,true,false,true));
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Lapis ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Lapis ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean lapisAbility(Player player) {
|
||||
makeInvisible(player,20);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS,20*6,0,true,false,true));
|
||||
makeInvisible(player,NORMAL_DURATION);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS,NORMAL_DURATION * 20,0,true,false,true));
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Netherite ", description = "Grants true invisibility for 10 seconds and makes your attacks stronger", cooldownTicks = 20 * 20)
|
||||
@MaterialInfo(name = "Netherite ", description = "Grants true invisibility for 10 seconds and makes your attacks stronger", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@Override
|
||||
public boolean netheriteAbility(Player player) {
|
||||
makeInvisible(player,10);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.STRENGTH,20*6,1,true,false,true));
|
||||
makeInvisible(player,NETHERITE_DURATION);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.STRENGTH,NETHERITE_DURATION * 20,1,true,false,true));
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Quartz ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Quartz ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean quartzAbility(Player player) {
|
||||
makeInvisible(player,20);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS,20*6,0,true,false,true));
|
||||
makeInvisible(player,NORMAL_DURATION);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS,NORMAL_DURATION * 20,0,true,false,true));
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Redstone ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Redstone ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean redstoneAbility(Player player) {
|
||||
makeInvisible(player,20);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS,20*6,0,true,false,true));
|
||||
makeInvisible(player,NORMAL_DURATION);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS,NORMAL_DURATION * 20,0,true,false,true));
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Resin ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Resin ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = RESIN_COOLDOWN)
|
||||
@Override
|
||||
public boolean resinAbility(Player player) {
|
||||
makeInvisible(player,20);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS,20*6,0,true,false,true));
|
||||
makeInvisible(player,NORMAL_DURATION);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS,RESIN_DURATION * 10,0,true,false,true));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import me.trouper.trimserver.server.systems.abilities.AbstractAbility;
|
||||
import me.trouper.trimserver.server.systems.abilities.PatternInfo;
|
||||
import me.trouper.trimserver.utils.PlayerUtils;
|
||||
import me.trouper.trimserver.utils.TargetingUtils;
|
||||
import me.trouper.trimserver.utils.Text;
|
||||
import me.trouper.trimserver.utils.visual.BlockDisplayRaytracer;
|
||||
import me.trouper.trimserver.utils.visual.DisplayUtils;
|
||||
import org.bukkit.*;
|
||||
@@ -25,13 +24,22 @@ import java.util.UUID;
|
||||
@PatternInfo(name = "Unexpected Levitation", description = "Raiser? I hardly know her!")
|
||||
public class RaiserAbility extends AbstractAbility {
|
||||
|
||||
public static final int NORMAL_DURATION = 15;
|
||||
public static final int NORMAL_COOLDOWN = 20 * 40;
|
||||
|
||||
public static final int NETHERITE_DURATION = 20;
|
||||
public static final int NETHERITE_COOLDOWN = 20 * 25;
|
||||
|
||||
public static final int RESIN_DURATION = 10;
|
||||
public static final int RESIN_COOLDOWN = 20 * 15;
|
||||
|
||||
public RaiserAbility() {
|
||||
super(TrimPattern.RAISER);
|
||||
}
|
||||
|
||||
private final Map<UUID, BukkitTask> levitationTasks = new HashMap<>();
|
||||
|
||||
public void raiseEntity(Player caster, LivingEntity target) {
|
||||
public void raiseEntity(Player caster, LivingEntity target, int durationSeconds) {
|
||||
if (target == null || !PlayerUtils.combatAllowed(target,caster)) return;
|
||||
|
||||
UUID uuid = target.getUniqueId();
|
||||
@@ -44,7 +52,7 @@ public class RaiserAbility extends AbstractAbility {
|
||||
double healthThreshold = initialHealth / 2.0;
|
||||
double targetY = initialLocation.getY() + 4.0;
|
||||
int frequency = 2;
|
||||
int duration = 20 * 7;
|
||||
int duration = durationSeconds * 20;
|
||||
|
||||
target.getWorld().playSound(target.getLocation(), Sound.ENTITY_BAT_TAKEOFF, 0.8f, 1.0f);
|
||||
BlockDisplay hook = BlockDisplayRaytracer.trace(Material.IRON_BLOCK,target.getEyeLocation(),target.getLocation().add(0,128,0),0.3,60);
|
||||
@@ -133,7 +141,7 @@ public class RaiserAbility extends AbstractAbility {
|
||||
}
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Amethyst ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = 20 * 45)
|
||||
@MaterialInfo(name = "Amethyst ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean amethystAbility(Player player) {
|
||||
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
|
||||
@@ -142,11 +150,11 @@ public class RaiserAbility extends AbstractAbility {
|
||||
!main.man().trustBackend.trusts(player,target) &&
|
||||
!shaper.activeShellTasks.containsKey(target.getUniqueId()) &&
|
||||
main.man().abilityBackend.abilityAllowed(player,target.getLocation()), ent->{
|
||||
raiseEntity(player,ent);
|
||||
raiseEntity(player,ent,NORMAL_DURATION);
|
||||
});
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Copper ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = 20 * 45)
|
||||
@MaterialInfo(name = "Copper ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean copperAbility(Player player) {
|
||||
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
|
||||
@@ -155,11 +163,11 @@ public class RaiserAbility extends AbstractAbility {
|
||||
!main.man().trustBackend.trusts(player,target) &&
|
||||
!shaper.activeShellTasks.containsKey(target.getUniqueId()) &&
|
||||
main.man().abilityBackend.abilityAllowed(player,target.getLocation()), ent->{
|
||||
raiseEntity(player,ent);
|
||||
raiseEntity(player,ent,NORMAL_DURATION);
|
||||
});
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Diamond ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = 20 * 45)
|
||||
@MaterialInfo(name = "Diamond ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean diamondAbility(Player player) {
|
||||
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
|
||||
@@ -168,11 +176,11 @@ public class RaiserAbility extends AbstractAbility {
|
||||
!main.man().trustBackend.trusts(player,target) &&
|
||||
!shaper.activeShellTasks.containsKey(target.getUniqueId()) &&
|
||||
main.man().abilityBackend.abilityAllowed(player,target.getLocation()), ent->{
|
||||
raiseEntity(player,ent);
|
||||
raiseEntity(player,ent,NORMAL_DURATION);
|
||||
});
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Emerald ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = 20 * 45)
|
||||
@MaterialInfo(name = "Emerald ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean emeraldAbility(Player player) {
|
||||
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
|
||||
@@ -181,11 +189,11 @@ public class RaiserAbility extends AbstractAbility {
|
||||
!main.man().trustBackend.trusts(player,target) &&
|
||||
!shaper.activeShellTasks.containsKey(target.getUniqueId()) &&
|
||||
main.man().abilityBackend.abilityAllowed(player,target.getLocation()), ent->{
|
||||
raiseEntity(player,ent);
|
||||
raiseEntity(player,ent,NORMAL_DURATION);
|
||||
});
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Gold ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = 20 * 45)
|
||||
@MaterialInfo(name = "Gold ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean goldAbility(Player player) {
|
||||
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
|
||||
@@ -194,11 +202,11 @@ public class RaiserAbility extends AbstractAbility {
|
||||
!main.man().trustBackend.trusts(player,target) &&
|
||||
!shaper.activeShellTasks.containsKey(target.getUniqueId()) &&
|
||||
main.man().abilityBackend.abilityAllowed(player,target.getLocation()), ent->{
|
||||
raiseEntity(player,ent);
|
||||
raiseEntity(player,ent,NORMAL_DURATION);
|
||||
});
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Iron ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = 20 * 45)
|
||||
@MaterialInfo(name = "Iron ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean ironAbility(Player player) {
|
||||
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
|
||||
@@ -207,11 +215,11 @@ public class RaiserAbility extends AbstractAbility {
|
||||
!main.man().trustBackend.trusts(player,target) &&
|
||||
!shaper.activeShellTasks.containsKey(target.getUniqueId()) &&
|
||||
main.man().abilityBackend.abilityAllowed(player,target.getLocation()), ent->{
|
||||
raiseEntity(player,ent);
|
||||
raiseEntity(player,ent,NORMAL_DURATION);
|
||||
});
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Lapis ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = 20 * 45)
|
||||
@MaterialInfo(name = "Lapis ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean lapisAbility(Player player) {
|
||||
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
|
||||
@@ -220,21 +228,21 @@ public class RaiserAbility extends AbstractAbility {
|
||||
!main.man().trustBackend.trusts(player,target) &&
|
||||
!shaper.activeShellTasks.containsKey(target.getUniqueId()) &&
|
||||
main.man().abilityBackend.abilityAllowed(player,target.getLocation()), ent->{
|
||||
raiseEntity(player,ent);
|
||||
raiseEntity(player,ent,NORMAL_DURATION);
|
||||
});
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Netherite ", description = "Pins your enemy 4 blocks into the air for 6 seconds. Can raise those with Shaper ability activated too.", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Netherite ", description = "Pins your enemy 4 blocks into the air for 6 seconds. Can raise those with Shaper ability activated too.", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@Override
|
||||
public boolean netheriteAbility(Player player) {
|
||||
return TargetingUtils.areaAffect(player.getLocation(),15,target ->
|
||||
!main.man().trustBackend.trusts(player,target) &&
|
||||
main.man().abilityBackend.abilityAllowed(player,target.getLocation()), ent->{
|
||||
raiseEntity(player,ent);
|
||||
raiseEntity(player,ent,NETHERITE_DURATION);
|
||||
});
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Quartz ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = 20 * 45)
|
||||
@MaterialInfo(name = "Quartz ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean quartzAbility(Player player) {
|
||||
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
|
||||
@@ -243,11 +251,11 @@ public class RaiserAbility extends AbstractAbility {
|
||||
!main.man().trustBackend.trusts(player,target) &&
|
||||
!shaper.activeShellTasks.containsKey(target.getUniqueId()) &&
|
||||
main.man().abilityBackend.abilityAllowed(player,target.getLocation()), ent->{
|
||||
raiseEntity(player,ent);
|
||||
raiseEntity(player,ent,NORMAL_DURATION);
|
||||
});
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Redstone ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = 20 * 45)
|
||||
@MaterialInfo(name = "Redstone ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean redstoneAbility(Player player) {
|
||||
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
|
||||
@@ -256,11 +264,11 @@ public class RaiserAbility extends AbstractAbility {
|
||||
!main.man().trustBackend.trusts(player,target) &&
|
||||
!shaper.activeShellTasks.containsKey(target.getUniqueId()) &&
|
||||
main.man().abilityBackend.abilityAllowed(player,target.getLocation()), ent->{
|
||||
raiseEntity(player,ent);
|
||||
raiseEntity(player,ent,NORMAL_DURATION);
|
||||
});
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Resin ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = 20 * 45)
|
||||
@MaterialInfo(name = "Resin ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = RESIN_COOLDOWN)
|
||||
@Override
|
||||
public boolean resinAbility(Player player) {
|
||||
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
|
||||
@@ -269,7 +277,7 @@ public class RaiserAbility extends AbstractAbility {
|
||||
!main.man().trustBackend.trusts(player,target) &&
|
||||
!shaper.activeShellTasks.containsKey(target.getUniqueId()) &&
|
||||
main.man().abilityBackend.abilityAllowed(player,target.getLocation()), ent->{
|
||||
raiseEntity(player,ent);
|
||||
raiseEntity(player,ent,RESIN_DURATION);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package me.trouper.trimserver.server.systems.abilities.trims;
|
||||
import me.trouper.trimserver.server.systems.abilities.MaterialInfo;
|
||||
import me.trouper.trimserver.server.systems.abilities.AbstractAbility;
|
||||
import me.trouper.trimserver.server.systems.abilities.PatternInfo;
|
||||
import me.trouper.trimserver.utils.PlayerUtils;
|
||||
import me.trouper.trimserver.utils.SoundPlayer;
|
||||
|
||||
import me.trouper.trimserver.utils.TargetingUtils;
|
||||
@@ -27,13 +28,22 @@ import java.util.Random;
|
||||
@PatternInfo(name = "Nether Eruption", description = "Summons sharp spikes from the ground that damage enemies accompanied by a blast of toxic ash.")
|
||||
public class RibAbility extends AbstractAbility {
|
||||
|
||||
public static final int NORMAL_COOLDOWN = 20 * 30;
|
||||
public static final int NORMAL_SPIKE_DAMAGE = 30;
|
||||
|
||||
public static final int NETHERITE_COOLDOWN = 20 * 20;
|
||||
public static final int NETHERITE_SPIKE_DAMAGE = 50;
|
||||
|
||||
public static final int RESIN_COOLDOWN = 20 * 15;
|
||||
public static final int RESIN_SPIKE_DAMAGE = 15;
|
||||
|
||||
private final Random random = new Random();
|
||||
|
||||
public RibAbility() {
|
||||
super(TrimPattern.RIB);
|
||||
}
|
||||
|
||||
private void executeEruption(Player caster, Material activatingTrimMaterial, int spikeCount, double areaRadius, int activeDurationTicks, Material groundParticleMaterial) {
|
||||
private void executeEruption(Player caster, Material activatingTrimMaterial, double spikeDamage, double areaRadius, int activeDurationTicks, Material groundParticleMaterial) {
|
||||
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
|
||||
ShaperAbility shaper = (ShaperAbility) shaperInstance;
|
||||
|
||||
@@ -75,7 +85,7 @@ public class RibAbility extends AbstractAbility {
|
||||
BlockData spikeBlockData = activatingTrimMaterial.createBlockData();
|
||||
BlockData groundBlockData = groundParticleMaterial.createBlockData();
|
||||
|
||||
for (int i = 0; i < spikeCount; i++) {
|
||||
for (int i = 0; i < 15; i++) {
|
||||
double angle = random.nextDouble() * 2 * Math.PI;
|
||||
double currentRandomRadius = random.nextDouble() * areaRadius;
|
||||
double dx = Math.cos(angle) * currentRandomRadius;
|
||||
@@ -83,7 +93,6 @@ public class RibAbility extends AbstractAbility {
|
||||
|
||||
Location spikeBaseCenter = playerCenterLoc.clone().add(dx, 0, dz);
|
||||
|
||||
// Find the ground for the spike
|
||||
Block highestBlock = world.getHighestBlockAt(spikeBaseCenter.getBlockX(), spikeBaseCenter.getBlockZ());
|
||||
Location groundSurfaceLoc = highestBlock.getLocation().add(0.5, 1.0, 0.5);
|
||||
|
||||
@@ -149,10 +158,10 @@ public class RibAbility extends AbstractAbility {
|
||||
}
|
||||
|
||||
if (ticksElapsed >= spikeRiseAnimationTicks / 2 && ticksElapsed <= spikeRiseAnimationTicks + 4 && !damageDealt) {
|
||||
TargetingUtils.areaAffect(finalSpikeBase,1,target -> !target.equals(caster) && !main.man().trustBackend.trusts(caster,target) && !shaper.activeShellTasks.containsKey(target.getUniqueId()),target -> {
|
||||
TargetingUtils.areaAffect(finalSpikeBase,4,target -> !target.equals(caster) && !main.man().trustBackend.trusts(caster,target) && !shaper.activeShellTasks.containsKey(target.getUniqueId()) && PlayerUtils.combatAllowed(target,caster), target -> {
|
||||
damageDealt = true;
|
||||
|
||||
target.damage(7.0, caster);
|
||||
target.damage(spikeDamage, caster);
|
||||
Vector knockDir = new Vector(random.nextGaussian() * 0.15, 0.9 + random.nextDouble()*0.2, random.nextGaussian() * 0.15);
|
||||
target.setVelocity(target.getVelocity().add(knockDir));
|
||||
new SoundPlayer(target.getLocation(), Sound.ENTITY_PLAYER_HURT_ON_FIRE, 1.0f, 1.0f).playWithin(15);
|
||||
@@ -191,7 +200,6 @@ public class RibAbility extends AbstractAbility {
|
||||
}.runTaskTimer(main.getPlugin(), delay, 1L);
|
||||
}
|
||||
|
||||
// Failsafe cleanup for all created displays
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -205,80 +213,80 @@ public class RibAbility extends AbstractAbility {
|
||||
}.runTaskLater(main.getPlugin(), activeDurationTicks + spikeRiseAnimationTicks + 40L);
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Eruption (Amethyst)", description = "Erupts spikes of amethyst", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Eruption (Amethyst)", description = "Erupts spikes of amethyst", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean amethystAbility(Player player) {
|
||||
executeEruption(player, Material.AMETHYST_BLOCK, 10, 5.5, 20 * 5, Material.SMOOTH_BASALT);
|
||||
executeEruption(player, Material.AMETHYST_BLOCK, NORMAL_SPIKE_DAMAGE, 5.5, 20 * 5, Material.SMOOTH_BASALT);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Eruption (Copper)", description = "Erupts spikes of oxidized copper", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Eruption (Copper)", description = "Erupts spikes of oxidized copper", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean copperAbility(Player player) {
|
||||
executeEruption(player, Material.RAW_COPPER, 10, 5.0, 20 * 5, Material.TUFF);
|
||||
executeEruption(player, Material.RAW_COPPER, NORMAL_SPIKE_DAMAGE, 5.0, 20 * 5, Material.TUFF);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Eruption (Diamond)", description = "Erupts spikes of diamond", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Eruption (Diamond)", description = "Erupts spikes of diamond", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean diamondAbility(Player player) {
|
||||
executeEruption(player, Material.DEEPSLATE_DIAMOND_ORE, 12, 6.0, 20 * 6, Material.DEEPSLATE);
|
||||
executeEruption(player, Material.DEEPSLATE_DIAMOND_ORE, NORMAL_SPIKE_DAMAGE, 6.0, 20 * 6, Material.DEEPSLATE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Eruption (Emerald)", description = "Erupts spikes of emerald", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Eruption (Emerald)", description = "Erupts spikes of emerald", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean emeraldAbility(Player player) {
|
||||
executeEruption(player, Material.DEEPSLATE_EMERALD_ORE, 12, 6.0, 20 * 6, Material.MOSS_BLOCK);
|
||||
executeEruption(player, Material.DEEPSLATE_EMERALD_ORE, NORMAL_SPIKE_DAMAGE, 6.0, 20 * 6, Material.MOSS_BLOCK);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Eruption (Gold)", description = "Erupts spikes of gold", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Eruption (Gold)", description = "Erupts spikes of gold", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean goldAbility(Player player) {
|
||||
executeEruption(player, Material.DEEPSLATE_GOLD_ORE, 10, 5.0, 20 * 5, Material.NETHER_GOLD_ORE);
|
||||
executeEruption(player, Material.DEEPSLATE_GOLD_ORE, NORMAL_SPIKE_DAMAGE, 5.0, 20 * 5, Material.NETHER_GOLD_ORE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Eruption (Iron)", description = "Erupts spikes of iron", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Eruption (Iron)", description = "Erupts spikes of iron", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean ironAbility(Player player) {
|
||||
executeEruption(player, Material.RAW_IRON_BLOCK, 11, 5.5, 20 * 5, Material.RAW_IRON_BLOCK);
|
||||
executeEruption(player, Material.RAW_IRON_BLOCK, NORMAL_SPIKE_DAMAGE, 5.5, 20 * 5, Material.RAW_IRON_BLOCK);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Eruption (Lapis)", description = "Erupts spikes of lapis", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Eruption (Lapis)", description = "Erupts spikes of lapis", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean lapisAbility(Player player) {
|
||||
executeEruption(player, Material.LAPIS_BLOCK, 10, 5.0, 20 * 5, Material.CLAY);
|
||||
executeEruption(player, Material.LAPIS_BLOCK, NORMAL_SPIKE_DAMAGE, 5.0, 20 * 5, Material.CLAY);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Eruption (Netherite)", description = "Erupts deadly blackstone spikes", cooldownTicks = 20 * 20)
|
||||
@MaterialInfo(name = "Eruption (Netherite)", description = "Erupts deadly blackstone spikes", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@Override
|
||||
public boolean netheriteAbility(Player player) {
|
||||
executeEruption(player, Material.BLACKSTONE, 20, 10.0, 20 * 8, Material.BLACKSTONE);
|
||||
executeEruption(player, Material.BLACKSTONE, NETHERITE_SPIKE_DAMAGE, 10.0, 20 * 8, Material.BLACKSTONE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Eruption (Quartz)", description = "Erupts spikes of quartz", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Eruption (Quartz)", description = "Erupts spikes of quartz", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean quartzAbility(Player player) {
|
||||
executeEruption(player, Material.QUARTZ_BLOCK, 11, 5.5, 20 * 5, Material.NETHER_QUARTZ_ORE);
|
||||
executeEruption(player, Material.QUARTZ_BLOCK, NORMAL_SPIKE_DAMAGE, 5.5, 20 * 5, Material.NETHER_QUARTZ_ORE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Eruption (Redstone)", description = "Erupts energized redstone spikes", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Eruption (Redstone)", description = "Erupts energized redstone spikes", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean redstoneAbility(Player player) {
|
||||
executeEruption(player, Material.REDSTONE_BLOCK, 11, 5.5, 20 * 5, Material.REDSTONE_ORE);
|
||||
executeEruption(player, Material.REDSTONE_BLOCK, NORMAL_SPIKE_DAMAGE, 5.5, 20 * 5, Material.REDSTONE_ORE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Eruption (Resin)", description = "Erupts spikes of hardened resin from the ground", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Eruption (Resin)", description = "Erupts spikes of hardened resin from the ground", cooldownTicks = RESIN_COOLDOWN)
|
||||
@Override
|
||||
public boolean resinAbility(Player player) {
|
||||
executeEruption(player, Material.RESIN_BLOCK, 12, 6.0, 20 * 6, Material.NETHERRACK);
|
||||
executeEruption(player, Material.RESIN_BLOCK, RESIN_SPIKE_DAMAGE, 6.0, 20 * 6, Material.NETHERRACK);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import me.trouper.trimserver.server.systems.abilities.PatternInfo;
|
||||
import me.trouper.trimserver.utils.PlayerUtils;
|
||||
import me.trouper.trimserver.utils.SoundPlayer;
|
||||
import me.trouper.trimserver.utils.TargetingUtils;
|
||||
import me.trouper.trimserver.utils.Text;
|
||||
import me.trouper.trimserver.utils.text.Text;
|
||||
import me.trouper.trimserver.utils.visual.BlockDisplayRaytracer;
|
||||
import me.trouper.trimserver.utils.visual.CustomDisplayRaytracer;
|
||||
import org.bukkit.*;
|
||||
@@ -29,6 +29,21 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
@PatternInfo(name = "Build Sentry", description = "\"Meet the Engineer.\" Includes Variants.")
|
||||
public class SentryAbility extends AbstractAbility {
|
||||
|
||||
public static final int NORMAL_COOLDOWN = 20 * 10;
|
||||
public static final int NORMAL_AMMO = 30;
|
||||
public static final int NORMAL_MAX_LIFE = 30;
|
||||
public static final int NORMAL_BULLET_COOLDOWN = 5;
|
||||
|
||||
public static final int NETHERITE_COOLDOWN = 20 * 15;
|
||||
public static final int NETHERITE_AMMO = 50;
|
||||
public static final int NETHERITE_MAX_LIFE = 45;
|
||||
public static final int NETHERITE_BULLET_COOLDOWN = 2;
|
||||
|
||||
public static final int RESIN_COOLDOWN = 20 * 5;
|
||||
public static final int RESIN_AMMO = 15;
|
||||
public static final int RESIN_MAX_LIFE = 15;
|
||||
public static final int RESIN_BULLET_COOLDOWN = 3;
|
||||
|
||||
public SentryAbility() {
|
||||
super(TrimPattern.SENTRY);
|
||||
}
|
||||
@@ -132,7 +147,7 @@ public class SentryAbility extends AbstractAbility {
|
||||
|
||||
CustomDisplayRaytracer.trace(turret.getLocation(),dir,60,0.5,point -> {
|
||||
List<Entity> hits = new ArrayList<>(w.getNearbyEntities(point.getLoc(), 0.5,0.5,0.5, entity -> {
|
||||
return entity instanceof LivingEntity living && !(living instanceof Bat) && !living.isDead() && living != owner;
|
||||
return entity instanceof LivingEntity living && !(living instanceof Shulker) && !living.isDead() && living != owner;
|
||||
}));
|
||||
hits.forEach(t -> {
|
||||
if (t instanceof LivingEntity liv) {
|
||||
@@ -215,80 +230,80 @@ public class SentryAbility extends AbstractAbility {
|
||||
e.getDrops().clear();
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Amethyst ", description = "Spawns a sentry which shoots the nearest player", cooldownTicks = 20 * 10)
|
||||
@MaterialInfo(name = "Amethyst ", description = "Spawns a sentry which shoots the nearest player", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean amethystAbility(Player player) {
|
||||
spawnSentry(player.getLocation(),player,Material.AMETHYST_BLOCK,Material.DISPENSER,25,60,5);
|
||||
spawnSentry(player.getLocation(),player,Material.AMETHYST_BLOCK,Material.DISPENSER,NORMAL_AMMO,NORMAL_MAX_LIFE,NORMAL_BULLET_COOLDOWN);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Copper ", description = "Spawns a sentry which shoots the nearest player", cooldownTicks = 20 * 10)
|
||||
@MaterialInfo(name = "Copper ", description = "Spawns a sentry which shoots the nearest player", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean copperAbility(Player player) {
|
||||
spawnSentry(player.getLocation(),player,Material.COPPER_BLOCK,Material.DISPENSER,25,60,5);
|
||||
spawnSentry(player.getLocation(),player,Material.COPPER_BLOCK,Material.DISPENSER,NORMAL_AMMO,NORMAL_MAX_LIFE,NORMAL_BULLET_COOLDOWN);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Diamond ", description = "Spawns a sentry which shoots the nearest player", cooldownTicks = 20 * 10)
|
||||
@MaterialInfo(name = "Diamond ", description = "Spawns a sentry which shoots the nearest player", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean diamondAbility(Player player) {
|
||||
spawnSentry(player.getLocation(),player,Material.DIAMOND_BLOCK,Material.DISPENSER,25,60,5);
|
||||
spawnSentry(player.getLocation(),player,Material.DIAMOND_BLOCK,Material.DISPENSER,NORMAL_AMMO,NORMAL_MAX_LIFE,NORMAL_BULLET_COOLDOWN);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Emerald ", description = "Spawns a sentry which shoots the nearest player", cooldownTicks = 20 * 10)
|
||||
@MaterialInfo(name = "Emerald ", description = "Spawns a sentry which shoots the nearest player", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean emeraldAbility(Player player) {
|
||||
spawnSentry(player.getLocation(),player,Material.EMERALD_BLOCK,Material.DISPENSER,25,60,5);
|
||||
spawnSentry(player.getLocation(),player,Material.EMERALD_BLOCK,Material.DISPENSER,NORMAL_AMMO,NORMAL_MAX_LIFE,NORMAL_BULLET_COOLDOWN);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Gold ", description = "Spawns a sentry which shoots the nearest player", cooldownTicks = 20 * 10)
|
||||
@MaterialInfo(name = "Gold ", description = "Spawns a sentry which shoots the nearest player", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean goldAbility(Player player) {
|
||||
spawnSentry(player.getLocation(),player,Material.GOLD_BLOCK,Material.DISPENSER,25,60,5);
|
||||
spawnSentry(player.getLocation(),player,Material.GOLD_BLOCK,Material.DISPENSER,NORMAL_AMMO,NORMAL_MAX_LIFE,NORMAL_BULLET_COOLDOWN);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Iron ", description = "Spawns a sentry which shoots the nearest player", cooldownTicks = 20 * 10)
|
||||
@MaterialInfo(name = "Iron ", description = "Spawns a sentry which shoots the nearest player", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean ironAbility(Player player) {
|
||||
spawnSentry(player.getLocation(),player,Material.IRON_BLOCK,Material.DISPENSER,25,60,5);
|
||||
spawnSentry(player.getLocation(),player,Material.IRON_BLOCK,Material.DISPENSER,NORMAL_AMMO,NORMAL_MAX_LIFE,NORMAL_BULLET_COOLDOWN);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Lapis ", description = "Spawns a sentry which shoots the nearest player", cooldownTicks = 20 * 10)
|
||||
@MaterialInfo(name = "Lapis ", description = "Spawns a sentry which shoots the nearest player", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean lapisAbility(Player player) {
|
||||
spawnSentry(player.getLocation(),player,Material.LAPIS_BLOCK,Material.DISPENSER,25,60,5);
|
||||
spawnSentry(player.getLocation(),player,Material.LAPIS_BLOCK,Material.DISPENSER,NORMAL_AMMO,NORMAL_MAX_LIFE,NORMAL_BULLET_COOLDOWN);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Netherite Sentry", description = "Spawns a supercharged sentry which absolutely shreds the nearest player", cooldownTicks = 20 * 15)
|
||||
@MaterialInfo(name = "Netherite Sentry", description = "Spawns a supercharged sentry which absolutely shreds the nearest player", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@Override
|
||||
public boolean netheriteAbility(Player player) {
|
||||
spawnSentry(player.getLocation(),player,Material.NETHERITE_BLOCK,Material.CRAFTER,50,60,2);
|
||||
spawnSentry(player.getLocation(),player,Material.NETHERITE_BLOCK,Material.CRAFTER,NETHERITE_AMMO,NETHERITE_MAX_LIFE,NETHERITE_BULLET_COOLDOWN);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Quartz ", description = "Spawns a sentry which shoots the nearest player", cooldownTicks = 20 * 10)
|
||||
@MaterialInfo(name = "Quartz ", description = "Spawns a sentry which shoots the nearest player", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean quartzAbility(Player player) {
|
||||
spawnSentry(player.getLocation(),player,Material.QUARTZ_BLOCK,Material.DISPENSER,25,60,5);
|
||||
spawnSentry(player.getLocation(),player,Material.QUARTZ_BLOCK,Material.DISPENSER,NORMAL_AMMO,NORMAL_MAX_LIFE,NORMAL_BULLET_COOLDOWN);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Redstone ", description = "Spawns a sentry which shoots the nearest player", cooldownTicks = 20 * 10)
|
||||
@MaterialInfo(name = "Redstone ", description = "Spawns a sentry which shoots the nearest player", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean redstoneAbility(Player player) {
|
||||
spawnSentry(player.getLocation(),player,Material.REDSTONE_BLOCK,Material.DISPENSER,25,60,5);
|
||||
spawnSentry(player.getLocation(),player,Material.REDSTONE_BLOCK,Material.DISPENSER,NORMAL_AMMO,NORMAL_MAX_LIFE,NORMAL_BULLET_COOLDOWN);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Resin ", description = "Spawns a sentry which shoots the nearest player", cooldownTicks = 20 * 10)
|
||||
@MaterialInfo(name = "Resin ", description = "Spawns a sentry which shoots the nearest player", cooldownTicks = RESIN_COOLDOWN)
|
||||
@Override
|
||||
public boolean resinAbility(Player player) {
|
||||
spawnSentry(player.getLocation(),player,Material.RESIN_BLOCK,Material.DISPENSER,25,60,5);
|
||||
spawnSentry(player.getLocation(),player,Material.RESIN_BLOCK,Material.DISPENSER,RESIN_AMMO,RESIN_MAX_LIFE,RESIN_BULLET_COOLDOWN);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import me.trouper.trimserver.server.systems.abilities.PatternInfo;
|
||||
import me.trouper.trimserver.server.systems.abilities.AbstractAbility;
|
||||
import me.trouper.trimserver.utils.SoundPlayer;
|
||||
import me.trouper.trimserver.utils.TargetingUtils;
|
||||
import me.trouper.trimserver.utils.Text;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.attribute.AttributeModifier;
|
||||
@@ -15,7 +14,6 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.meta.trim.TrimPattern;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
@@ -37,17 +35,15 @@ public class ShaperAbility extends AbstractAbility implements Listener {
|
||||
private final Map<UUID, AttributeModifier> knockbackModifiers = new ConcurrentHashMap<>();
|
||||
private final Map<UUID, Integer> originalFireTicks = new ConcurrentHashMap<>();
|
||||
|
||||
private static final int BASE_DURATION_TICKS = 8 * 20;
|
||||
private static final double BASE_SHATTER_DAMAGE = 10.0;
|
||||
private static final double BASE_SHATTER_RADIUS = 8.0;
|
||||
private static final int NORMAL_DURATION = 8 * 20;
|
||||
private static final double NORMAL_SHATTER_DAMAGE = 10.0;
|
||||
private static final double NORMAL_SHATTER_RADIUS = 8.0;
|
||||
private static final int SLOWNESS_AMPLIFIER = 1;
|
||||
|
||||
// Cooldowns
|
||||
private static final int DEFAULT_COOLDOWN = 20 * 60;
|
||||
private static final int DEFAULT_COOLDOWN = 20 * 50;
|
||||
private static final int NETHERITE_COOLDOWN = 20 * 90;
|
||||
private static final int RESIN_COOLDOWN = 20 * 40;
|
||||
|
||||
// Netherite Modifiers
|
||||
private static final double NETHERITE_DURATION_MULTIPLIER = 1.3;
|
||||
private static final double NETHERITE_SHATTER_DAMAGE_MULTIPLIER = 1.5;
|
||||
private static final double NETHERITE_SHATTER_RADIUS_MULTIPLIER = 1.2;
|
||||
@@ -97,9 +93,9 @@ public class ShaperAbility extends AbstractAbility implements Listener {
|
||||
shellParts.add(bd);
|
||||
}
|
||||
|
||||
int duration = BASE_DURATION_TICKS;
|
||||
double shatterDamage = BASE_SHATTER_DAMAGE;
|
||||
double shatterRadius = BASE_SHATTER_RADIUS;
|
||||
int duration = NORMAL_DURATION;
|
||||
double shatterDamage = NORMAL_SHATTER_DAMAGE;
|
||||
double shatterRadius = NORMAL_SHATTER_RADIUS;
|
||||
int slownessAmplifier = SLOWNESS_AMPLIFIER;
|
||||
|
||||
if (blockMaterialForShell == Material.NETHERITE_BLOCK) {
|
||||
|
||||
@@ -27,12 +27,18 @@ import java.util.Optional;
|
||||
|
||||
@PatternInfo(name = "Warden's Call", description = "Now I am become warden, destroyer of ears.")
|
||||
public class SilenceAbility extends AbstractAbility {
|
||||
|
||||
public static final double NORMAL_DAMAGE = 10;
|
||||
public static final int NORMAL_COOLDOWN = 20 * 10;
|
||||
|
||||
public static final double NETHERITE_DAMAGE = 15;
|
||||
public static final int NETHERITE_COOLDOWN = 20 * 12;
|
||||
|
||||
public SilenceAbility() {
|
||||
super(TrimPattern.SILENCE);
|
||||
}
|
||||
|
||||
public void shootSonicBoom(Player player) {
|
||||
public void shootSonicBoom(Player player, double damage) {
|
||||
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
|
||||
ShaperAbility shaper = (ShaperAbility) shaperInstance;
|
||||
|
||||
@@ -62,7 +68,7 @@ public class SilenceAbility extends AbstractAbility {
|
||||
PlayerUtils.combatAllowed(entity,player)
|
||||
);
|
||||
targets.forEach(target -> {
|
||||
PlayerUtils.dealTrueDamage((LivingEntity) target, DamageSource.builder(DamageType.SONIC_BOOM).withDirectEntity(player).build(), 10);
|
||||
PlayerUtils.dealTrueDamage((LivingEntity) target, DamageSource.builder(DamageType.SONIC_BOOM).withDirectEntity(player).build(), damage);
|
||||
});
|
||||
return !targets.isEmpty();
|
||||
},(point,blockHit) -> {
|
||||
@@ -75,80 +81,80 @@ public class SilenceAbility extends AbstractAbility {
|
||||
},30);
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Amethyst ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = 20*10)
|
||||
@MaterialInfo(name = "Amethyst ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean amethystAbility(Player player) {
|
||||
shootSonicBoom(player);
|
||||
shootSonicBoom(player, NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Copper ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = 20*10)
|
||||
@MaterialInfo(name = "Copper ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean copperAbility(Player player) {
|
||||
shootSonicBoom(player);
|
||||
shootSonicBoom(player, NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Diamond ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = 20*10)
|
||||
@MaterialInfo(name = "Diamond ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean diamondAbility(Player player) {
|
||||
shootSonicBoom(player);
|
||||
shootSonicBoom(player, NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Emerald Bolt", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = 20*10)
|
||||
@MaterialInfo(name = "Emerald Bolt", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean emeraldAbility(Player player) {
|
||||
shootSonicBoom(player);
|
||||
shootSonicBoom(player, NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Gold ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = 20*10)
|
||||
@MaterialInfo(name = "Gold ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean goldAbility(Player player) {
|
||||
shootSonicBoom(player);
|
||||
shootSonicBoom(player, NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Iron ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = 20*10)
|
||||
@MaterialInfo(name = "Iron ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean ironAbility(Player player) {
|
||||
shootSonicBoom(player);
|
||||
shootSonicBoom(player, NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Lapis ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = 20*10)
|
||||
@MaterialInfo(name = "Lapis ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean lapisAbility(Player player) {
|
||||
shootSonicBoom(player);
|
||||
shootSonicBoom(player, NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Netherite ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = 20*7)
|
||||
@MaterialInfo(name = "Netherite ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@Override
|
||||
public boolean netheriteAbility(Player player) {
|
||||
shootSonicBoom(player);
|
||||
shootSonicBoom(player, NETHERITE_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Quartz ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = 20*10)
|
||||
@MaterialInfo(name = "Quartz ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean quartzAbility(Player player) {
|
||||
shootSonicBoom(player);
|
||||
shootSonicBoom(player, NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Redstone ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = 20*10)
|
||||
@MaterialInfo(name = "Redstone ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean redstoneAbility(Player player) {
|
||||
shootSonicBoom(player);
|
||||
shootSonicBoom(player, NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Resin ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = 20*10)
|
||||
@MaterialInfo(name = "Resin ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean resinAbility(Player player) {
|
||||
shootSonicBoom(player);
|
||||
shootSonicBoom(player, NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package me.trouper.trimserver.server.systems.abilities.trims;
|
||||
import me.trouper.trimserver.server.systems.abilities.MaterialInfo;
|
||||
import me.trouper.trimserver.server.systems.abilities.AbstractAbility;
|
||||
import me.trouper.trimserver.server.systems.abilities.PatternInfo;
|
||||
import me.trouper.trimserver.utils.Text;
|
||||
import me.trouper.trimserver.utils.text.Text;
|
||||
import me.trouper.trimserver.utils.Verbose;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -27,6 +27,15 @@ public class SnoutAbility extends AbstractAbility {
|
||||
super(TrimPattern.SNOUT);
|
||||
}
|
||||
|
||||
public static final int NORMAL_COOLDOWN = 20 * 45;
|
||||
public static final int NORMAL_COUNT = 4;
|
||||
|
||||
public static final int NETHERITE_COOLDOWN = 20 * 45;
|
||||
public static final int NETHERITE_COUNT = 6;
|
||||
|
||||
public static final int RESIN_COOLDOWN = 20 * 20;
|
||||
public static final int RESIN_COUNT = 3;
|
||||
|
||||
/**
|
||||
* Spawns a Piglin Brutes Loyal to the specified player.
|
||||
*
|
||||
@@ -117,111 +126,111 @@ public class SnoutAbility extends AbstractAbility {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Amethyst ", description = "Spawns 4 Purple Piglin Brutes Loyal to you. They despawn after 30 seconds", cooldownTicks = 20 * 45)
|
||||
@MaterialInfo(name = "Amethyst ", description = "Spawns 4 Purple Piglin Brutes Loyal to you. They despawn after 30 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean amethystAbility(Player player) {
|
||||
player.getWorld().playSound(player, Sound.ENTITY_EVOKER_PREPARE_WOLOLO,10,1);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int i = 0; i < NORMAL_COUNT; i++) {
|
||||
spawnLoyalPiglin(player, player.getEyeLocation(), NamedTextColor.LIGHT_PURPLE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Copper ", description = "Spawns 4 Gold Piglin Brutes Loyal to you. They despawn after 30 seconds", cooldownTicks = 20 * 45)
|
||||
@MaterialInfo(name = "Copper ", description = "Spawns 4 Gold Piglin Brutes Loyal to you. They despawn after 30 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean copperAbility(Player player) {
|
||||
player.getWorld().playSound(player, Sound.ENTITY_EVOKER_PREPARE_WOLOLO,10,1);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int i = 0; i < NORMAL_COUNT; i++) {
|
||||
spawnLoyalPiglin(player, player.getEyeLocation(), NamedTextColor.GOLD);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Diamond ", description = "Spawns 4 Aqua Piglin Brutes Loyal to you. They despawn after 30 seconds", cooldownTicks = 20 * 45)
|
||||
@MaterialInfo(name = "Diamond ", description = "Spawns 4 Aqua Piglin Brutes Loyal to you. They despawn after 30 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean diamondAbility(Player player) {
|
||||
player.getWorld().playSound(player, Sound.ENTITY_EVOKER_PREPARE_WOLOLO,10,1);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int i = 0; i < NORMAL_COUNT; i++) {
|
||||
spawnLoyalPiglin(player, player.getEyeLocation(), NamedTextColor.AQUA);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Emerald ", description = "Spawns 4 Emerald Piglin Brutes Loyal to you. They despawn after 30 seconds", cooldownTicks = 20 * 45)
|
||||
@MaterialInfo(name = "Emerald ", description = "Spawns 4 Emerald Piglin Brutes Loyal to you. They despawn after 30 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean emeraldAbility(Player player) {
|
||||
player.getWorld().playSound(player, Sound.ENTITY_EVOKER_PREPARE_WOLOLO,10,1);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int i = 0; i < NORMAL_COUNT; i++) {
|
||||
spawnLoyalPiglin(player, player.getEyeLocation(), NamedTextColor.DARK_GREEN);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Gold ", description = "Spawns 4 Yellow Piglin Brutes Loyal to you. They despawn after 30 seconds", cooldownTicks = 20 * 45)
|
||||
@MaterialInfo(name = "Gold ", description = "Spawns 4 Yellow Piglin Brutes Loyal to you. They despawn after 30 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean goldAbility(Player player) {
|
||||
player.getWorld().playSound(player, Sound.ENTITY_EVOKER_PREPARE_WOLOLO,10,1);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int i = 0; i < NORMAL_COUNT; i++) {
|
||||
spawnLoyalPiglin(player, player.getEyeLocation(), NamedTextColor.YELLOW);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Iron ", description = "Spawns 4 Gray Piglin Brutes Loyal to you. They despawn after 30 seconds", cooldownTicks = 20 * 45)
|
||||
@MaterialInfo(name = "Iron ", description = "Spawns 4 Gray Piglin Brutes Loyal to you. They despawn after 30 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean ironAbility(Player player) {
|
||||
player.getWorld().playSound(player, Sound.ENTITY_EVOKER_PREPARE_WOLOLO,10,1);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int i = 0; i < NORMAL_COUNT; i++) {
|
||||
spawnLoyalPiglin(player, player.getEyeLocation(), NamedTextColor.GRAY);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Lapis ", description = "Spawns 4 Blue Piglin Brutes Loyal to you. They despawn after 30 seconds", cooldownTicks = 20 * 45)
|
||||
@MaterialInfo(name = "Lapis ", description = "Spawns 4 Blue Piglin Brutes Loyal to you. They despawn after 30 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean lapisAbility(Player player) {
|
||||
player.getWorld().playSound(player, Sound.ENTITY_EVOKER_PREPARE_WOLOLO,10,1);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int i = 0; i < NORMAL_COUNT; i++) {
|
||||
spawnLoyalPiglin(player,player.getEyeLocation(),NamedTextColor.DARK_BLUE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Netherite ", description = "Spawns 6 Dark Piglin Brutes Loyal to you. They despawn after 30 seconds", cooldownTicks = 20 * 45)
|
||||
@MaterialInfo(name = "Netherite ", description = "Spawns 6 Dark Piglin Brutes Loyal to you. They despawn after 30 seconds", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@Override
|
||||
public boolean netheriteAbility(Player player) {
|
||||
player.getWorld().playSound(player, Sound.ENTITY_EVOKER_PREPARE_WOLOLO,10,1);
|
||||
for (int i = 0; i < 6; i++) {
|
||||
for (int i = 0; i < NETHERITE_COUNT; i++) {
|
||||
spawnLoyalPiglin(player,player.getEyeLocation(),NamedTextColor.DARK_GRAY);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Quartz ", description = "Spawns 4 White Piglin Brutes Loyal to you. They despawn after 30 seconds", cooldownTicks = 20 * 45)
|
||||
@MaterialInfo(name = "Quartz ", description = "Spawns 4 White Piglin Brutes Loyal to you. They despawn after 30 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean quartzAbility(Player player) {
|
||||
player.getWorld().playSound(player, Sound.ENTITY_EVOKER_PREPARE_WOLOLO,10,1);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int i = 0; i < NORMAL_COUNT; i++) {
|
||||
spawnLoyalPiglin(player,player.getEyeLocation(),NamedTextColor.WHITE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Redstone ", description = "Spawns 4 Red Piglin Brutes Loyal to you. They despawn after 30 seconds", cooldownTicks = 20 * 45)
|
||||
@MaterialInfo(name = "Redstone ", description = "Spawns 4 Red Piglin Brutes Loyal to you. They despawn after 30 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean redstoneAbility(Player player) {
|
||||
player.getWorld().playSound(player, Sound.ENTITY_EVOKER_PREPARE_WOLOLO,10,1);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int i = 0; i < NORMAL_COUNT; i++) {
|
||||
spawnLoyalPiglin(player,player.getEyeLocation(),NamedTextColor.RED);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Resin ", description = "Spawns 4 Gold Piglin Brutes Loyal to you. They despawn after 30 seconds", cooldownTicks = 20 * 45)
|
||||
@MaterialInfo(name = "Resin ", description = "Spawns 4 Gold Piglin Brutes Loyal to you. They despawn after 30 seconds", cooldownTicks = RESIN_COOLDOWN)
|
||||
@Override
|
||||
public boolean resinAbility(Player player) {
|
||||
player.getWorld().playSound(player, Sound.ENTITY_EVOKER_PREPARE_WOLOLO,10,1);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int i = 0; i < RESIN_COUNT; i++) {
|
||||
spawnLoyalPiglin(player,player.getEyeLocation(),NamedTextColor.GOLD);
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -6,6 +6,7 @@ import me.trouper.trimserver.server.systems.abilities.AbstractAbility;
|
||||
import me.trouper.trimserver.utils.PlayerUtils;
|
||||
import me.trouper.trimserver.utils.SoundPlayer;
|
||||
import me.trouper.trimserver.utils.TargetingUtils;
|
||||
import me.trouper.trimserver.utils.text.CustomBossBar;
|
||||
import me.trouper.trimserver.utils.visual.DisplayUtils;
|
||||
import me.trouper.trimserver.utils.visual.BlockDisplayRaytracer;
|
||||
|
||||
@@ -33,6 +34,18 @@ public class SpireAbility extends AbstractAbility {
|
||||
private final Map<UUID, BukkitTask> activeTasks = new HashMap<>();
|
||||
private final Map<UUID, UUID> activeProjectiles = new HashMap<>();
|
||||
|
||||
public static final int NORMAL_DURATION = 30;
|
||||
public static final int NORMAL_HEIGHT = 20;
|
||||
public static final int NORMAL_COOLDOWN = 20 * 90;
|
||||
|
||||
public static final int NETHERITE_DURATION = 40;
|
||||
public static final int NETHERITE_HEIGHT = 30;
|
||||
public static final int NETHERITE_COOLDOWN = 20 * 100;
|
||||
|
||||
public static final int RESIN_DURATION = 15;
|
||||
public static final int RESIN_HEIGHT = 10;
|
||||
public static final int RESIN_COOLDOWN = 20 * 60;
|
||||
|
||||
public SpireAbility() {
|
||||
super(TrimPattern.SPIRE);
|
||||
}
|
||||
@@ -40,7 +53,9 @@ public class SpireAbility extends AbstractAbility {
|
||||
private void createEnderStorm(Player player, Material material, int duration, int spireHeight) {
|
||||
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
|
||||
ShaperAbility shaper = (ShaperAbility) shaperInstance;
|
||||
|
||||
|
||||
CustomBossBar.showBossBar(main.getPlugin(),player,"Ender Storm",duration * 20);
|
||||
|
||||
if (activeTasks.containsKey(player.getUniqueId())) {
|
||||
activeTasks.get(player.getUniqueId()).cancel();
|
||||
activeTasks.remove(player.getUniqueId());
|
||||
@@ -106,7 +121,6 @@ public class SpireAbility extends AbstractAbility {
|
||||
});
|
||||
}
|
||||
|
||||
// check for players in the sphere and push them inward if they're near the edge
|
||||
if (tickCounter % 5 == 0) {
|
||||
TargetingUtils.areaAffect(sphereCenter,sphereRadius,target -> !main.man().trustBackend.trusts(player,target) && PlayerUtils.combatAllowed(target,player),target -> {
|
||||
double distanceFromCenter = target.getLocation().distance(sphereCenter);
|
||||
@@ -156,7 +170,6 @@ public class SpireAbility extends AbstractAbility {
|
||||
for (int y = 0; y < spireHeight; y += 2) {
|
||||
Location particleLoc = baseLoc.clone().add(0, y, 0);
|
||||
|
||||
// Spiral particles up the spire
|
||||
double angle = (y / (double) spireHeight) * 360 * 3;
|
||||
double radius = (spireHeight - y) / (double) spireHeight * 2;
|
||||
double x = Math.cos(Math.toRadians(angle)) * radius;
|
||||
@@ -172,7 +185,6 @@ public class SpireAbility extends AbstractAbility {
|
||||
|
||||
activeTasks.put(player.getUniqueId(), task);
|
||||
|
||||
// Schedule the end of the ability
|
||||
Bukkit.getScheduler().runTaskLater(main.getPlugin(), () -> {
|
||||
if (activeTasks.containsKey(player.getUniqueId())) {
|
||||
endEnderStorm(player);
|
||||
@@ -338,80 +350,80 @@ public class SpireAbility extends AbstractAbility {
|
||||
impactSound.playWithin(5);
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Amethyst Ender Storm", description = "Summon a spire that traps players and fires shulker bullets", cooldownTicks = 20*90)
|
||||
@MaterialInfo(name = "Amethyst Ender Storm", description = "Summon a spire that traps players and fires shulker bullets", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean amethystAbility(Player player) {
|
||||
createEnderStorm(player, Material.AMETHYST_BLOCK, 30, 20);
|
||||
createEnderStorm(player, Material.AMETHYST_BLOCK, NORMAL_DURATION, NORMAL_HEIGHT);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Copper Ender Storm", description = "Summon a spire that traps players and fires shulker bullets", cooldownTicks = 20*90)
|
||||
@MaterialInfo(name = "Copper Ender Storm", description = "Summon a spire that traps players and fires shulker bullets", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean copperAbility(Player player) {
|
||||
createEnderStorm(player, Material.COPPER_BLOCK, 30, 20);
|
||||
createEnderStorm(player, Material.COPPER_BLOCK, NORMAL_DURATION, NORMAL_HEIGHT);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Diamond Ender Storm", description = "Summon a spire that traps players and fires shulker bullets", cooldownTicks = 20*90)
|
||||
@MaterialInfo(name = "Diamond Ender Storm", description = "Summon a spire that traps players and fires shulker bullets", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean diamondAbility(Player player) {
|
||||
createEnderStorm(player, Material.DIAMOND_BLOCK, 30, 20);
|
||||
createEnderStorm(player, Material.DIAMOND_BLOCK, NORMAL_DURATION, NORMAL_HEIGHT);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Emerald Ender Storm", description = "Summon a spire that traps players and fires shulker bullets", cooldownTicks = 20*90)
|
||||
@MaterialInfo(name = "Emerald Ender Storm", description = "Summon a spire that traps players and fires shulker bullets", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean emeraldAbility(Player player) {
|
||||
createEnderStorm(player, Material.EMERALD_BLOCK, 30, 20);
|
||||
createEnderStorm(player, Material.EMERALD_BLOCK, NORMAL_DURATION, NORMAL_HEIGHT);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Gold Ender Storm", description = "Summon a spire that traps players and fires shulker bullets", cooldownTicks = 20*90)
|
||||
@MaterialInfo(name = "Gold Ender Storm", description = "Summon a spire that traps players and fires shulker bullets", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean goldAbility(Player player) {
|
||||
createEnderStorm(player, Material.GOLD_BLOCK, 30, 20);
|
||||
createEnderStorm(player, Material.GOLD_BLOCK, NORMAL_DURATION, NORMAL_HEIGHT);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Iron Ender Storm", description = "Summon a spire that traps players and fires shulker bullets", cooldownTicks = 20*90)
|
||||
@MaterialInfo(name = "Iron Ender Storm", description = "Summon a spire that traps players and fires shulker bullets", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean ironAbility(Player player) {
|
||||
createEnderStorm(player, Material.IRON_BLOCK, 30, 20);
|
||||
createEnderStorm(player, Material.IRON_BLOCK, NORMAL_DURATION, NORMAL_HEIGHT);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Lapis Ender Storm", description = "Summon a spire that traps players and fires shulker bullets", cooldownTicks = 20*90)
|
||||
@MaterialInfo(name = "Lapis Ender Storm", description = "Summon a spire that traps players and fires shulker bullets", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean lapisAbility(Player player) {
|
||||
createEnderStorm(player, Material.LAPIS_BLOCK, 30, 20);
|
||||
createEnderStorm(player, Material.LAPIS_BLOCK, NORMAL_DURATION, NORMAL_HEIGHT);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Netherite Ender Storm", description = "Summon a powerful spire that traps players and fires enhanced shulker bullets", cooldownTicks = 20*120)
|
||||
@MaterialInfo(name = "Netherite Ender Storm", description = "Summon a powerful spire that traps players and fires enhanced shulker bullets", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@Override
|
||||
public boolean netheriteAbility(Player player) {
|
||||
createEnderStorm(player, Material.NETHERITE_BLOCK, 45, 25);
|
||||
createEnderStorm(player, Material.NETHERITE_BLOCK, NETHERITE_HEIGHT, NETHERITE_DURATION);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Quartz Ender Storm", description = "Summon a spire that traps players and fires shulker bullets", cooldownTicks = 20*90)
|
||||
@MaterialInfo(name = "Quartz Ender Storm", description = "Summon a spire that traps players and fires shulker bullets", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean quartzAbility(Player player) {
|
||||
createEnderStorm(player, Material.QUARTZ_BLOCK, 30, 20);
|
||||
createEnderStorm(player, Material.QUARTZ_BLOCK, NORMAL_DURATION, NORMAL_HEIGHT);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Redstone Ender Storm", description = "Summon a spire that traps players and fires shulker bullets", cooldownTicks = 20*90)
|
||||
@MaterialInfo(name = "Redstone Ender Storm", description = "Summon a spire that traps players and fires shulker bullets", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean redstoneAbility(Player player) {
|
||||
createEnderStorm(player, Material.REDSTONE_BLOCK, 30, 20);
|
||||
createEnderStorm(player, Material.REDSTONE_BLOCK, NORMAL_DURATION, NORMAL_HEIGHT);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Resin Ender Storm", description = "Summon a spire that traps players and fires shulker bullets", cooldownTicks = 20*90)
|
||||
@MaterialInfo(name = "Resin Ender Storm", description = "Summon a spire that traps players and fires shulker bullets", cooldownTicks = RESIN_COOLDOWN)
|
||||
@Override
|
||||
public boolean resinAbility(Player player) {
|
||||
createEnderStorm(player, Material.RESIN_BLOCK, 30, 20);
|
||||
createEnderStorm(player, Material.RESIN_BLOCK, RESIN_DURATION, RESIN_HEIGHT);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -24,11 +24,23 @@ import java.util.List;
|
||||
@PatternInfo(name = "Tidal Wave", description = "No lifeguard on duty, swim at your own risk!")
|
||||
public class TideAbility extends AbstractAbility {
|
||||
|
||||
public static final int NORMAL_RADIUS = 10;
|
||||
public static final int NORMAL_DAMAGE = 6;
|
||||
public static final int NORMAL_COOLDOWN = 20 * 30;
|
||||
|
||||
public static final int NETHERITE_RADIUS = 12;
|
||||
public static final int NETHERITE_DAMAGE = 15;
|
||||
public static final int NETHERITE_COOLDOWN = 20 * 35;
|
||||
|
||||
public static final int RESIN_RADIUS = 5;
|
||||
public static final int RESIN_DAMAGE = 3;
|
||||
public static final int RESIN_COOLDOWN = 20 * 6;
|
||||
|
||||
public TideAbility() {
|
||||
super(TrimPattern.TIDE);
|
||||
}
|
||||
|
||||
public void spawnTidalWave(Player caster) {
|
||||
public void spawnTidalWave(Player caster, double radius, double damage) {
|
||||
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
|
||||
ShaperAbility shaper = (ShaperAbility) shaperInstance;
|
||||
|
||||
@@ -36,7 +48,7 @@ public class TideAbility extends AbstractAbility {
|
||||
new SoundPlayer(caster.getLocation(), Sound.ENTITY_PLAYER_SPLASH_HIGH_SPEED, 1, 1F).playWithin(30);
|
||||
|
||||
Vector direction = caster.getLocation().getDirection();
|
||||
DisplayUtils.waveFan(caster.getLocation().add(0, 2,0),10,direction,90,0.1, point->{
|
||||
DisplayUtils.waveFan(caster.getLocation().add(0, 2,0),radius,direction,90,0.1, point->{
|
||||
point.getWorld().spawnParticle(Particle.BLOCK_CRUMBLE,point,8,0.1,0.1,0.1,0.1, Material.BLUE_STAINED_GLASS.createBlockData());
|
||||
|
||||
TargetingUtils.areaAffect(point,0.3,5,0.3,target -> !main.man().trustBackend.trusts(caster,target) &&
|
||||
@@ -49,7 +61,7 @@ public class TideAbility extends AbstractAbility {
|
||||
double verticalMultiplier = 0.2;
|
||||
target.setVelocity(dir.multiply(strength).setY(verticalMultiplier));
|
||||
target.setRemainingAir(0);
|
||||
target.damage(6, DamageSource.builder(DamageType.DROWN).withDirectEntity(caster).build());
|
||||
target.damage(damage, DamageSource.builder(DamageType.DROWN).withDirectEntity(caster).build());
|
||||
blockSound.playWithin(10);
|
||||
caster.getWorld().spawnParticle(Particle.FALLING_WATER,target.getLocation().clone().add(0,1,0),10,0.2,1,0.2,0.1);
|
||||
});
|
||||
@@ -62,80 +74,80 @@ public class TideAbility extends AbstractAbility {
|
||||
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Amethyst ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Amethyst ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean amethystAbility(Player player) {
|
||||
spawnTidalWave(player);
|
||||
spawnTidalWave(player,NORMAL_RADIUS,NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Copper ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Copper ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean copperAbility(Player player) {
|
||||
spawnTidalWave(player);
|
||||
spawnTidalWave(player,NORMAL_RADIUS,NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Diamond ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Diamond ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean diamondAbility(Player player) {
|
||||
spawnTidalWave(player);
|
||||
spawnTidalWave(player,NORMAL_RADIUS,NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Emerald", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Emerald", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean emeraldAbility(Player player) {
|
||||
spawnTidalWave(player);
|
||||
spawnTidalWave(player,NORMAL_RADIUS,NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Gold ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Gold ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean goldAbility(Player player) {
|
||||
spawnTidalWave(player);
|
||||
spawnTidalWave(player,NORMAL_RADIUS,NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Iron ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Iron ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean ironAbility(Player player) {
|
||||
spawnTidalWave(player);
|
||||
spawnTidalWave(player,NORMAL_RADIUS,NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Lapis ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Lapis ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean lapisAbility(Player player) {
|
||||
spawnTidalWave(player);
|
||||
spawnTidalWave(player,NORMAL_RADIUS,NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Netherite ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = 20 * 10)
|
||||
@MaterialInfo(name = "Netherite ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@Override
|
||||
public boolean netheriteAbility(Player player) {
|
||||
spawnTidalWave(player);
|
||||
spawnTidalWave(player,NETHERITE_RADIUS,NETHERITE_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Quartz ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Quartz ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean quartzAbility(Player player) {
|
||||
spawnTidalWave(player);
|
||||
spawnTidalWave(player,NORMAL_RADIUS,NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Redstone ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Redstone ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean redstoneAbility(Player player) {
|
||||
spawnTidalWave(player);
|
||||
spawnTidalWave(player,NORMAL_RADIUS,NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Resin ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Resin ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = RESIN_COOLDOWN)
|
||||
@Override
|
||||
public boolean resinAbility(Player player) {
|
||||
spawnTidalWave(player);
|
||||
spawnTidalWave(player,RESIN_RADIUS,RESIN_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package me.trouper.trimserver.server.systems.abilities.trims;
|
||||
import me.trouper.trimserver.server.systems.abilities.MaterialInfo;
|
||||
import me.trouper.trimserver.server.systems.abilities.AbstractAbility;
|
||||
import me.trouper.trimserver.server.systems.abilities.PatternInfo;
|
||||
import me.trouper.trimserver.utils.Text;
|
||||
import me.trouper.trimserver.utils.text.Text;
|
||||
import me.trouper.trimserver.utils.Verbose;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -22,6 +22,15 @@ import java.util.UUID;
|
||||
@PatternInfo(name = "Vex Set", description = "Not the Vex!!")
|
||||
public class VexAbility extends AbstractAbility {
|
||||
|
||||
public static final int NORMAL_COOLDOWN = 20 * 30;
|
||||
public static final int NORMAL_COUNT = 10;
|
||||
|
||||
public static final int NETHERITE_COOLDOWN = 20 * 45;
|
||||
public static final int NETHERITE_COUNT = 15;
|
||||
|
||||
public static final int RESIN_COOLDOWN = 20 * 20;
|
||||
public static final int RESIN_COUNT = 7;
|
||||
|
||||
public VexAbility() {
|
||||
super(TrimPattern.VEX);
|
||||
}
|
||||
@@ -101,111 +110,111 @@ public class VexAbility extends AbstractAbility {
|
||||
}
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Amethyst ", description = "Spawns 10 Purple Vex Loyal to you. They despawn after 15 seconds", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Amethyst ", description = "Spawns 10 Purple Vex Loyal to you. They despawn after 15 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean amethystAbility(Player player) {
|
||||
player.getWorld().playSound(player, Sound.ENTITY_EVOKER_PREPARE_WOLOLO,10,1);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int i = 0; i < NORMAL_COUNT; i++) {
|
||||
spawnLoyalVex(player, player.getEyeLocation(), NamedTextColor.LIGHT_PURPLE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Copper ", description = "Spawns 10 Gold Vex Loyal to you. They despawn after 15 seconds", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Copper ", description = "Spawns 10 Gold Vex Loyal to you. They despawn after 15 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean copperAbility(Player player) {
|
||||
player.getWorld().playSound(player, Sound.ENTITY_EVOKER_PREPARE_WOLOLO,10,1);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int i = 0; i < NORMAL_COUNT; i++) {
|
||||
spawnLoyalVex(player, player.getEyeLocation(), NamedTextColor.GOLD);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Diamond ", description = "Spawns 10 Aqua Vex Loyal to you. They despawn after 15 seconds", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Diamond ", description = "Spawns 10 Aqua Vex Loyal to you. They despawn after 15 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean diamondAbility(Player player) {
|
||||
player.getWorld().playSound(player, Sound.ENTITY_EVOKER_PREPARE_WOLOLO,10,1);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int i = 0; i < NORMAL_COUNT; i++) {
|
||||
spawnLoyalVex(player, player.getEyeLocation(), NamedTextColor.AQUA);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Emerald", description = "Spawns 10 Emerald Vex Loyal to you. They despawn after 15 seconds", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Emerald", description = "Spawns 10 Emerald Vex Loyal to you. They despawn after 15 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean emeraldAbility(Player player) {
|
||||
player.getWorld().playSound(player, Sound.ENTITY_EVOKER_PREPARE_WOLOLO,10,1);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int i = 0; i < NORMAL_COUNT; i++) {
|
||||
spawnLoyalVex(player, player.getEyeLocation(), NamedTextColor.DARK_GREEN);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Gold ", description = "Spawns 10 Yellow Vex Loyal to you. They despawn after 15 seconds", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Gold ", description = "Spawns 10 Yellow Vex Loyal to you. They despawn after 15 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean goldAbility(Player player) {
|
||||
player.getWorld().playSound(player, Sound.ENTITY_EVOKER_PREPARE_WOLOLO,10,1);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int i = 0; i < NORMAL_COUNT; i++) {
|
||||
spawnLoyalVex(player, player.getEyeLocation(), NamedTextColor.YELLOW);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Iron ", description = "Spawns 10 Gray Vex Loyal to you. They despawn after 15 seconds", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Iron ", description = "Spawns 10 Gray Vex Loyal to you. They despawn after 15 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean ironAbility(Player player) {
|
||||
player.getWorld().playSound(player, Sound.ENTITY_EVOKER_PREPARE_WOLOLO,10,1);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int i = 0; i < NORMAL_COUNT; i++) {
|
||||
spawnLoyalVex(player, player.getEyeLocation(), NamedTextColor.GRAY);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Lapis ", description = "Spawns 10 Blue Vex Loyal to you. They despawn after 15 seconds", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Lapis ", description = "Spawns 10 Blue Vex Loyal to you. They despawn after 15 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean lapisAbility(Player player) {
|
||||
player.getWorld().playSound(player, Sound.ENTITY_EVOKER_PREPARE_WOLOLO,10,1);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int i = 0; i < NORMAL_COUNT; i++) {
|
||||
spawnLoyalVex(player,player.getEyeLocation(),NamedTextColor.DARK_BLUE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Netherite ", description = "Spawns 15 Dark Vex Loyal to you. They despawn after 15 seconds", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Netherite ", description = "Spawns 15 Dark Vex Loyal to you. They despawn after 15 seconds", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@Override
|
||||
public boolean netheriteAbility(Player player) {
|
||||
player.getWorld().playSound(player, Sound.ENTITY_EVOKER_PREPARE_WOLOLO,10,1);
|
||||
for (int i = 0; i < 15; i++) {
|
||||
for (int i = 0; i < NETHERITE_COUNT; i++) {
|
||||
spawnLoyalVex(player,player.getEyeLocation(),NamedTextColor.DARK_GRAY);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Quartz ", description = "Spawns 10 White Vex Loyal to you. They despawn after 15 seconds", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Quartz ", description = "Spawns 10 White Vex Loyal to you. They despawn after 15 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean quartzAbility(Player player) {
|
||||
player.getWorld().playSound(player, Sound.ENTITY_EVOKER_PREPARE_WOLOLO,10,1);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int i = 0; i < NORMAL_COUNT; i++) {
|
||||
spawnLoyalVex(player,player.getEyeLocation(),NamedTextColor.WHITE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Redstone ", description = "Spawns 10 Red Vex Loyal to you. They despawn after 15 seconds", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Redstone ", description = "Spawns 10 Red Vex Loyal to you. They despawn after 15 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean redstoneAbility(Player player) {
|
||||
player.getWorld().playSound(player, Sound.ENTITY_EVOKER_PREPARE_WOLOLO,10,1);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int i = 0; i < NORMAL_COUNT; i++) {
|
||||
spawnLoyalVex(player,player.getEyeLocation(),NamedTextColor.RED);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Resin ", description = "Spawns 10 Gold Vex Loyal to you. They despawn after 15 seconds", cooldownTicks = 20 * 30)
|
||||
@MaterialInfo(name = "Resin ", description = "Spawns 10 Gold Vex Loyal to you. They despawn after 15 seconds", cooldownTicks = RESIN_COOLDOWN)
|
||||
@Override
|
||||
public boolean resinAbility(Player player) {
|
||||
player.getWorld().playSound(player, Sound.ENTITY_EVOKER_PREPARE_WOLOLO,10,1);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int i = 0; i < RESIN_COUNT; i++) {
|
||||
spawnLoyalVex(player,player.getEyeLocation(),NamedTextColor.GOLD);
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -6,11 +6,9 @@ import me.trouper.trimserver.server.systems.abilities.MaterialInfo;
|
||||
import me.trouper.trimserver.server.systems.abilities.AbstractAbility;
|
||||
import me.trouper.trimserver.server.systems.abilities.PatternInfo;
|
||||
import me.trouper.trimserver.utils.SoundPlayer;
|
||||
import me.trouper.trimserver.utils.Text;
|
||||
import me.trouper.trimserver.utils.text.Text;
|
||||
import me.trouper.trimserver.utils.Verbose;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.SculkSensor;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@@ -18,6 +16,7 @@ import org.bukkit.event.block.BlockReceiveGameEvent;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerToggleSneakEvent;
|
||||
@@ -34,10 +33,8 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
@PatternInfo(name = "Warden's Assistant", description = "You glazed the warden so much that he just ignores you now. Wardens and sculk sensors won't detect you.")
|
||||
public class WardAbility extends AbstractAbility {
|
||||
|
||||
// Map to track active disguises: player UUID -> disguise entity and task
|
||||
private final Map<UUID, DisguiseData> activeDisguises = new HashMap<>();
|
||||
|
||||
// Inner class to track disguise data
|
||||
private static class DisguiseData {
|
||||
final Warden disguise;
|
||||
final BukkitTask expirationTask;
|
||||
@@ -182,6 +179,15 @@ public class WardAbility extends AbstractAbility {
|
||||
removeDisguise(e.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDeath(PlayerDeathEvent e) {
|
||||
Verbose.send( "onPlayerQuit: %s", e.getPlayer().getName());
|
||||
if (!activeDisguises.containsKey(e.getPlayer().getUniqueId())) return;
|
||||
|
||||
Verbose.send( "Player %s died while disguised; removing disguise", e.getPlayer().getName());
|
||||
removeDisguise(e.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onSensor(BlockReceiveGameEvent e) {
|
||||
if (e.getBlock().getState() instanceof SculkSensor sensor
|
||||
|
||||
@@ -26,11 +26,23 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
@PatternInfo(name = "Big Step", description = "\"He boot too big for he gotdamn feet.\"")
|
||||
public class WayfinderAbility extends AbstractAbility {
|
||||
|
||||
public static final int NORMAL_COOLDOWN = 20 * 5;
|
||||
public static final double NORMAL_DAMAGE = 30;
|
||||
public static final double NORMAL_RADIUS = 10;
|
||||
|
||||
public static final int NETHERITE_COOLDOWN = 20 * 4;
|
||||
public static final double NETHERITE_DAMAGE = 40;
|
||||
public static final double NETHERITE_RADIUS = 15;
|
||||
|
||||
public static final int RESIN_COOLDOWN = 20 * 2;
|
||||
public static final double RESIN_DAMAGE = 20;
|
||||
public static final double RESIN_RADIUS = 4;
|
||||
|
||||
public WayfinderAbility() {
|
||||
super(TrimPattern.WAYFINDER);
|
||||
}
|
||||
|
||||
public void stomp(Player caster) {
|
||||
public void stomp(Player caster, double damage, double radius) {
|
||||
if (caster.getLocation().clone().subtract(0,1,0).getBlock().isPassable()) return;
|
||||
|
||||
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
|
||||
@@ -64,7 +76,7 @@ public class WayfinderAbility extends AbstractAbility {
|
||||
block.setCancelDrop(true);
|
||||
});
|
||||
|
||||
TargetingUtils.areaAffect(caster.getLocation(),10,target -> !target.isDead() &&
|
||||
TargetingUtils.areaAffect(caster.getLocation(),radius,target -> !target.isDead() &&
|
||||
!target.equals(caster) &&
|
||||
!main.man().trustBackend.trusts(caster,target) &&
|
||||
!shaper.activeShellTasks.containsKey(target.getUniqueId()) &&
|
||||
@@ -72,7 +84,7 @@ public class WayfinderAbility extends AbstractAbility {
|
||||
SoundPlayer hit = new SoundPlayer(target.getLocation(), Sound.ENTITY_EVOKER_FANGS_ATTACK, 1, 2);
|
||||
Vector direction = target.getLocation().toVector().subtract(caster.getEyeLocation().toVector()).normalize();
|
||||
target.setVelocity(direction.multiply(0.5).setY(0.3));
|
||||
target.damage(15, DamageSource.builder(DamageType.FALLING_BLOCK).build());
|
||||
target.damage(damage, DamageSource.builder(DamageType.FALLING_BLOCK).build());
|
||||
hit.playWithin(10);
|
||||
caster.getWorld().spawnParticle(Particle.DAMAGE_INDICATOR,target.getLocation().clone().add(0,1,0),10,0.2,1,0.2,0.1);
|
||||
});
|
||||
@@ -82,80 +94,80 @@ public class WayfinderAbility extends AbstractAbility {
|
||||
},10,2);
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Amethyst ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = 20 * 4)
|
||||
@MaterialInfo(name = "Amethyst ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean amethystAbility(Player player) {
|
||||
stomp(player);
|
||||
stomp(player,NORMAL_DAMAGE,NORMAL_RADIUS);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Copper ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = 20 * 4)
|
||||
@MaterialInfo(name = "Copper ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean copperAbility(Player player) {
|
||||
stomp(player);
|
||||
stomp(player,NORMAL_DAMAGE,NORMAL_RADIUS);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Diamond ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = 20 * 4)
|
||||
@MaterialInfo(name = "Diamond ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean diamondAbility(Player player) {
|
||||
stomp(player);
|
||||
stomp(player,NORMAL_DAMAGE,NORMAL_RADIUS);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Emerald Bolt", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = 20 * 4)
|
||||
@MaterialInfo(name = "Emerald Bolt", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean emeraldAbility(Player player) {
|
||||
stomp(player);
|
||||
stomp(player,NORMAL_DAMAGE,NORMAL_RADIUS);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Gold ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = 20 * 4)
|
||||
@MaterialInfo(name = "Gold ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean goldAbility(Player player) {
|
||||
stomp(player);
|
||||
stomp(player,NORMAL_DAMAGE,NORMAL_RADIUS);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Iron ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = 20 * 4)
|
||||
@MaterialInfo(name = "Iron ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean ironAbility(Player player) {
|
||||
stomp(player);
|
||||
stomp(player,NORMAL_DAMAGE,NORMAL_RADIUS);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Lapis ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = 20 * 4)
|
||||
@MaterialInfo(name = "Lapis ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean lapisAbility(Player player) {
|
||||
stomp(player);
|
||||
stomp(player,NORMAL_DAMAGE,NORMAL_RADIUS);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Netherite ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = 20 * 3)
|
||||
@MaterialInfo(name = "Netherite ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@Override
|
||||
public boolean netheriteAbility(Player player) {
|
||||
stomp(player);
|
||||
stomp(player,NETHERITE_DAMAGE,NETHERITE_RADIUS);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Quartz ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = 20 * 4)
|
||||
@MaterialInfo(name = "Quartz ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean quartzAbility(Player player) {
|
||||
stomp(player);
|
||||
stomp(player,NORMAL_DAMAGE,NORMAL_RADIUS);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Redstone ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = 20 * 4)
|
||||
@MaterialInfo(name = "Redstone ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean redstoneAbility(Player player) {
|
||||
stomp(player);
|
||||
stomp(player,NORMAL_DAMAGE,NORMAL_RADIUS);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Resin ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = 20 * 4)
|
||||
@MaterialInfo(name = "Resin ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = RESIN_COOLDOWN)
|
||||
@Override
|
||||
public boolean resinAbility(Player player) {
|
||||
stomp(player);
|
||||
stomp(player,RESIN_DAMAGE,RESIN_RADIUS);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ import org.bukkit.entity.BlockDisplay;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.meta.trim.TrimPattern;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
@@ -36,7 +38,6 @@ public class WildAbility extends AbstractAbility {
|
||||
if (shaper.activeShellTasks.containsKey(target.getUniqueId())) return;
|
||||
if (caster.getWorld() != target.getWorld()) return;
|
||||
|
||||
// --- Configuration ---
|
||||
final Location casterStartLoc = caster.getLocation().clone().add(0,1,0);
|
||||
final double maxDistance = 20.0;
|
||||
final double pullSpeed = 0.2;
|
||||
@@ -45,13 +46,13 @@ public class WildAbility extends AbstractAbility {
|
||||
final long updateInterval = 1L;
|
||||
final double minPullDistance = 2.0;
|
||||
|
||||
// --- Initial Check ---
|
||||
if (casterStartLoc.distanceSquared(target.getLocation()) > maxDistance * maxDistance) return;
|
||||
|
||||
caster.getWorld().playSound(casterStartLoc, Sound.ENTITY_FISHING_BOBBER_THROW, 1.0f, 0.8f);
|
||||
|
||||
target.addPotionEffect(new PotionEffect(PotionEffectType.POISON,4*20,1,true,false,false));
|
||||
|
||||
|
||||
// --- Task for Pulling & Visuals ---
|
||||
final List<BlockDisplay> currentVineSegment = new ArrayList<>(1);
|
||||
|
||||
new BukkitRunnable() {
|
||||
@@ -59,7 +60,6 @@ public class WildAbility extends AbstractAbility {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// --- Cancellation Conditions ---
|
||||
if (ticksElapsed >= pullDurationTicks ||
|
||||
!caster.isOnline() ||
|
||||
!target.isOnline() ||
|
||||
@@ -88,8 +88,7 @@ public class WildAbility extends AbstractAbility {
|
||||
target.setVelocity(target.getVelocity().add(pullVelocity));
|
||||
|
||||
|
||||
// --- Update Vine Visual ---
|
||||
|
||||
|
||||
BlockDisplay segment = BlockDisplayRaytracer.trace(
|
||||
vineMaterial,
|
||||
currentCasterPos,
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package me.trouper.trimserver.utils.misc;
|
||||
|
||||
public interface TimerScheduler {
|
||||
void runTimer(Runnable task, long initialDelayTicks, long periodTicks);
|
||||
void cancel();
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package me.trouper.trimserver.utils.text;
|
||||
|
||||
import net.kyori.adventure.bossbar.BossBar;
|
||||
|
||||
|
||||
public class BossBarConfig {
|
||||
public final int durationTicks;
|
||||
public final BossBar.Color color;
|
||||
public final BossBar.Overlay overlay;
|
||||
public final boolean changeColorOnLowTime;
|
||||
|
||||
public BossBarConfig(int durationTicks, BossBar.Color color, BossBar.Overlay overlay) {
|
||||
this(durationTicks, color, overlay, true);
|
||||
}
|
||||
|
||||
public BossBarConfig(int durationTicks, BossBar.Color color, BossBar.Overlay overlay, boolean changeColorOnLowTime) {
|
||||
this.durationTicks = durationTicks;
|
||||
this.color = color;
|
||||
this.overlay = overlay;
|
||||
this.changeColorOnLowTime = changeColorOnLowTime;
|
||||
}
|
||||
|
||||
public static BossBarConfig info(int durationTicks) {
|
||||
return new BossBarConfig(durationTicks, BossBar.Color.BLUE, BossBar.Overlay.PROGRESS);
|
||||
}
|
||||
|
||||
public static BossBarConfig warning(int durationTicks) {
|
||||
return new BossBarConfig(durationTicks, BossBar.Color.YELLOW, BossBar.Overlay.PROGRESS);
|
||||
}
|
||||
|
||||
public static BossBarConfig error(int durationTicks) {
|
||||
return new BossBarConfig(durationTicks, BossBar.Color.RED, BossBar.Overlay.PROGRESS);
|
||||
}
|
||||
|
||||
public static BossBarConfig success(int durationTicks) {
|
||||
return new BossBarConfig(durationTicks, BossBar.Color.GREEN, BossBar.Overlay.PROGRESS);
|
||||
}
|
||||
|
||||
public static BossBarConfig permanent() {
|
||||
return new BossBarConfig(0, BossBar.Color.PURPLE, BossBar.Overlay.PROGRESS, false);
|
||||
}
|
||||
|
||||
public static BossBarConfig timed(int durationTicks, BossBar.Color color) {
|
||||
return new BossBarConfig(durationTicks, color, BossBar.Overlay.PROGRESS);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
package me.trouper.trimserver.utils.text;
|
||||
|
||||
import net.kyori.adventure.bossbar.BossBar;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Static utility class for displaying text on configurable boss bars with timing features
|
||||
*/
|
||||
public class CustomBossBar {
|
||||
|
||||
private static final Map<UUID, PlayerBossBarData> activeBossBars = new ConcurrentHashMap<>();
|
||||
|
||||
// Private constructor to prevent instantiation
|
||||
private CustomBossBar() {}
|
||||
|
||||
/**
|
||||
* Shows a boss bar to a player with specified configuration
|
||||
*
|
||||
* @param plugin The plugin instance for scheduling tasks
|
||||
* @param player The player to show the boss bar to
|
||||
* @param text The text to display
|
||||
* @param config The boss bar configuration
|
||||
*/
|
||||
public static void showBossBar(Plugin plugin, Player player, Component text, BossBarConfig config) {
|
||||
UUID playerId = player.getUniqueId();
|
||||
|
||||
// Remove existing boss bar if present
|
||||
removeBossBar(player);
|
||||
|
||||
// Create new boss bar
|
||||
BossBar bossBar = BossBar.bossBar(text, 1.0f, config.color, config.overlay);
|
||||
|
||||
// Show to player
|
||||
player.showBossBar(bossBar);
|
||||
|
||||
// Create and store boss bar data
|
||||
PlayerBossBarData data = new PlayerBossBarData(bossBar, config);
|
||||
activeBossBars.put(playerId, data);
|
||||
|
||||
// Start countdown if duration is specified
|
||||
if (config.durationTicks > 0) {
|
||||
startCountdown(plugin, player, data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a boss bar with simple text and default configuration
|
||||
*
|
||||
* @param plugin The plugin instance for scheduling tasks
|
||||
* @param player The player to show the boss bar to
|
||||
* @param text The text to display
|
||||
* @param durationTicks How long to show the bar (in ticks)
|
||||
*/
|
||||
public static void showBossBar(Plugin plugin, Player player, String text, int durationTicks) {
|
||||
showBossBar(plugin, player, Component.text(text),
|
||||
new BossBarConfig(durationTicks, BossBar.Color.BLUE, BossBar.Overlay.PROGRESS));
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a boss bar with Component text and duration
|
||||
*
|
||||
* @param plugin The plugin instance for scheduling tasks
|
||||
* @param player The player to show the boss bar to
|
||||
* @param text The text component to display
|
||||
* @param durationTicks How long to show the bar (in ticks)
|
||||
*/
|
||||
public static void showBossBar(Plugin plugin, Player player, Component text, int durationTicks) {
|
||||
showBossBar(plugin, player, text,
|
||||
new BossBarConfig(durationTicks, BossBar.Color.BLUE, BossBar.Overlay.PROGRESS));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the text of an active boss bar
|
||||
*
|
||||
* @param player The player whose boss bar to update
|
||||
* @param newText The new text to display
|
||||
*/
|
||||
public static void updateBossBarText(Player player, Component newText) {
|
||||
PlayerBossBarData data = activeBossBars.get(player.getUniqueId());
|
||||
if (data != null) {
|
||||
data.bossBar.name(newText);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the text of an active boss bar
|
||||
*
|
||||
* @param player The player whose boss bar to update
|
||||
* @param newText The new text to display
|
||||
*/
|
||||
public static void updateBossBarText(Player player, String newText) {
|
||||
updateBossBarText(player, Component.text(newText));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the progress of an active boss bar
|
||||
*
|
||||
* @param player The player whose boss bar to update
|
||||
* @param progress The progress value (0.0 to 1.0)
|
||||
*/
|
||||
public static void updateBossBarProgress(Player player, float progress) {
|
||||
PlayerBossBarData data = activeBossBars.get(player.getUniqueId());
|
||||
if (data != null) {
|
||||
data.bossBar.progress(Math.max(0.0f, Math.min(1.0f, progress)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the color of an active boss bar
|
||||
*
|
||||
* @param player The player whose boss bar to update
|
||||
* @param color The new color
|
||||
*/
|
||||
public static void updateBossBarColor(Player player, BossBar.Color color) {
|
||||
PlayerBossBarData data = activeBossBars.get(player.getUniqueId());
|
||||
if (data != null) {
|
||||
data.bossBar.color(color);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the boss bar from a player
|
||||
*
|
||||
* @param player The player to remove the boss bar from
|
||||
*/
|
||||
public static void removeBossBar(Player player) {
|
||||
UUID playerId = player.getUniqueId();
|
||||
PlayerBossBarData data = activeBossBars.remove(playerId);
|
||||
|
||||
if (data != null) {
|
||||
// Cancel countdown task if running
|
||||
if (data.countdownTask != null && !data.countdownTask.isCancelled()) {
|
||||
data.countdownTask.cancel();
|
||||
}
|
||||
|
||||
// Hide boss bar
|
||||
player.hideBossBar(data.bossBar);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a player has an active boss bar
|
||||
*
|
||||
* @param player The player to check
|
||||
* @return true if the player has an active boss bar
|
||||
*/
|
||||
public static boolean hasBossBar(Player player) {
|
||||
return activeBossBars.containsKey(player.getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the remaining time for a player's boss bar in ticks
|
||||
*
|
||||
* @param player The player to check
|
||||
* @return remaining ticks, or -1 if no boss bar or infinite duration
|
||||
*/
|
||||
public static int getRemainingTicks(Player player) {
|
||||
PlayerBossBarData data = activeBossBars.get(player.getUniqueId());
|
||||
return data != null ? data.remainingTicks : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the remaining time for a player's boss bar in seconds
|
||||
*
|
||||
* @param player The player to check
|
||||
* @return remaining seconds, or -1 if no boss bar or infinite duration
|
||||
*/
|
||||
public static int getRemainingSeconds(Player player) {
|
||||
int ticks = getRemainingTicks(player);
|
||||
return ticks > 0 ? ticks / 20 : ticks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends the duration of an active boss bar
|
||||
*
|
||||
* @param player The player whose boss bar to extend
|
||||
* @param additionalTicks Additional ticks to add
|
||||
*/
|
||||
public static void extendBossBar(Player player, int additionalTicks) {
|
||||
PlayerBossBarData data = activeBossBars.get(player.getUniqueId());
|
||||
if (data != null && data.remainingTicks > 0) {
|
||||
data.remainingTicks += additionalTicks;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all active boss bars (useful for plugin disable)
|
||||
*/
|
||||
public static void removeAllBossBars() {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
removeBossBar(player);
|
||||
}
|
||||
activeBossBars.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of active boss bars
|
||||
*
|
||||
* @return number of active boss bars
|
||||
*/
|
||||
public static int getActiveBossBarCount() {
|
||||
return activeBossBars.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up disconnected players from the boss bar map
|
||||
*/
|
||||
public static void cleanupDisconnectedPlayers() {
|
||||
activeBossBars.entrySet().removeIf(entry -> {
|
||||
Player player = Bukkit.getPlayer(entry.getKey());
|
||||
if (player == null || !player.isOnline()) {
|
||||
PlayerBossBarData data = entry.getValue();
|
||||
if (data.countdownTask != null && !data.countdownTask.isCancelled()) {
|
||||
data.countdownTask.cancel();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
private static void startCountdown(Plugin plugin, Player player, PlayerBossBarData data) {
|
||||
data.remainingTicks = data.config.durationTicks;
|
||||
|
||||
data.countdownTask = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!player.isOnline()) {
|
||||
removeBossBar(player);
|
||||
return;
|
||||
}
|
||||
|
||||
data.remainingTicks--;
|
||||
|
||||
// Update progress bar based on remaining time
|
||||
float progress = (float) data.remainingTicks / data.config.durationTicks;
|
||||
data.bossBar.progress(Math.max(0.0f, progress));
|
||||
|
||||
// Change color based on remaining time if configured
|
||||
if (data.config.changeColorOnLowTime) {
|
||||
if (progress <= 0.2f) {
|
||||
data.bossBar.color(BossBar.Color.RED);
|
||||
} else if (progress <= 0.5f) {
|
||||
data.bossBar.color(BossBar.Color.YELLOW);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove when time is up
|
||||
if (data.remainingTicks <= 0) {
|
||||
removeBossBar(player);
|
||||
}
|
||||
}
|
||||
}.runTaskTimer(plugin, 0L, 1L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal class to hold boss bar data for each player
|
||||
*/
|
||||
private static class PlayerBossBarData {
|
||||
final BossBar bossBar;
|
||||
final BossBarConfig config;
|
||||
int remainingTicks;
|
||||
BukkitTask countdownTask;
|
||||
|
||||
PlayerBossBarData(BossBar bossBar, BossBarConfig config) {
|
||||
this.bossBar = bossBar;
|
||||
this.config = config;
|
||||
this.remainingTicks = config.durationTicks;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package me.trouper.trimserver.utils;
|
||||
package me.trouper.trimserver.utils.text;
|
||||
|
||||
import me.trouper.trimserver.server.Main;
|
||||
import net.kyori.adventure.text.Component;
|
||||
@@ -11,10 +11,7 @@ import org.bukkit.SoundCategory;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -286,4 +283,30 @@ public class Text implements Main {
|
||||
|
||||
return formatted.toString().trim();
|
||||
}
|
||||
|
||||
public static int getLevel(String s) {
|
||||
HashMap<Character, Integer> romanToInt = new HashMap<Character, Integer>();
|
||||
romanToInt.put(Character.valueOf('I'), 1);
|
||||
romanToInt.put(Character.valueOf('V'), 5);
|
||||
romanToInt.put(Character.valueOf('X'), 10);
|
||||
romanToInt.put(Character.valueOf('L'), 50);
|
||||
romanToInt.put(Character.valueOf('C'), 100);
|
||||
romanToInt.put(Character.valueOf('D'), 500);
|
||||
romanToInt.put(Character.valueOf('M'), 1000);
|
||||
int result = 0;
|
||||
for (int i = 0; i < s.length(); ++i) {
|
||||
if (i > 0 && romanToInt.get(Character.valueOf(s.charAt(i))) > romanToInt.get(Character.valueOf(s.charAt(i - 1)))) {
|
||||
result += romanToInt.get(Character.valueOf(s.charAt(i))) - 2 * romanToInt.get(Character.valueOf(s.charAt(i - 1)));
|
||||
continue;
|
||||
}
|
||||
if (romanToInt.get(Character.valueOf(s.charAt(i))) == null) {
|
||||
return 0;
|
||||
}
|
||||
result += (romanToInt.get(Character.valueOf(s.charAt(i)))).intValue();
|
||||
}
|
||||
if (result > 255) {
|
||||
result = 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
package me.trouper.trimserver.utils.visual;
|
||||
|
||||
import me.trouper.trimserver.utils.Text;
|
||||
import me.trouper.trimserver.utils.Verbose;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -6,14 +6,15 @@ prefix: TrimServer
|
||||
load: STARTUP
|
||||
authors: [ obvWolf ]
|
||||
depend: [ WorldGuard ]
|
||||
softdepend: [ PlaceholderAPI ]
|
||||
description: Armor trims give you abilities
|
||||
commands:
|
||||
trims:
|
||||
permission: trims.admin
|
||||
description: Command for managing trims.
|
||||
info:
|
||||
triminfo:
|
||||
description: Provides info on armor trim abilities.
|
||||
usage: /info <trim>
|
||||
usage: /triminfo <trim>
|
||||
trust:
|
||||
description: Make your friends immune to your abilities.
|
||||
usage: "<add|remove|list> <player>"
|
||||
|
||||
Reference in New Issue
Block a user