Updated some raytracer stuff, made eye always on the plane.

This commit is contained in:
2025-06-16 17:51:40 -05:00
parent 1da50164ea
commit e8e85e0b23
23 changed files with 346 additions and 1948 deletions

View File

@@ -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" -> {

View File

@@ -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();

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;
}
}

View File

@@ -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() {

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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());

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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);