Updated some raytracer stuff, made eye always on the plane.
This commit is contained in:
@@ -26,11 +26,13 @@ import org.bukkit.inventory.meta.trim.ArmorTrim;
|
||||
import org.bukkit.inventory.meta.trim.TrimMaterial;
|
||||
import org.bukkit.inventory.meta.trim.TrimPattern;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
@CommandRegistry(value = "trims",permission = @Permission("trims.admin"),printStackTrace = true)
|
||||
public class AdminCommand implements QuickCommand {
|
||||
|
||||
public static final Set<UUID> adminBypass = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public void dispatchCommand(CommandSender commandSender, Command command, String s, Args args) {
|
||||
if (args.getSize() < 1) {
|
||||
@@ -42,13 +44,14 @@ public class AdminCommand implements QuickCommand {
|
||||
case "try" -> handleTry(commandSender,args);
|
||||
case "test" -> handleTest(commandSender,args);
|
||||
case "give" -> handleGive(commandSender,args);
|
||||
case "bypass" -> handleBypass(commandSender,args);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchCompletions(CommandSender commandSender, Command command, String s, CompletionBuilder b) {
|
||||
b.then(
|
||||
b.arg("reload")
|
||||
b.arg("reload","bypass")
|
||||
).then(
|
||||
b.arg("debug")
|
||||
.then(
|
||||
@@ -104,6 +107,18 @@ public class AdminCommand implements QuickCommand {
|
||||
);
|
||||
}
|
||||
|
||||
private void handleBypass(CommandSender sender, Args args) {
|
||||
if (!(sender instanceof Player p)) {
|
||||
error(sender,"This sub-command is player only.");
|
||||
return;
|
||||
}
|
||||
if (adminBypass.remove(p.getUniqueId())) {
|
||||
success(sender, "You are {0} bypassing ability restrictions.","now");
|
||||
} else if (adminBypass.add(p.getUniqueId())) {
|
||||
success(sender, "You are {0} bypassing ability restrictions.","no longer");
|
||||
}
|
||||
}
|
||||
|
||||
private void handleGive(CommandSender commandSender, Args args) {
|
||||
switch (args.get(1).toString()) {
|
||||
case "consumable" -> {
|
||||
|
||||
@@ -10,6 +10,7 @@ import io.papermc.paper.registry.RegistryAccess;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import me.trouper.trimserver.server.Main;
|
||||
import me.trouper.trimserver.server.api.AbilityFlag;
|
||||
import me.trouper.trimserver.server.commands.AdminCommand;
|
||||
import me.trouper.trimserver.server.systems.abilities.MaterialInfo;
|
||||
import me.trouper.trimserver.server.systems.abilities.AbstractAbility;
|
||||
import me.trouper.trimserver.utils.text.Text;
|
||||
@@ -285,13 +286,12 @@ public class AbilityBackend implements Main {
|
||||
|
||||
AbilityCooldown cooldownKey = new AbilityCooldown(player.getUniqueId(), info.getValidPattern().getCanonical(), info.getValidMaterial().getCanonical());
|
||||
|
||||
if (onCooldown.isOnCooldown(cooldownKey)) return false;
|
||||
|
||||
if (!AdminCommand.adminBypass.contains(player.getUniqueId()) && onCooldown.isOnCooldown(cooldownKey)) return false;
|
||||
|
||||
try {
|
||||
boolean applyCooldown = abilityAllowed(player, player.getLocation()) && ability.dispatchAbility(info.getValidMaterial(), player);
|
||||
|
||||
if (cooldownTicks > 0 && applyCooldown) onCooldown.addCooldown(cooldownKey, (long) cooldownTicks * 50L);
|
||||
if (cooldownTicks > 0 && applyCooldown) onCooldown.setCooldown(cooldownKey, (long) cooldownTicks * 50L);
|
||||
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
@@ -346,6 +346,7 @@ public class AbilityBackend implements Main {
|
||||
* @return true if the ability is allowed, false otherwise
|
||||
*/
|
||||
public boolean abilityAllowed(Player player, Location useLocation) {
|
||||
if (AdminCommand.adminBypass.contains(player.getUniqueId())) return true;
|
||||
LocalPlayer user = WorldGuardPlugin.inst().wrapPlayer(player);
|
||||
|
||||
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package me.trouper.trimserver.server.systems;
|
||||
|
||||
import me.trouper.trimserver.server.Main;
|
||||
import me.trouper.trimserver.server.commands.AdminCommand;
|
||||
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 net.kyori.adventure.text.format.TextColor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.meta.trim.TrimMaterial;
|
||||
@@ -52,14 +54,16 @@ public class PollingBackend implements Main {
|
||||
elapsedMillis = Math.max(0, elapsedMillis);
|
||||
elapsedMillis = Math.min(totalDurationMillis, elapsedMillis);
|
||||
|
||||
bar = bar.append(Component.text("Ability Recharging: ", NamedTextColor.WHITE))
|
||||
bar = bar.append(Component.text("Ability Recharging: ", TextColor.color(0xFFAAAA)))
|
||||
.append(Text.color(Text.generateProgressBar(20, (int)totalDurationMillis, (int)elapsedMillis)));
|
||||
} else {
|
||||
bar = bar.append(Component.text("Ability Ready", NamedTextColor.namedColor(0x00FFAA)));
|
||||
bar = bar.append(Component.text("Ability Ready", TextColor.color(0x00FFAA)));
|
||||
}
|
||||
|
||||
bar = bar.append(Text.formatArgs(Text.Pallet.INFO," /info {0} for usage",Text.formatEnum(AbilityBackend.ValidPattern.validate(pattern))));
|
||||
bar = bar.append(Text.formatArgs(Text.Pallet.INFO," /triminfo {0} for usage",Text.formatEnum(AbilityBackend.ValidPattern.validate(pattern))));
|
||||
|
||||
if (AdminCommand.adminBypass.contains(player.getUniqueId())) bar = bar.append(Component.text(" (Admin Mode)",TextColor.color(0x99ffaa)));
|
||||
|
||||
player.sendActionBar(bar);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,30 +7,33 @@ 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.misc.Randomizer;
|
||||
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.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.meta.trim.TrimPattern;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
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 = 6;
|
||||
public static final double NORMAL_DAMAGE = 4;
|
||||
|
||||
public static final int RESIN_COOLDOWN = 20 * 5;
|
||||
public static final double RESIN_DAMAGE = 4;
|
||||
public static final int RESIN_COOLDOWN = 20 * 7;
|
||||
public static final double RESIN_DAMAGE = 3;
|
||||
|
||||
public static final int NETHERITE_COOLDOWN = 20 * 15;
|
||||
public static final double NETHERITE_DAMAGE = 8;
|
||||
public static final double NETHERITE_DAMAGE = 5;
|
||||
|
||||
public BoltAbility() {
|
||||
super(TrimPattern.BOLT);
|
||||
@@ -39,48 +42,54 @@ public class BoltAbility extends AbstractAbility implements Main {
|
||||
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;
|
||||
|
||||
return TargetingUtils.areaAffect(caster.getLocation(),range,target-> !main.man().trustBackend.trusts(caster,target) &&
|
||||
|
||||
Optional<LivingEntity> hit = TargetingUtils.livingClosestAngle(caster.getEyeLocation(),caster.getEyeLocation().getDirection(),20,1, target-> !main.man().trustBackend.trusts(caster,target) &&
|
||||
!shaper.activeShellTasks.containsKey(target.getUniqueId()) &&
|
||||
main.man().abilityBackend.abilityAllowed(caster,target.getLocation()),(target) ->{
|
||||
PlayerUtils.dealTrueDamage(target,DamageSource.builder(DamageType.LIGHTNING_BOLT).withDamageLocation(caster.getEyeLocation()).build(),damage);
|
||||
if (target instanceof Player t) Text.sendMessage(Text.Pallet.INFO,t,"You have been stunned by {0}'s Bolt!",caster.getName());
|
||||
main.man().abilityBackend.abilityAllowed(caster,target.getLocation()));
|
||||
|
||||
if (hit.isEmpty()) return false;
|
||||
|
||||
LivingEntity target = hit.get();
|
||||
PlayerUtils.dealTrueDamage(target,DamageSource.builder(DamageType.LIGHTNING_BOLT).withDamageLocation(caster.getEyeLocation()).build(),damage);
|
||||
|
||||
if (target instanceof Player t) Text.sendMessage(Text.Pallet.INFO,t,"You have been stunned by {0}'s Bolt!",caster.getName());
|
||||
|
||||
SoundPlayer bolt = new SoundPlayer(target.getLocation(), Sound.ENTITY_LIGHTNING_BOLT_THUNDER,10,1);
|
||||
SoundPlayer ring = new SoundPlayer(target.getLocation(), Sound.ITEM_TRIDENT_THUNDER,10,2);
|
||||
SoundPlayer zip = new SoundPlayer(target.getLocation(), Sound.ENTITY_BEE_STING,10,1);
|
||||
SoundPlayer bolt = new SoundPlayer(target.getLocation(), Sound.ENTITY_LIGHTNING_BOLT_THUNDER,10,1);
|
||||
SoundPlayer ring = new SoundPlayer(target.getLocation(), Sound.ITEM_TRIDENT_THUNDER,10,1.5F);
|
||||
SoundPlayer zip = new SoundPlayer(target.getLocation(), Sound.ENTITY_BEE_DEATH,10,2);
|
||||
|
||||
bolt.playWithin(50);
|
||||
ring.playWithin(30);
|
||||
bolt.playWithin(50);
|
||||
ring.playWithin(30);
|
||||
|
||||
AtomicInteger counter = new AtomicInteger(0);
|
||||
Bukkit.getScheduler().runTaskTimer(main.getPlugin(),(task) -> {
|
||||
if (counter.getAndIncrement() > 40) {
|
||||
task.cancel();
|
||||
return;
|
||||
}
|
||||
int tick = target.getNoDamageTicks();
|
||||
int maxTick = target.getMaximumNoDamageTicks();
|
||||
AtomicInteger counter = new AtomicInteger(0);
|
||||
Bukkit.getScheduler().runTaskTimer(main.getPlugin(),(task) -> {
|
||||
if (counter.getAndIncrement() > 50) {
|
||||
task.cancel();
|
||||
return;
|
||||
}
|
||||
int tick = target.getNoDamageTicks();
|
||||
int maxTick = target.getMaximumNoDamageTicks();
|
||||
|
||||
if (counter.get() % 5 == 0) zip.playWithin(30);
|
||||
target.setNoDamageTicks(0);
|
||||
target.setMaximumNoDamageTicks(1);
|
||||
target.damage(0.01,DamageSource.builder(DamageType.LIGHTNING_BOLT).withDamageLocation(caster.getLocation()).withDirectEntity(caster).build());
|
||||
target.setNoDamageTicks(tick);
|
||||
target.setMaximumNoDamageTicks(maxTick);
|
||||
Location stunLoc = target.getLocation().clone();
|
||||
target.teleport(stunLoc);
|
||||
drawLightning(caster.getEyeLocation().subtract(0,0.5,0),target.getEyeLocation(),innerBlock,outerBlock);
|
||||
},0,1);
|
||||
});
|
||||
if (counter.get() % 5 == 0) zip.playWithin(30);
|
||||
target.setNoDamageTicks(0);
|
||||
target.setMaximumNoDamageTicks(1);
|
||||
target.damage(0.01,DamageSource.builder(DamageType.LIGHTNING_BOLT).withDamageLocation(caster.getLocation()).withDirectEntity(caster).build());
|
||||
target.setNoDamageTicks(tick);
|
||||
target.setMaximumNoDamageTicks(maxTick);
|
||||
Location stunLoc = target.getLocation().clone();
|
||||
target.teleport(stunLoc);
|
||||
drawLightning(caster.getEyeLocation().subtract(0,0.5,0),target.getEyeLocation(),innerBlock,outerBlock);
|
||||
},0,1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void drawLightning(Location start, Location end, Material blockInner, Material blockOuter) {
|
||||
int segments = 10;
|
||||
double maxOffset = 0.5;
|
||||
long stayTime = 10L;
|
||||
double thickness = 0.01;
|
||||
double thicknessOut = 0.05;
|
||||
double thickness = 0.02;
|
||||
double thicknessOut = 0.04;
|
||||
List<Player> viewers = new ArrayList<>(start.getWorld().getPlayers());
|
||||
|
||||
Location current = start.clone();
|
||||
@@ -98,75 +107,75 @@ public class BoltAbility extends AbstractAbility implements Main {
|
||||
|
||||
BlockDisplayRaytracer.trace(blockInner, current, next, thickness, stayTime, viewers);
|
||||
BlockDisplayRaytracer.trace(blockOuter, current, next, thicknessOut, stayTime, viewers);
|
||||
next.getWorld().spawnParticle(Particle.FLASH,next,0,0,0,0,0);
|
||||
current = next;
|
||||
}
|
||||
|
||||
|
||||
BlockDisplayRaytracer.trace(blockInner, current, end, thickness, stayTime, viewers);
|
||||
BlockDisplayRaytracer.trace(blockOuter, current, end, thicknessOut, stayTime, viewers);
|
||||
end.getWorld().spawnParticle(Particle.FLASH,end,0,0,0,0,0);
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Amethyst Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 10 Damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Amethyst Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 4 true Damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean amethystAbility(Player player) {
|
||||
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 = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Copper Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 4 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean copperAbility(Player player) {
|
||||
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 = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Diamond Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 4 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean diamondAbility(Player player) {
|
||||
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 = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Emerald ",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 4 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean emeraldAbility(Player player) {
|
||||
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 = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Gold Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 4 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean goldAbility(Player player) {
|
||||
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 = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Iron Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 4 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean ironAbility(Player player) {
|
||||
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 = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Lapis Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 4 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean lapisAbility(Player player) {
|
||||
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 = NETHERITE_COOLDOWN)
|
||||
@MaterialInfo(name = "Netherite Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 5 true damage", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@Override
|
||||
public boolean netheriteAbility(Player player) {
|
||||
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 = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Quartz Bolt",description = "Shoots a bolt of overcharged lightning at your closest enemy within 20 blocks. Deals 4 true Damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean quartzAbility(Player player) {
|
||||
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 = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Redstone Bolt",description = "Shoots a bolt of colored lightning at your closest enemy within 20 blocks. Deals 4 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean redstoneAbility(Player player) {
|
||||
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 = RESIN_COOLDOWN)
|
||||
@MaterialInfo(name = "Resin Bolt",description = "Shoots a bolt of resin lightning at your closest enemy within 20 blocks. Deals 3 true", cooldownTicks = RESIN_COOLDOWN)
|
||||
@Override
|
||||
public boolean resinAbility(Player player) {
|
||||
return strike(player,20,RESIN_DAMAGE,Material.RESIN_BLOCK,Material.ORANGE_STAINED_GLASS);
|
||||
|
||||
@@ -5,6 +5,7 @@ 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.text.CustomBossBar;
|
||||
import me.trouper.trimserver.utils.visual.BlockDisplayRaytracer;
|
||||
import me.trouper.trimserver.utils.visual.CustomDisplayRaytracer;
|
||||
import org.bukkit.*;
|
||||
@@ -35,7 +36,7 @@ public class EyeAbility extends AbstractAbility {
|
||||
public static final double NETHERITE_DAMAGE_CHANCE = 1.0;
|
||||
|
||||
public static final int RESIN_COOLDOWN = 20 * 20;
|
||||
public static final long RESIN_DURATION = 2;
|
||||
public static final int RESIN_DURATION = 2;
|
||||
public static final double RESIN_DAMAGE = 0.1;
|
||||
public static final double RESIN_DAMAGE_CHANCE = 0.60;
|
||||
|
||||
@@ -43,10 +44,14 @@ public class EyeAbility extends AbstractAbility {
|
||||
super(TrimPattern.EYE);
|
||||
}
|
||||
|
||||
public void eyeLasers(Player player, Material beam,Material glow, long durationSeconds, double damagePerTick, double damageFailChance) {
|
||||
public void eyeLasers(Player player, Material beam,Material glow, int durationSeconds, double damagePerTick, double damageFailChance) {
|
||||
|
||||
CustomBossBar.showBossBar(main.getPlugin(),player,"Laser Eyes",durationSeconds * 20);
|
||||
|
||||
AtomicInteger timer = new AtomicInteger(0);
|
||||
Bukkit.getScheduler().runTaskTimer(main.getPlugin(),(task)->{
|
||||
if (timer.getAndIncrement() >= durationSeconds * 20) {
|
||||
CustomBossBar.removeBossBar(player);
|
||||
task.cancel();
|
||||
return;
|
||||
}
|
||||
@@ -110,77 +115,77 @@ public class EyeAbility extends AbstractAbility {
|
||||
}).getLoc();
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Amethyst Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Amethyst Laser beam", description = "Shoot lasers from your eyes", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean amethystAbility(Player player) {
|
||||
eyeLasers(player,Material.PURPLE_CONCRETE_POWDER,Material.MAGENTA_STAINED_GLASS,NORMAL_DURATION,NORMAL_DAMAGE, NORMAL_DAMAGE_CHANCE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Copper Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Copper Laser beam", description = "Shoot lasers from your eyes", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean copperAbility(Player player) {
|
||||
eyeLasers(player,Material.LIME_TERRACOTTA,Material.GREEN_STAINED_GLASS,NORMAL_DURATION,NORMAL_DAMAGE, NORMAL_DAMAGE_CHANCE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Diamond Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Diamond Laser beam", description = "Shoot lasers from your eyes", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean diamondAbility(Player player) {
|
||||
eyeLasers(player,Material.LIGHT_BLUE_CONCRETE_POWDER,Material.LIGHT_BLUE_STAINED_GLASS,NORMAL_DURATION,NORMAL_DAMAGE, NORMAL_DAMAGE_CHANCE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Emerald Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Emerald Laser beam", description = "Shoot lasers from your eyes", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean emeraldAbility(Player player) {
|
||||
eyeLasers(player,Material.LIME_CONCRETE_POWDER,Material.LIME_STAINED_GLASS,NORMAL_DURATION,NORMAL_DAMAGE, NORMAL_DAMAGE_CHANCE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Gold Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Gold Laser beam", description = "Shoot lasers from your eyes", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean goldAbility(Player player) {
|
||||
eyeLasers(player,Material.YELLOW_TERRACOTTA,Material.YELLOW_STAINED_GLASS,NORMAL_DURATION,NORMAL_DAMAGE, NORMAL_DAMAGE_CHANCE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Iron Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Iron Laser beam", description = "Shoot lasers from your eyes", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean ironAbility(Player player) {
|
||||
eyeLasers(player,Material.LIGHT_GRAY_CONCRETE_POWDER,Material.LIGHT_GRAY_STAINED_GLASS,NORMAL_DURATION,NORMAL_DAMAGE, NORMAL_DAMAGE_CHANCE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Lapis Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Lapis Laser beam", description = "Shoot lasers from your eyes", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean lapisAbility(Player player) {
|
||||
eyeLasers(player,Material.BLUE_CONCRETE,Material.BLUE_STAINED_GLASS,NORMAL_DURATION,NORMAL_DAMAGE, NORMAL_DAMAGE_CHANCE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Netherite Laser beam", description = "Shoot lasers from the eye on the chestpiece for 10 seconds", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@MaterialInfo(name = "Netherite Laser beam", description = "Shoot lasers from your eyes", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@Override
|
||||
public boolean netheriteAbility(Player player) {
|
||||
eyeLasers(player,Material.BLACK_CONCRETE,Material.BLACK_STAINED_GLASS,NETHERITE_DURATION,NETHERITE_DAMAGE, NETHERITE_DAMAGE_CHANCE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Quartz Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Quartz Laser beam", description = "Shoot lasers from your eyes", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean quartzAbility(Player player) {
|
||||
eyeLasers(player,Material.WHITE_CONCRETE_POWDER,Material.WHITE_STAINED_GLASS,NORMAL_DURATION,NORMAL_DAMAGE, NORMAL_DAMAGE_CHANCE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Redstone Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Redstone Laser beam", description = "Shoot lasers from your eyes", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean redstoneAbility(Player player) {
|
||||
eyeLasers(player,Material.RED_CONCRETE,Material.RED_STAINED_GLASS,NORMAL_DURATION,NORMAL_DAMAGE, NORMAL_DAMAGE_CHANCE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Resin Laser beam", description = "Shoot lasers from the eye on the chestpiece for 5 seconds", cooldownTicks = RESIN_COOLDOWN)
|
||||
@MaterialInfo(name = "Resin Laser beam", description = "Shoot lasers from your eyes", cooldownTicks = RESIN_COOLDOWN)
|
||||
@Override
|
||||
public boolean resinAbility(Player player) {
|
||||
eyeLasers(player,Material.ORANGE_CONCRETE_POWDER,Material.ORANGE_STAINED_GLASS,RESIN_DURATION,RESIN_DAMAGE, RESIN_DAMAGE_CHANCE);
|
||||
|
||||
@@ -89,7 +89,7 @@ public class HostAbility extends AbstractAbility {
|
||||
}
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Amethyst ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Amethyst ", description = "Grants true invisibility for 5 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean amethystAbility(Player player) {
|
||||
makeInvisible(player,NORMAL_DURATION);
|
||||
@@ -97,7 +97,7 @@ public class HostAbility extends AbstractAbility {
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Copper ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Copper ", description = "Grants true invisibility for 5 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean copperAbility(Player player) {
|
||||
makeInvisible(player,NORMAL_DURATION);
|
||||
@@ -105,7 +105,7 @@ public class HostAbility extends AbstractAbility {
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Diamond ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Diamond ", description = "Grants true invisibility for 5 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean diamondAbility(Player player) {
|
||||
makeInvisible(player,NORMAL_DURATION);
|
||||
@@ -113,7 +113,7 @@ public class HostAbility extends AbstractAbility {
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Emerald ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Emerald ", description = "Grants true invisibility for 5 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean emeraldAbility(Player player) {
|
||||
makeInvisible(player,NORMAL_DURATION);
|
||||
@@ -121,7 +121,7 @@ public class HostAbility extends AbstractAbility {
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Gold ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Gold ", description = "Grants true invisibility for 5 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean goldAbility(Player player) {
|
||||
makeInvisible(player,NORMAL_DURATION);
|
||||
@@ -129,7 +129,7 @@ public class HostAbility extends AbstractAbility {
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Iron ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Iron ", description = "Grants true invisibility for 5 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean ironAbility(Player player) {
|
||||
makeInvisible(player,NORMAL_DURATION);
|
||||
@@ -137,7 +137,7 @@ public class HostAbility extends AbstractAbility {
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Lapis ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Lapis ", description = "Grants true invisibility for 5 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean lapisAbility(Player player) {
|
||||
makeInvisible(player,NORMAL_DURATION);
|
||||
@@ -145,7 +145,7 @@ public class HostAbility extends AbstractAbility {
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Netherite ", description = "Grants true invisibility for 10 seconds and makes your attacks stronger", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@MaterialInfo(name = "Netherite ", description = "Grants true invisibility for 8 seconds and makes your attacks stronger", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@Override
|
||||
public boolean netheriteAbility(Player player) {
|
||||
makeInvisible(player,NETHERITE_DURATION);
|
||||
@@ -153,7 +153,7 @@ public class HostAbility extends AbstractAbility {
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Quartz ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Quartz ", description = "Grants true invisibility for 5 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean quartzAbility(Player player) {
|
||||
makeInvisible(player,NORMAL_DURATION);
|
||||
@@ -161,7 +161,7 @@ public class HostAbility extends AbstractAbility {
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Redstone ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Redstone ", description = "Grants true invisibility for 5 seconds but makes your attacks weaker", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean redstoneAbility(Player player) {
|
||||
makeInvisible(player,NORMAL_DURATION);
|
||||
@@ -169,11 +169,10 @@ public class HostAbility extends AbstractAbility {
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Resin ", description = "Grants true invisibility for 6 seconds but makes your attacks weaker", cooldownTicks = RESIN_COOLDOWN)
|
||||
@MaterialInfo(name = "Resin ", description = "Grants true invisibility for 3 seconds.", cooldownTicks = RESIN_COOLDOWN)
|
||||
@Override
|
||||
public boolean resinAbility(Player player) {
|
||||
makeInvisible(player,NORMAL_DURATION);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS,RESIN_DURATION * 10,0,true,false,true));
|
||||
makeInvisible(player,RESIN_DURATION);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,13 +24,13 @@ 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 NORMAL_DURATION = 10;
|
||||
public static final int NORMAL_COOLDOWN = 20 * 45;
|
||||
|
||||
public static final int NETHERITE_DURATION = 20;
|
||||
public static final int NETHERITE_COOLDOWN = 20 * 30;
|
||||
public static final int NETHERITE_DURATION = 15;
|
||||
public static final int NETHERITE_COOLDOWN = 20 * 40;
|
||||
|
||||
public static final int RESIN_DURATION = 10;
|
||||
public static final int RESIN_DURATION = 5;
|
||||
public static final int RESIN_COOLDOWN = 20 * 15;
|
||||
|
||||
public RaiserAbility() {
|
||||
|
||||
@@ -66,7 +66,7 @@ public class RibAbility extends AbstractAbility {
|
||||
!shaper.activeShellTasks.containsKey(liv.getUniqueId())
|
||||
&& main.man().abilityBackend.abilityAllowed(caster, liv.getLocation()),
|
||||
target->{
|
||||
target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS,20*20,1,true,false,false));
|
||||
target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS,20*6,1,true,false,false));
|
||||
target.setFireTicks(20*20);
|
||||
});
|
||||
});
|
||||
@@ -162,8 +162,7 @@ public class RibAbility extends AbstractAbility {
|
||||
damageDealt = true;
|
||||
|
||||
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));
|
||||
target.setVelocity(target.getVelocity().add(new Vector(0,0.5,0)));
|
||||
new SoundPlayer(target.getLocation(), Sound.ENTITY_PLAYER_HURT_ON_FIRE, 1.0f, 1.0f).playWithin(15);
|
||||
world.spawnParticle(Particle.LAVA, target.getEyeLocation(), 8, 0.2, 0.2, 0.2, 0);
|
||||
world.spawnParticle(Particle.ASH, target.getLocation(), 20, 0.5,0.5,0.5,0);
|
||||
|
||||
@@ -10,6 +10,7 @@ import me.trouper.trimserver.utils.text.Text;
|
||||
import me.trouper.trimserver.utils.visual.BlockDisplayRaytracer;
|
||||
import me.trouper.trimserver.utils.visual.CustomDisplayRaytracer;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.damage.DamageSource;
|
||||
import org.bukkit.damage.DamageType;
|
||||
@@ -76,7 +77,9 @@ public class SentryAbility extends AbstractAbility {
|
||||
|
||||
Shulker dummy = w.spawn(turret.getLocation().clone().subtract(0,3,0),Shulker.class,shulker->{
|
||||
shulker.setInvisible(true);
|
||||
shulker.setHealth(10);
|
||||
shulker.registerAttribute(Attribute.MAX_HEALTH);
|
||||
shulker.getAttribute(Attribute.MAX_HEALTH).setBaseValue(40);
|
||||
shulker.setHealth(40);
|
||||
shulker.customName(Text.color("%s's Sentry\n".formatted(owner.getName())));
|
||||
shulker.setAI(false);
|
||||
shulker.addScoreboardTag("$/TrimServer/ Temp");
|
||||
@@ -95,7 +98,7 @@ public class SentryAbility extends AbstractAbility {
|
||||
legsMat,
|
||||
start,
|
||||
end.toVector().subtract(start.toVector()),
|
||||
0.1, // leg thickness
|
||||
0.1,
|
||||
start.distance(end),
|
||||
20 * secondsAlive + 1
|
||||
));
|
||||
@@ -129,12 +132,13 @@ public class SentryAbility extends AbstractAbility {
|
||||
String bar = Text.generateProgressBar(10, maxAmmo, chamber);
|
||||
meter.text(Text.color("%s's Sentry\n".formatted(owner.getName()) + "Ammo " + bar));
|
||||
|
||||
Optional<LivingEntity> target = TargetingUtils.getClosestLivingEntity(finalLoc,15,p -> !p.isDead() &&
|
||||
Optional<LivingEntity> target = TargetingUtils.getClosestLivingEntity(finalLoc,15,liv ->
|
||||
!liv.isDead() && (liv instanceof Player p &&
|
||||
!p.equals(owner) &&
|
||||
!main.man().trustBackend.trusts(owner,p) &&
|
||||
!shaper.activeShellTasks.containsKey(p.getUniqueId()) &&
|
||||
PlayerUtils.combatAllowed(p,owner) &&
|
||||
!p.equals(dummy)
|
||||
PlayerUtils.combatAllowed(p,owner)) ||
|
||||
(liv instanceof Enemy m && !m.equals(dummy))
|
||||
);
|
||||
|
||||
if (target.isPresent()) {
|
||||
@@ -145,14 +149,15 @@ public class SentryAbility extends AbstractAbility {
|
||||
.subtract(turret.getLocation().toVector());
|
||||
Vector dir = toEye.clone().normalize();
|
||||
|
||||
float yaw = (float)(Math.toDegrees(Math.atan2(dir.getZ(), dir.getX())) - 90 + 180);
|
||||
float yaw = (float)(Math.toDegrees(Math.atan2(dir.getZ(), dir.getX())) - 90 + 180);
|
||||
float pitch = (float)(Math.toDegrees(Math.asin(dir.getY())));
|
||||
turret.setRotation(yaw, pitch);
|
||||
|
||||
w.spawnParticle(Particle.FLASH, turret.getLocation(), 1, 0,0,0, 0);
|
||||
|
||||
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 Shulker) && !living.isDead() && living != owner;
|
||||
return entity instanceof LivingEntity living && !(living.equals(dummy)) && !living.isDead() && living != owner;
|
||||
}));
|
||||
hits.forEach(t -> {
|
||||
if (t instanceof LivingEntity liv) {
|
||||
|
||||
@@ -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.attribute.Attribute;
|
||||
import org.bukkit.attribute.AttributeModifier;
|
||||
@@ -58,6 +59,7 @@ public class ShaperAbility extends AbstractAbility implements Listener {
|
||||
UUID playerUUID = player.getUniqueId();
|
||||
|
||||
if (activeShellTasks.containsKey(playerUUID)) return;
|
||||
CustomBossBar.showBossBar(main.getPlugin(),player,"Terra Shell",duration);
|
||||
|
||||
World world = player.getWorld();
|
||||
List<BlockDisplay> shellParts = new ArrayList<>();
|
||||
@@ -111,6 +113,7 @@ public class ShaperAbility extends AbstractAbility implements Listener {
|
||||
if (!player.isOnline() || ticksElapsed >= finalDuration) {
|
||||
shatterShell(player, finalShatterDamage, finalShatterRadius, blockMaterialForShell);
|
||||
cleanupShellProperties(playerUUID, player);
|
||||
CustomBossBar.removeBossBar(player);
|
||||
cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -27,15 +27,15 @@ 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;
|
||||
// Damage is true once again
|
||||
public static final double NORMAL_DAMAGE = 7;
|
||||
public static final int NORMAL_COOLDOWN = 20 * 25;
|
||||
|
||||
public static final double NETHERITE_DAMAGE = 30;
|
||||
public static final int NETHERITE_COOLDOWN = 20 * 12;
|
||||
public static final double NETHERITE_DAMAGE = 10;
|
||||
public static final int NETHERITE_COOLDOWN = 20 * 22;
|
||||
|
||||
public static final double RESIN_DAMAGE = 10;
|
||||
public static final int RESIN_COOLDOWN = 20 * 6;
|
||||
public static final double RESIN_DAMAGE = 5;
|
||||
public static final int RESIN_COOLDOWN = 20 * 15;
|
||||
|
||||
public SilenceAbility() {
|
||||
super(TrimPattern.SILENCE);
|
||||
@@ -71,7 +71,7 @@ public class SilenceAbility extends AbstractAbility {
|
||||
PlayerUtils.combatAllowed(entity,player)
|
||||
);
|
||||
targets.stream().filter(t -> t instanceof LivingEntity).map(t-> (LivingEntity) t).forEach(target -> {
|
||||
target.damage(damage,DamageSource.builder(DamageType.SONIC_BOOM).withDirectEntity(player).build());
|
||||
PlayerUtils.dealTrueDamage(target,DamageSource.builder(DamageType.SONIC_BOOM).withDirectEntity(player).build(),damage);
|
||||
});
|
||||
return !targets.isEmpty();
|
||||
},(point,blockHit) -> {
|
||||
@@ -84,77 +84,77 @@ public class SilenceAbility extends AbstractAbility {
|
||||
},30);
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Amethyst ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Amethyst ", description = "Shoot a sonic blast like the warden. Deals 7 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean amethystAbility(Player player) {
|
||||
shootSonicBoom(player, NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Copper ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Copper ", description = "Shoot a sonic blast like the warden. Deals 7 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean copperAbility(Player player) {
|
||||
shootSonicBoom(player, NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Diamond ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Diamond ", description = "Shoot a sonic blast like the warden. Deals 7 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean diamondAbility(Player player) {
|
||||
shootSonicBoom(player, NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Emerald Bolt", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Emerald Bolt", description = "Shoot a sonic blast like the warden. Deals 7 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean emeraldAbility(Player player) {
|
||||
shootSonicBoom(player, NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Gold ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Gold ", description = "Shoot a sonic blast like the warden. Deals 7 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean goldAbility(Player player) {
|
||||
shootSonicBoom(player, NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Iron ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Iron ", description = "Shoot a sonic blast like the warden. Deals 7 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean ironAbility(Player player) {
|
||||
shootSonicBoom(player, NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Lapis ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Lapis ", description = "Shoot a sonic blast like the warden. Deals 7 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean lapisAbility(Player player) {
|
||||
shootSonicBoom(player, NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Netherite ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@MaterialInfo(name = "Netherite ", description = "Shoot a sonic blast like the warden. Deals 10 true damage", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@Override
|
||||
public boolean netheriteAbility(Player player) {
|
||||
shootSonicBoom(player, NETHERITE_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Quartz ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Quartz ", description = "Shoot a sonic blast like the warden. Deals 7 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean quartzAbility(Player player) {
|
||||
shootSonicBoom(player, NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Redstone ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Redstone ", description = "Shoot a sonic blast like the warden. Deals 7 true damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean redstoneAbility(Player player) {
|
||||
shootSonicBoom(player, NORMAL_DAMAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Resin ", description = "Shoot a sonic blast like the warden. Deals 15 true damage", cooldownTicks = RESIN_COOLDOWN)
|
||||
@MaterialInfo(name = "Resin ", description = "Shoot a sonic blast like the warden. Deals 4 true damage", cooldownTicks = RESIN_COOLDOWN)
|
||||
@Override
|
||||
public boolean resinAbility(Player player) {
|
||||
shootSonicBoom(player, RESIN_DAMAGE);
|
||||
|
||||
@@ -8,11 +8,15 @@ import me.trouper.trimserver.utils.Verbose;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
|
||||
import org.bukkit.event.entity.EntityTransformEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.trim.TrimPattern;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.bukkit.scoreboard.Scoreboard;
|
||||
@@ -57,9 +61,13 @@ public class SnoutAbility extends AbstractAbility {
|
||||
team = board.registerNewTeam("glow_" + color.asHexString());
|
||||
team.color(color);
|
||||
}
|
||||
|
||||
ItemStack weapon = new ItemStack(Material.NETHERITE_AXE);
|
||||
ItemMeta meta = weapon.getItemMeta();
|
||||
meta.addEnchant(Enchantment.SHARPNESS,3,false);
|
||||
team.addEntity(brute);
|
||||
brute.setGlowing(true);
|
||||
brute.getEquipment().setItemInMainHand(weapon);
|
||||
brute.getEquipment().setItemInMainHandDropChance(0F);
|
||||
brute.customName(Text.color(owner.getName() + "'s Piglin Brute").color(color));
|
||||
brute.setCustomNameVisible(true);
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@PatternInfo(name = "Tidal Wave", description = "No lifeguard on duty, swim at your own risk!")
|
||||
public class TideAbility extends AbstractAbility {
|
||||
@@ -44,9 +45,18 @@ public class TideAbility extends AbstractAbility {
|
||||
public void spawnTidalWave(Player caster, double radius, double damage) {
|
||||
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
|
||||
ShaperAbility shaper = (ShaperAbility) shaperInstance;
|
||||
|
||||
new SoundPlayer(caster.getLocation(), Sound.WEATHER_RAIN_ABOVE, 1, 2F).playWithin(30);
|
||||
|
||||
new SoundPlayer(caster.getLocation(), Sound.ENTITY_PLAYER_SPLASH_HIGH_SPEED, 1, 1F).playWithin(30);
|
||||
|
||||
AtomicInteger i = new AtomicInteger();
|
||||
Bukkit.getScheduler().runTaskTimer(main.getPlugin(),(task)->{
|
||||
if (i.getAndIncrement() >= 8) {
|
||||
task.cancel();
|
||||
return;
|
||||
}
|
||||
new SoundPlayer(caster.getLocation(), Sound.WEATHER_RAIN_ABOVE, 1, 2F).playWithin(30);
|
||||
new SoundPlayer(caster.getLocation(), Sound.ENTITY_GUARDIAN_ATTACK, 1, 2F).playWithin(30);
|
||||
},1,10);
|
||||
|
||||
Vector direction = caster.getLocation().getDirection();
|
||||
DisplayUtils.waveFan(caster.getLocation().add(0, 2,0),radius,direction,90,0.1, point->{
|
||||
@@ -65,6 +75,7 @@ public class TideAbility extends AbstractAbility {
|
||||
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);
|
||||
new SoundPlayer(target.getLocation(), Sound.ENTITY_DROWNED_HURT_WATER, 0.9f, 1.4f).playWithin(15);
|
||||
});
|
||||
},0.2);
|
||||
Bukkit.getScheduler().runTaskLater(main.getPlugin(),()->{
|
||||
@@ -124,7 +135,7 @@ public class TideAbility extends AbstractAbility {
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Netherite ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@MaterialInfo(name = "Netherite ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 15 damage", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@Override
|
||||
public boolean netheriteAbility(Player player) {
|
||||
spawnTidalWave(player,NETHERITE_RADIUS,NETHERITE_DAMAGE);
|
||||
@@ -145,7 +156,7 @@ public class TideAbility extends AbstractAbility {
|
||||
return true;
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Resin ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 6 damage", cooldownTicks = RESIN_COOLDOWN)
|
||||
@MaterialInfo(name = "Resin ", description = "Summon a tidal wave in the direction you are looking. Pushes away enemies, deals 3 damage", cooldownTicks = RESIN_COOLDOWN)
|
||||
@Override
|
||||
public boolean resinAbility(Player player) {
|
||||
spawnTidalWave(player,RESIN_RADIUS,RESIN_DAMAGE);
|
||||
|
||||
@@ -8,10 +8,14 @@ import me.trouper.trimserver.utils.Verbose;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.trim.TrimPattern;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.bukkit.scoreboard.Scoreboard;
|
||||
@@ -50,8 +54,15 @@ public class VexAbility extends AbstractAbility {
|
||||
team.color(color);
|
||||
}
|
||||
|
||||
ItemStack weapon = new ItemStack(Material.NETHERITE_SWORD);
|
||||
ItemMeta meta = weapon.getItemMeta();
|
||||
meta.addEnchant(Enchantment.SHARPNESS,3,false);
|
||||
weapon.setItemMeta(meta);
|
||||
team.addEntity(vex);
|
||||
vex.setGlowing(true);
|
||||
vex.getEquipment().setItemInMainHand(weapon);
|
||||
vex.getEquipment().setItemInMainHandDropChance(0F);
|
||||
vex.setLeftHanded(false);
|
||||
vex.customName(Text.color(owner.getName() + "'s Vex").color(color));
|
||||
vex.setCustomNameVisible(true);
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ 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.CustomBossBar;
|
||||
import me.trouper.trimserver.utils.text.Text;
|
||||
import me.trouper.trimserver.utils.Verbose;
|
||||
import org.bukkit.*;
|
||||
@@ -52,7 +53,7 @@ public class WardAbility extends AbstractAbility {
|
||||
private void transformPlayer(Player player) {
|
||||
Verbose.send( "transformPlayer called for %s; currently disguised? %b",
|
||||
player.getName(), activeDisguises.containsKey(player.getUniqueId()));
|
||||
|
||||
CustomBossBar.showBossBar(main.getPlugin(),player,"Warden Disguise",30 * 20);
|
||||
if (activeDisguises.containsKey(player.getUniqueId())) {
|
||||
Verbose.send( "Player %s already disguised; removing disguise", player.getName());
|
||||
removeDisguise(player);
|
||||
@@ -109,6 +110,7 @@ public class WardAbility extends AbstractAbility {
|
||||
Verbose.send( "No disguise data found for %s; aborting", player.getName());
|
||||
return;
|
||||
}
|
||||
CustomBossBar.removeBossBar(player);
|
||||
|
||||
data.disguise.remove();
|
||||
Verbose.send( "Removed disguise entity %s", data.disguise.getUniqueId());
|
||||
|
||||
@@ -8,6 +8,7 @@ import me.trouper.trimserver.utils.SoundPlayer;
|
||||
import me.trouper.trimserver.utils.TargetingUtils;
|
||||
import me.trouper.trimserver.utils.visual.DisplayUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
@@ -16,11 +17,12 @@ import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.damage.DamageSource;
|
||||
import org.bukkit.damage.DamageType;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.inventory.meta.trim.TrimPattern;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@PatternInfo(name = "Big Step", description = "\"He boot too big for he gotdamn feet.\"")
|
||||
@@ -38,133 +40,148 @@ public class WayfinderAbility extends AbstractAbility {
|
||||
public static final double RESIN_DAMAGE = 26;
|
||||
public static final double RESIN_RADIUS = 4;
|
||||
|
||||
private final Set<UUID> awaitStomp = new HashSet<>();
|
||||
|
||||
public WayfinderAbility() {
|
||||
super(TrimPattern.WAYFINDER);
|
||||
}
|
||||
|
||||
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);
|
||||
ShaperAbility shaper = (ShaperAbility) shaperInstance;
|
||||
awaitStomp.add(caster.getUniqueId());
|
||||
|
||||
caster.setVelocity(caster.getVelocity().setY(caster.getVelocity().getY() + 1.5));
|
||||
SoundPlayer jump = new SoundPlayer(caster.getLocation(), Sound.ENTITY_ENDER_DRAGON_FLAP, 1, 2);
|
||||
jump.playWithin(10);
|
||||
|
||||
DisplayUtils.disc(caster.getLocation(),3,0.5,0.25,point->{
|
||||
DisplayUtils.disc(caster.getLocation(),2,0.5,0.25,point->{
|
||||
point.getWorld().spawnParticle(Particle.POOF,point,1,0,0,0,0);
|
||||
});
|
||||
|
||||
AtomicInteger expiry = new AtomicInteger(80);
|
||||
Bukkit.getScheduler().runTaskTimer(main.getPlugin(),task -> {
|
||||
if (expiry.getAndDecrement() <= 0) {
|
||||
if (expiry.getAndDecrement() <= 0 || !awaitStomp.contains(caster.getUniqueId())) {
|
||||
awaitStomp.remove(caster.getUniqueId());
|
||||
task.cancel();
|
||||
return;
|
||||
}
|
||||
if (!caster.getLocation().clone().subtract(0,1,0).getBlock().isPassable()) {
|
||||
|
||||
DisplayUtils.wave(caster.getLocation(),10,1,1,point -> {
|
||||
Block thrown = point.getWorld().getHighestBlockAt((int) point.x(), (int) point.z());
|
||||
BlockData data = thrown.getBlockData();
|
||||
BlockState state = point.getWorld().getHighestBlockAt((int) point.x(), (int) point.z()).getState();
|
||||
|
||||
FallingBlock block = (FallingBlock) point.getWorld().spawnEntity(point.clone(), EntityType.FALLING_BLOCK);
|
||||
block.setBlockData(data);
|
||||
block.setBlockState(state);
|
||||
block.setVelocity(new Vector(0,0.1,0));
|
||||
block.setCancelDrop(true);
|
||||
});
|
||||
|
||||
TargetingUtils.areaAffect(caster.getLocation(),radius,target -> !target.isDead() &&
|
||||
!target.equals(caster) &&
|
||||
!main.man().trustBackend.trusts(caster,target) &&
|
||||
!shaper.activeShellTasks.containsKey(target.getUniqueId()) &&
|
||||
PlayerUtils.combatAllowed(target,caster), target->{
|
||||
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(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);
|
||||
});
|
||||
|
||||
land(caster,damage,radius);
|
||||
task.cancel();
|
||||
}
|
||||
},10,2);
|
||||
}
|
||||
|
||||
public void land(Player caster, double damage, double radius) {
|
||||
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
|
||||
ShaperAbility shaper = (ShaperAbility) shaperInstance;
|
||||
|
||||
@MaterialInfo(name = "Amethyst ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 5 Damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
DisplayUtils.wave(caster.getLocation(),10,1,1,point -> {
|
||||
Block thrown = point.getWorld().getHighestBlockAt((int) point.x(), (int) point.z());
|
||||
BlockData data = thrown.getBlockData();
|
||||
BlockState state = point.getWorld().getHighestBlockAt((int) point.x(), (int) point.z()).getState();
|
||||
|
||||
FallingBlock block = (FallingBlock) point.getWorld().spawnEntity(point.clone(), EntityType.FALLING_BLOCK);
|
||||
block.setBlockData(data);
|
||||
block.setBlockState(state);
|
||||
block.setVelocity(new Vector(0,0.1,0));
|
||||
block.setCancelDrop(true);
|
||||
});
|
||||
|
||||
TargetingUtils.areaAffect(caster.getLocation(),radius,target -> !target.isDead() &&
|
||||
!target.equals(caster) &&
|
||||
!main.man().trustBackend.trusts(caster,target) &&
|
||||
!shaper.activeShellTasks.containsKey(target.getUniqueId()) &&
|
||||
PlayerUtils.combatAllowed(target,caster), target->{
|
||||
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(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);
|
||||
caster.getWorld().spawnParticle(Particle.BLOCK_CRUMBLE,target.getLocation().clone().add(0,1,0),20,0.2,1,0.2,0.1, target.getLocation().clone().subtract(0,2,0).getBlock().getBlockData());
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDamage(EntityDamageEvent e) {
|
||||
if (e.getCause().equals(EntityDamageEvent.DamageCause.FALL) && awaitStomp.remove(e.getEntity().getUniqueId())) {
|
||||
e.setCancelled(true);
|
||||
e.getEntity().getWorld().playSound(e.getEntity(),Sound.ENTITY_ZOMBIE_BREAK_WOODEN_DOOR,1,1);
|
||||
}
|
||||
}
|
||||
|
||||
@MaterialInfo(name = "Amethyst ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 36 damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean amethystAbility(Player 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 = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Copper ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 36 damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean copperAbility(Player 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 = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Diamond ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 36 damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean diamondAbility(Player 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 = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Emerald Bolt", description = "Jump into the air, creating a seismic disturbance when you land. Deals 36 damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean emeraldAbility(Player 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 = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Gold ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 36 damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean goldAbility(Player 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 = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Iron ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 36 damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean ironAbility(Player 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 = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Lapis ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 36 damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean lapisAbility(Player 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 = NETHERITE_COOLDOWN)
|
||||
@MaterialInfo(name = "Netherite ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 46 damage", cooldownTicks = NETHERITE_COOLDOWN)
|
||||
@Override
|
||||
public boolean netheriteAbility(Player 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 = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Quartz ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 36 damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean quartzAbility(Player 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 = NORMAL_COOLDOWN)
|
||||
@MaterialInfo(name = "Redstone ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 36 damage", cooldownTicks = NORMAL_COOLDOWN)
|
||||
@Override
|
||||
public boolean redstoneAbility(Player 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 = RESIN_COOLDOWN)
|
||||
@MaterialInfo(name = "Resin ", description = "Jump into the air, creating a seismic disturbance when you land. Deals 26 damage", cooldownTicks = RESIN_COOLDOWN)
|
||||
@Override
|
||||
public boolean resinAbility(Player player) {
|
||||
stomp(player,RESIN_DAMAGE,RESIN_RADIUS);
|
||||
|
||||
@@ -50,7 +50,7 @@ public class WildAbility extends AbstractAbility {
|
||||
|
||||
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));
|
||||
target.addPotionEffect(new PotionEffect(PotionEffectType.POISON,6*20,1,true,false,false));
|
||||
|
||||
|
||||
final List<BlockDisplay> currentVineSegment = new ArrayList<>(1);
|
||||
|
||||
@@ -13,6 +13,9 @@ import org.bukkit.damage.DamageSource;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.inventory.EntityEquipment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class PlayerUtils implements Main {
|
||||
@@ -87,28 +90,30 @@ public class PlayerUtils implements Main {
|
||||
|
||||
public static void dealTrueDamage(LivingEntity target, DamageSource source, double amount) {
|
||||
if (source.getDirectEntity() instanceof Player a && target instanceof Player t && !combatAllowed(t,a)) return;
|
||||
|
||||
double newHealth = target.getHealth() - amount;
|
||||
if (newHealth <= 0) {
|
||||
target.setHealth(1);
|
||||
target.damage(30, source);
|
||||
} else {
|
||||
target.setHealth(newHealth);
|
||||
target.damage(1, source);
|
||||
|
||||
EntityEquipment equipment = target.getEquipment();
|
||||
if (equipment == null) {
|
||||
target.damage(amount,source);
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack helmet = equipment.getHelmet();
|
||||
ItemStack chestplate = equipment.getChestplate();
|
||||
ItemStack leggings = equipment.getLeggings();
|
||||
ItemStack boots = equipment.getBoots();
|
||||
|
||||
Entity attacker = source.getDirectEntity();
|
||||
if (attacker instanceof LivingEntity) {
|
||||
double dx = target.getX() - attacker.getX();
|
||||
double dz = target.getZ() - attacker.getZ();
|
||||
double magnitude = Math.sqrt(dx * dx + dz * dz);
|
||||
|
||||
if (magnitude > 0) {
|
||||
double strength = 0.4;
|
||||
dx /= magnitude;
|
||||
dz /= magnitude;
|
||||
target.setVelocity(target.getVelocity().add(new Vector(dx * strength, 0.1, dz * strength)));
|
||||
}
|
||||
equipment.setHelmet(null);
|
||||
equipment.setChestplate(null);
|
||||
equipment.setLeggings(null);
|
||||
equipment.setBoots(null);
|
||||
|
||||
try {
|
||||
target.damage(amount,source);
|
||||
} finally {
|
||||
equipment.setHelmet(helmet);
|
||||
equipment.setChestplate(chestplate);
|
||||
equipment.setLeggings(leggings);
|
||||
equipment.setBoots(boots);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -225,8 +225,8 @@ public class TargetingUtils {
|
||||
* @return An {@link Optional} containing the {@link LivingEntity} closest to the aim vector,
|
||||
* or an empty Optional if no suitable entity is found or world is null.
|
||||
*/
|
||||
public static Optional<LivingEntity> getLivingEntityClosestToVector(Location originEyeLocation, Vector direction, double maxDistance, double maxAngleRadians) {
|
||||
return getLivingEntityClosestToVector(originEyeLocation, direction, maxDistance, maxAngleRadians, entity -> true);
|
||||
public static Optional<LivingEntity> livingClosestAngle(Location originEyeLocation, Vector direction, double maxDistance, double maxAngleRadians) {
|
||||
return livingClosestAngle(originEyeLocation, direction, maxDistance, maxAngleRadians, entity -> true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -242,7 +242,7 @@ public class TargetingUtils {
|
||||
* @return An {@link Optional} containing the {@link LivingEntity} closest to the aim vector and matching the filter,
|
||||
* or an empty Optional if no suitable entity is found or world is null.
|
||||
*/
|
||||
public static Optional<LivingEntity> getLivingEntityClosestToVector(Location originEyeLocation, Vector direction, double maxDistance, double maxAngleRadians, Predicate<LivingEntity> filter) {
|
||||
public static Optional<LivingEntity> livingClosestAngle(Location originEyeLocation, Vector direction, double maxDistance, double maxAngleRadians, Predicate<LivingEntity> filter) {
|
||||
if (originEyeLocation == null || originEyeLocation.getWorld() == null || direction == null || filter == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ public class CustomBossBar {
|
||||
|
||||
private static final Map<UUID, PlayerBossBarData> activeBossBars = new ConcurrentHashMap<>();
|
||||
|
||||
// Private constructor to prevent instantiation
|
||||
private CustomBossBar() {}
|
||||
|
||||
/**
|
||||
@@ -33,20 +32,15 @@ public class CustomBossBar {
|
||||
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);
|
||||
}
|
||||
@@ -137,12 +131,10 @@ public class CustomBossBar {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -193,7 +185,7 @@ public class CustomBossBar {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all active boss bars (useful for plugin disable)
|
||||
* Removes all active boss bars
|
||||
*/
|
||||
public static void removeAllBossBars() {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
@@ -241,11 +233,9 @@ public class CustomBossBar {
|
||||
|
||||
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);
|
||||
@@ -254,17 +244,13 @@ public class CustomBossBar {
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
@@ -136,7 +136,9 @@ public class Text implements Main {
|
||||
int currentLineLength = offset;
|
||||
|
||||
for (String word : words) {
|
||||
if (currentLineLength + word.length() + 1 > maxLineLength) {
|
||||
int wordVisibleLength = getVisibleLength(word);
|
||||
|
||||
if (currentLineLength + wordVisibleLength + 1 > maxLineLength) {
|
||||
lines.add(currentLine.toString());
|
||||
currentLine = new StringBuilder();
|
||||
currentLineLength = 0;
|
||||
@@ -148,7 +150,7 @@ public class Text implements Main {
|
||||
}
|
||||
|
||||
currentLine.append(word);
|
||||
currentLineLength += word.length();
|
||||
currentLineLength += wordVisibleLength;
|
||||
}
|
||||
|
||||
if (!currentLine.isEmpty()) {
|
||||
@@ -158,6 +160,10 @@ public class Text implements Main {
|
||||
return lines;
|
||||
}
|
||||
|
||||
private static int getVisibleLength(String text) {
|
||||
return text.replaceAll("&(?:[0-9a-fk-or]|#[0-9a-fA-F]{6})", "").length();
|
||||
}
|
||||
|
||||
public static String getActiveFormatting(String text) {
|
||||
final Pattern pattern = Pattern.compile("&[0-9a-fk-or]");
|
||||
final Matcher matcher = pattern.matcher(text);
|
||||
@@ -198,35 +204,40 @@ public class Text implements Main {
|
||||
|
||||
public enum Pallet {
|
||||
ERROR(
|
||||
NamedTextColor.RED,
|
||||
NamedTextColor.YELLOW,
|
||||
NamedTextColor.GOLD,
|
||||
NamedTextColor.DARK_RED,
|
||||
new SoundData(Sound.BLOCK_NOTE_BLOCK_BASS,1)),
|
||||
TextColor.color(0xFFB3BA), // Pastel red
|
||||
TextColor.color(0xFFD6A5), // Pastel orange
|
||||
TextColor.color(0xFFDFBA), // Peach
|
||||
TextColor.color(0xFF9999), // Soft coral
|
||||
new SoundData(Sound.BLOCK_NOTE_BLOCK_BASS, 1)
|
||||
),
|
||||
WARNING(
|
||||
NamedTextColor.YELLOW,
|
||||
NamedTextColor.GOLD,
|
||||
NamedTextColor.RED,
|
||||
NamedTextColor.DARK_RED,
|
||||
new SoundData(Sound.BLOCK_NOTE_BLOCK_BIT,0.5F)),
|
||||
TextColor.color(0xFFEAA7), // Light pastel yellow-orange
|
||||
TextColor.color(0xFFFACD), // Lemon chiffon
|
||||
TextColor.color(0xFFDAC1), // Light orange-pink
|
||||
TextColor.color(0xFFD1DC), // Light pink
|
||||
new SoundData(Sound.BLOCK_NOTE_BLOCK_BIT, 0.5F)
|
||||
),
|
||||
INFO(
|
||||
NamedTextColor.GRAY,
|
||||
NamedTextColor.WHITE,
|
||||
NamedTextColor.AQUA,
|
||||
NamedTextColor.DARK_AQUA,
|
||||
new SoundData(Sound.BLOCK_NOTE_BLOCK_BELL,1)),
|
||||
TextColor.color(0xAAAAFF), // Lavender blue
|
||||
TextColor.color(0xDDDDFF), // Very light lavender
|
||||
TextColor.color(0xB4E7FB), // Baby blue
|
||||
TextColor.color(0xA298FF), // Pastel indigo
|
||||
new SoundData(Sound.BLOCK_NOTE_BLOCK_BELL, 1)
|
||||
),
|
||||
SUCCESS(
|
||||
NamedTextColor.GREEN,
|
||||
NamedTextColor.DARK_GREEN,
|
||||
NamedTextColor.YELLOW,
|
||||
NamedTextColor.GOLD,
|
||||
new SoundData(Sound.BLOCK_NOTE_BLOCK_CHIME,1)),
|
||||
TextColor.color(0xAAFFAA), // Mint green
|
||||
TextColor.color(0xC1F7C1), // Pale green
|
||||
TextColor.color(0xFFFFAA), // Pale yellow
|
||||
TextColor.color(0xFFF5C3), // Light creamy yellow
|
||||
new SoundData(Sound.BLOCK_NOTE_BLOCK_CHIME, 1)
|
||||
),
|
||||
NEUTRAL(
|
||||
NamedTextColor.GRAY,
|
||||
NamedTextColor.WHITE,
|
||||
NamedTextColor.DARK_AQUA,
|
||||
NamedTextColor.BLUE,
|
||||
new SoundData(Sound.BLOCK_NOTE_BLOCK_BELL,1));
|
||||
TextColor.color(0xCCCCCC), // Soft gray
|
||||
TextColor.color(0xFFFFFF), // White
|
||||
TextColor.color(0xC2E0F4), // Powder blue
|
||||
TextColor.color(0xAAAAFF), // Lavender blue
|
||||
new SoundData(Sound.BLOCK_NOTE_BLOCK_BELL, 1)
|
||||
);
|
||||
|
||||
private final TextColor mainText;
|
||||
private final TextColor argDefault;
|
||||
@@ -242,7 +253,8 @@ public class Text implements Main {
|
||||
this.sound = sound;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public record SoundData(Sound sound, float pitch){};
|
||||
|
||||
public static String generateProgressBar(int length, int max, int current) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -46,9 +46,12 @@ public class DisplayUtils implements Main {
|
||||
public static void sphereWave(Location center, double maxRadius, double radialStep, double maxDistanceBetweenPoints, Consumer<Location> action) {
|
||||
AtomicReference<Double> currentRadius = new AtomicReference<>(radialStep);
|
||||
|
||||
Bukkit.getScheduler().scheduleSyncRepeatingTask(main.getPlugin(), () -> {
|
||||
Bukkit.getScheduler().runTaskTimer(main.getPlugin(), (task) -> {
|
||||
double r = currentRadius.get();
|
||||
if (r > maxRadius) return;
|
||||
if (r > maxRadius) {
|
||||
task.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
sphere(center, r, maxDistanceBetweenPoints, action);
|
||||
currentRadius.set(r + radialStep);
|
||||
@@ -92,8 +95,9 @@ public class DisplayUtils implements Main {
|
||||
|
||||
public static void wave(Location loc, double radius, Consumer<Location> action, double gap) {
|
||||
AtomicReference<Double> i = new AtomicReference<>(gap);
|
||||
Bukkit.getScheduler().scheduleSyncRepeatingTask(main.getPlugin(), () -> {
|
||||
Bukkit.getScheduler().runTaskTimer(main.getPlugin(), (task) -> {
|
||||
if (i.get() >= radius) {
|
||||
task.cancel();
|
||||
return;
|
||||
}
|
||||
ring(loc, i.get(), action);
|
||||
@@ -103,8 +107,11 @@ public class DisplayUtils implements Main {
|
||||
|
||||
public static void wave(Location loc, double radius, double radialGap, double maxDistanceBetweenPoints, Consumer<Location> action) {
|
||||
AtomicReference<Double> r = new AtomicReference<>(radialGap);
|
||||
Bukkit.getScheduler().scheduleSyncRepeatingTask(main.getPlugin(), () -> {
|
||||
if (r.get() > radius) return;
|
||||
Bukkit.getScheduler().runTaskTimer(main.getPlugin(), (task) -> {
|
||||
if (r.get() > radius) {
|
||||
task.cancel();
|
||||
return;
|
||||
}
|
||||
ring(loc, r.get(), maxDistanceBetweenPoints, action);
|
||||
r.set(r.get() + radialGap);
|
||||
}, 0, 1);
|
||||
@@ -197,8 +204,9 @@ public class DisplayUtils implements Main {
|
||||
public static void fanWave(Location loc, double radius, int sections, Consumer<Location> action, double gap) {
|
||||
double arcLength = 360.0 / sections;
|
||||
AtomicReference<Double> i = new AtomicReference<>(0.0);
|
||||
Bukkit.getScheduler().scheduleSyncRepeatingTask(main.getPlugin(), () -> {
|
||||
Bukkit.getScheduler().runTaskTimer(main.getPlugin(), (task) -> {
|
||||
if (i.get() >= 360) {
|
||||
task.cancel();
|
||||
return;
|
||||
}
|
||||
double start = i.get();
|
||||
@@ -216,8 +224,9 @@ public class DisplayUtils implements Main {
|
||||
|
||||
AtomicInteger i = new AtomicInteger(0);
|
||||
Randomizer random = new Randomizer();
|
||||
Bukkit.getScheduler().scheduleSyncRepeatingTask(main.getPlugin(), () -> {
|
||||
Bukkit.getScheduler().runTaskTimer(main.getPlugin(), (task) -> {
|
||||
if (i.get() >= sections) {
|
||||
task.cancel();
|
||||
return;
|
||||
}
|
||||
double start = random.getRandomElement(ints);
|
||||
@@ -229,8 +238,11 @@ public class DisplayUtils implements Main {
|
||||
|
||||
public static void waveFan(Location loc, double radius, int angleFrom, int angleTo, double maxDistanceBetweenPoints, Consumer<Location> action, double radialGap) {
|
||||
AtomicReference<Double> r = new AtomicReference<>(radialGap);
|
||||
Bukkit.getScheduler().scheduleSyncRepeatingTask(main.getPlugin(), () -> {
|
||||
if (r.get() >= radius) return;
|
||||
Bukkit.getScheduler().runTaskTimer(main.getPlugin(), (task) -> {
|
||||
if (r.get() >= radius) {
|
||||
task.cancel();
|
||||
return;
|
||||
}
|
||||
arc(loc, r.get(), angleFrom, angleTo, maxDistanceBetweenPoints, action);
|
||||
r.set(r.get() + radialGap);
|
||||
}, 0, 1);
|
||||
|
||||
Reference in New Issue
Block a user