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

This commit is contained in:
2025-05-17 17:48:26 -05:00
parent c9e1e4e7c1
commit 6ab32029f9
14 changed files with 166 additions and 57 deletions

View File

@@ -75,6 +75,9 @@ public class AdminCommand implements QuickCommand {
b.argEnum( b.argEnum(
AbilityBackend.ValidMaterial.class AbilityBackend.ValidMaterial.class
) )
.then(
b.argEnum(AbilityBackend.ValidArmorType.class)
)
) )
) )
).then( ).then(
@@ -108,7 +111,7 @@ public class AdminCommand implements QuickCommand {
private void handleTry(CommandSender sender, Args args) { private void handleTry(CommandSender sender, Args args) {
if (args.getSize() < 2) { if (args.getSize() < 2) {
error(sender, "Usage: /trims try <trim> [material]"); error(sender, "Usage: /trims try <trim> [material] [armortype]");
return; return;
} }
if (!(sender instanceof Player p)) { if (!(sender instanceof Player p)) {
@@ -118,17 +121,19 @@ public class AdminCommand implements QuickCommand {
AbilityBackend.ValidPattern validPattern = args.get(1).toEnum(AbilityBackend.ValidPattern.class); AbilityBackend.ValidPattern validPattern = args.get(1).toEnum(AbilityBackend.ValidPattern.class);
AbilityBackend.ValidMaterial validMaterial = new Randomizer().getRandomElement(AbilityBackend.ValidMaterial.values()); AbilityBackend.ValidMaterial validMaterial = new Randomizer().getRandomElement(AbilityBackend.ValidMaterial.values());
AbilityBackend.ValidArmorType validArmorType = new Randomizer().getRandomElement(AbilityBackend.ValidArmorType.values());
if (args.getSize() >= 3) validMaterial = args.get(2).toEnum(AbilityBackend.ValidMaterial.class); if (args.getSize() >= 3) validMaterial = args.get(2).toEnum(AbilityBackend.ValidMaterial.class);
if (args.getSize() >= 4) validArmorType = args.get(3).toEnum(AbilityBackend.ValidArmorType.class);
TrimPattern pattern = validPattern.getCanonical(); TrimPattern pattern = validPattern.getCanonical();
TrimMaterial material = validMaterial.getCanonical(); TrimMaterial material = validMaterial.getCanonical();
if (material == null) material = new Randomizer().getRandomElement(AbilityBackend.ValidMaterial.values()).getCanonical(); if (material == null) material = new Randomizer().getRandomElement(AbilityBackend.ValidMaterial.values()).getCanonical();
p.getEquipment().setHelmet(createTestArmor(new ItemStack(Material.NETHERITE_HELMET),pattern,material)); p.getEquipment().setHelmet(createTestArmor(new ItemStack(validArmorType.getHelmet()),pattern,material));
p.getEquipment().setChestplate(createTestArmor(new ItemStack(Material.NETHERITE_CHESTPLATE),pattern,material)); p.getEquipment().setChestplate(createTestArmor(new ItemStack(validArmorType.getChestplate()),pattern,material));
p.getEquipment().setLeggings(createTestArmor(new ItemStack(Material.NETHERITE_LEGGINGS),pattern,material)); p.getEquipment().setLeggings(createTestArmor(new ItemStack(validArmorType.getLeggings()),pattern,material));
p.getEquipment().setBoots(createTestArmor(new ItemStack(Material.NETHERITE_BOOTS),pattern,material)); p.getEquipment().setBoots(createTestArmor(new ItemStack(validArmorType.getBoots()),pattern,material));
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
double finalI = i; double finalI = i;

View File

@@ -367,4 +367,41 @@ public class AbilityBackend implements Main {
return canonical; return canonical;
} }
} }
public enum ValidArmorType {
LEATHER(Material.LEATHER_HELMET,Material.LEATHER_CHESTPLATE,Material.LEATHER_LEGGINGS,Material.LEATHER_BOOTS),
GOLDEN(Material.GOLDEN_HELMET,Material.GOLDEN_CHESTPLATE,Material.GOLDEN_LEGGINGS,Material.GOLDEN_BOOTS),
CHAINMAIL(Material.CHAINMAIL_HELMET,Material.CHAINMAIL_CHESTPLATE,Material.CHAINMAIL_LEGGINGS,Material.CHAINMAIL_BOOTS),
IRON(Material.IRON_HELMET,Material.IRON_CHESTPLATE,Material.IRON_LEGGINGS,Material.IRON_BOOTS),
DIAMOND(Material.DIAMOND_HELMET,Material.DIAMOND_CHESTPLATE,Material.DIAMOND_LEGGINGS,Material.DIAMOND_BOOTS),
NETHERITE(Material.NETHERITE_HELMET,Material.NETHERITE_CHESTPLATE,Material.NETHERITE_LEGGINGS,Material.NETHERITE_BOOTS);
private final Material helmet;
private final Material chestplate;
private final Material leggings;
private final Material boots;
ValidArmorType(Material helmet, Material chestplate, Material leggings, Material boots) {
this.helmet = helmet;
this.chestplate = chestplate;
this.leggings = leggings;
this.boots = boots;
}
public Material getHelmet() {
return helmet;
}
public Material getChestplate() {
return chestplate;
}
public Material getLeggings() {
return leggings;
}
public Material getBoots() {
return boots;
}
}
} }

View File

@@ -28,7 +28,10 @@ public class BoltAbility extends AbstractAbility implements Main {
} }
public boolean strike(Player caster, int range, double damage, Material innerBlock, Material outerBlock) { public boolean strike(Player caster, int range, double damage, Material innerBlock, Material outerBlock) {
return TargetingUtils.areaAffect(caster.getLocation(),range,target-> !main.man().trustBackend.trusts(caster,target),(target)->{ 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) && !shaper.activeShellTasks.containsKey(target.getUniqueId()),(target) ->{
drawLightning(caster.getEyeLocation(),target.getEyeLocation(),innerBlock,outerBlock); drawLightning(caster.getEyeLocation(),target.getEyeLocation(),innerBlock,outerBlock);
target.damage(damage,DamageSource.builder(DamageType.LIGHTNING_BOLT).withDamageLocation(caster.getEyeLocation()).withDirectEntity(caster).build()); target.damage(damage,DamageSource.builder(DamageType.LIGHTNING_BOLT).withDamageLocation(caster.getEyeLocation()).withDirectEntity(caster).build());
if (target instanceof Player t) Text.sendMessage(Text.Pallet.INFO,t,"You have been stunned by {0}'s Bolt!",caster.name()); if (target instanceof Player t) Text.sendMessage(Text.Pallet.INFO,t,"You have been stunned by {0}'s Bolt!",caster.name());

View File

@@ -37,7 +37,7 @@ public class EyeAbility extends AbstractAbility {
} }
Location headLocation = player.getEyeLocation().clone(); Location headLocation = player.getEyeLocation().clone();
Vector eyeCenter = headLocation.getDirection(); Vector eyeCenter = headLocation.getDirection();
Vector leftRight = new Vector(-eyeCenter.getZ(), eyeCenter.getY(), eyeCenter.getX()).normalize().multiply(0.2); Vector leftRight = new Vector(-eyeCenter.getZ(), 0, eyeCenter.getX()).normalize().multiply(0.2);
// Two eye locations // Two eye locations
Location leftEye = headLocation.clone().add(leftRight); Location leftEye = headLocation.clone().add(leftRight);
@@ -54,11 +54,13 @@ public class EyeAbility extends AbstractAbility {
} }
public Location laser(Player owner, Location start, Vector direction, double distance) { public Location laser(Player owner, Location start, Vector direction, double distance) {
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
ShaperAbility shaper = (ShaperAbility) shaperInstance;
return CustomDisplayRaytracer.trace(start,direction,distance,1,point ->{ return CustomDisplayRaytracer.trace(start,direction,distance,1,point ->{
SoundPlayer hissSound = new SoundPlayer(point.getLoc(), Sound.BLOCK_LAVA_EXTINGUISH, 1, 1); SoundPlayer hissSound = new SoundPlayer(point.getLoc(), Sound.BLOCK_LAVA_EXTINGUISH, 1, 1);
List<Entity> targets = point.getNearbyEntities(owner,5,true,0.5, target -> target instanceof LivingEntity && !target.isDead() && !main.man().trustBackend.trusts(owner, (LivingEntity) target)); List<Entity> targets = point.getNearbyEntities(owner,5,true,0.5, target -> target instanceof LivingEntity && !target.isDead() && !main.man().trustBackend.trusts(owner, (LivingEntity) target));
targets.forEach(entity -> { targets.forEach(entity -> {
if (!(entity instanceof LivingEntity liv)) return; if (!(entity instanceof LivingEntity liv) || shaper.activeShellTasks.containsKey(liv.getUniqueId())) return;
hissSound.playWithin(10); hissSound.playWithin(10);
int tick = liv.getNoDamageTicks(); int tick = liv.getNoDamageTicks();

View File

@@ -32,6 +32,9 @@ public class FlowAbility extends AbstractAbility {
} }
private void spawnRideableBreeze(Player player, int duration, Material material) { private void spawnRideableBreeze(Player player, int duration, Material material) {
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
ShaperAbility shaper = (ShaperAbility) shaperInstance;
if (activeRiders.containsKey(player.getUniqueId())) { if (activeRiders.containsKey(player.getUniqueId())) {
activeRiders.get(player.getUniqueId()).cancel(); activeRiders.get(player.getUniqueId()).cancel();
activeRiders.remove(player.getUniqueId()); activeRiders.remove(player.getUniqueId());
@@ -91,7 +94,7 @@ public class FlowAbility extends AbstractAbility {
} }
} }
TargetingUtils.areaAffect(breeze.getLocation(),1.5,entity -> !entity.equals(player) && !main.man().trustBackend.trusts(player,entity) && !breeze.equals(entity),target->{ TargetingUtils.areaAffect(breeze.getLocation(),1.5,entity -> !entity.equals(player) && !main.man().trustBackend.trusts(player,entity) && !breeze.equals(entity) && !shaper.activeShellTasks.containsKey(entity.getUniqueId()),target->{
launchEntity(target); launchEntity(target);
world.spawnParticle(Particle.EXPLOSION, target.getLocation(), 10, 0.5, 0.5, 0.5, 0.1); world.spawnParticle(Particle.EXPLOSION, target.getLocation(), 10, 0.5, 0.5, 0.5, 0.1);
}); });

View File

@@ -3,8 +3,11 @@ package me.trouper.trimserver.server.systems.abilities.trims;
import me.trouper.trimserver.server.systems.abilities.MaterialInfo; import me.trouper.trimserver.server.systems.abilities.MaterialInfo;
import me.trouper.trimserver.server.systems.abilities.AbstractAbility; import me.trouper.trimserver.server.systems.abilities.AbstractAbility;
import me.trouper.trimserver.server.systems.abilities.PatternInfo; import me.trouper.trimserver.server.systems.abilities.PatternInfo;
import me.trouper.trimserver.utils.SoundPlayer;
import me.trouper.trimserver.utils.Text; import me.trouper.trimserver.utils.Text;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Particle;
import org.bukkit.Sound;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
@@ -22,9 +25,15 @@ public class HostAbility extends AbstractAbility {
} }
public void makeInvisible(Player invis, long seconds) { public void makeInvisible(Player invis, long seconds) {
AbstractAbility eyeInstance = main.man().abilityBackend.getAbility(TrimPattern.EYE);
EyeAbility eye = (EyeAbility) eyeInstance;
invis.getLocation().getWorld().spawnParticle(Particle.EXPLOSION_EMITTER,invis.getLocation(),1,0,0,0);
new SoundPlayer(invis.getLocation(),Sound.BLOCK_REDSTONE_TORCH_BURNOUT,10,0.5F);
invis.addScoreboardTag("$/TrimServer/ Invisible"); invis.addScoreboardTag("$/TrimServer/ Invisible");
for (Player player : Bukkit.getOnlinePlayers()) { for (Player player : Bukkit.getOnlinePlayers()) {
if (main.man().trustBackend.trusts(invis,player)) continue; if (main.man().trustBackend.trusts(invis,player) || main.man().abilityBackend.getAbility(player).getPattern().equals(TrimPattern.EYE)) continue;
player.hidePlayer(main.getPlugin(),invis); player.hidePlayer(main.getPlugin(),invis);
AtomicInteger timer = new AtomicInteger(); AtomicInteger timer = new AtomicInteger();
Bukkit.getScheduler().runTaskTimer(main.getPlugin(),(task)->{ Bukkit.getScheduler().runTaskTimer(main.getPlugin(),(task)->{

View File

@@ -4,6 +4,7 @@ import me.trouper.trimserver.server.systems.abilities.MaterialInfo;
import me.trouper.trimserver.server.systems.abilities.AbstractAbility; import me.trouper.trimserver.server.systems.abilities.AbstractAbility;
import me.trouper.trimserver.server.systems.abilities.PatternInfo; import me.trouper.trimserver.server.systems.abilities.PatternInfo;
import me.trouper.trimserver.utils.TargetingUtils; import me.trouper.trimserver.utils.TargetingUtils;
import me.trouper.trimserver.utils.Text;
import me.trouper.trimserver.utils.visual.BlockDisplayRaytracer; import me.trouper.trimserver.utils.visual.BlockDisplayRaytracer;
import me.trouper.trimserver.utils.visual.DisplayUtils; import me.trouper.trimserver.utils.visual.DisplayUtils;
import org.bukkit.*; import org.bukkit.*;
@@ -138,69 +139,89 @@ public class RaiserAbility extends AbstractAbility {
} }
} }
@MaterialInfo(name = "Amethyst ", description = "Pins your enemy 4 blocks into the air for 30 seconds, or until they loose half their current health", cooldownTicks = 20 * 45) @MaterialInfo(name = "Amethyst ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = 20 * 45)
@Override @Override
public boolean amethystAbility(Player player) { public boolean amethystAbility(Player player) {
return TargetingUtils.areaAffect(player.getLocation(),15,target -> !main.man().trustBackend.trusts(player,target), this::raiseEntity); AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
ShaperAbility shaper = (ShaperAbility) shaperInstance;
return TargetingUtils.areaAffect(player.getLocation(),15,target -> !main.man().trustBackend.trusts(player,target) && !shaper.activeShellTasks.containsKey(target.getUniqueId()), this::raiseEntity);
} }
@MaterialInfo(name = "Copper ", description = "Pins your enemy 4 blocks into the air for 30 seconds, or until they loose half their current health", cooldownTicks = 20 * 45) @MaterialInfo(name = "Copper ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = 20 * 45)
@Override @Override
public boolean copperAbility(Player player) { public boolean copperAbility(Player player) {
return TargetingUtils.areaAffect(player.getLocation(),15,target -> !main.man().trustBackend.trusts(player,target), this::raiseEntity); AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
ShaperAbility shaper = (ShaperAbility) shaperInstance;
return TargetingUtils.areaAffect(player.getLocation(),15,target -> !main.man().trustBackend.trusts(player,target) && !shaper.activeShellTasks.containsKey(target.getUniqueId()), this::raiseEntity);
} }
@MaterialInfo(name = "Diamond ", description = "Pins your enemy 4 blocks into the air for 30 seconds, or until they loose half their current health", cooldownTicks = 20 * 45) @MaterialInfo(name = "Diamond ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = 20 * 45)
@Override @Override
public boolean diamondAbility(Player player) { public boolean diamondAbility(Player player) {
return TargetingUtils.areaAffect(player.getLocation(),15,target -> !main.man().trustBackend.trusts(player,target), this::raiseEntity); AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
ShaperAbility shaper = (ShaperAbility) shaperInstance;
return TargetingUtils.areaAffect(player.getLocation(),15,target -> !main.man().trustBackend.trusts(player,target) && !shaper.activeShellTasks.containsKey(target.getUniqueId()), this::raiseEntity);
} }
@MaterialInfo(name = "Emerald ", description = "Pins your enemy 4 blocks into the air for 30 seconds, or until they loose half their current health", cooldownTicks = 20 * 45) @MaterialInfo(name = "Emerald ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = 20 * 45)
@Override @Override
public boolean emeraldAbility(Player player) { public boolean emeraldAbility(Player player) {
return TargetingUtils.areaAffect(player.getLocation(),15,target -> !main.man().trustBackend.trusts(player,target), this::raiseEntity); AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
ShaperAbility shaper = (ShaperAbility) shaperInstance;
return TargetingUtils.areaAffect(player.getLocation(),15,target -> !main.man().trustBackend.trusts(player,target) && !shaper.activeShellTasks.containsKey(target.getUniqueId()), this::raiseEntity);
} }
@MaterialInfo(name = "Gold ", description = "Pins your enemy 4 blocks into the air for 30 seconds, or until they loose half their current health", cooldownTicks = 20 * 45) @MaterialInfo(name = "Gold ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = 20 * 45)
@Override @Override
public boolean goldAbility(Player player) { public boolean goldAbility(Player player) {
return TargetingUtils.areaAffect(player.getLocation(),15,target -> !main.man().trustBackend.trusts(player,target), this::raiseEntity); AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
ShaperAbility shaper = (ShaperAbility) shaperInstance;
return TargetingUtils.areaAffect(player.getLocation(),15,target -> !main.man().trustBackend.trusts(player,target) && !shaper.activeShellTasks.containsKey(target.getUniqueId()), this::raiseEntity);
} }
@MaterialInfo(name = "Iron ", description = "Pins your enemy 4 blocks into the air for 30 seconds, or until they loose half their current health", cooldownTicks = 20 * 45) @MaterialInfo(name = "Iron ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = 20 * 45)
@Override @Override
public boolean ironAbility(Player player) { public boolean ironAbility(Player player) {
return TargetingUtils.areaAffect(player.getLocation(),15,target -> !main.man().trustBackend.trusts(player,target), this::raiseEntity); AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
ShaperAbility shaper = (ShaperAbility) shaperInstance;
return TargetingUtils.areaAffect(player.getLocation(),15,target -> !main.man().trustBackend.trusts(player,target) && !shaper.activeShellTasks.containsKey(target.getUniqueId()), this::raiseEntity);
} }
@MaterialInfo(name = "Lapis ", description = "Pins your enemy 4 blocks into the air for 30 seconds, or until they loose half their current health", cooldownTicks = 20 * 45) @MaterialInfo(name = "Lapis ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = 20 * 45)
@Override @Override
public boolean lapisAbility(Player player) { public boolean lapisAbility(Player player) {
return TargetingUtils.areaAffect(player.getLocation(),15,target -> !main.man().trustBackend.trusts(player,target), this::raiseEntity); AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
ShaperAbility shaper = (ShaperAbility) shaperInstance;
return TargetingUtils.areaAffect(player.getLocation(),15,target -> !main.man().trustBackend.trusts(player,target) && !shaper.activeShellTasks.containsKey(target.getUniqueId()), this::raiseEntity);
} }
@MaterialInfo(name = "Netherite ", description = "Pins your enemy 4 blocks into the air for 30 seconds, or until they loose half their current health", cooldownTicks = 20 * 30) @MaterialInfo(name = "Netherite ", description = "Pins your enemy 4 blocks into the air for 6 seconds. Can raise those with Shaper ability activated too.", cooldownTicks = 20 * 30)
@Override @Override
public boolean netheriteAbility(Player player) { public boolean netheriteAbility(Player player) {
return TargetingUtils.areaAffect(player.getLocation(),15,target -> !main.man().trustBackend.trusts(player,target), this::raiseEntity); return TargetingUtils.areaAffect(player.getLocation(),15,target -> !main.man().trustBackend.trusts(player,target), this::raiseEntity);
} }
@MaterialInfo(name = "Quartz ", description = "Pins your enemy 4 blocks into the air for 30 seconds, or until they loose half their current health", cooldownTicks = 20 * 45) @MaterialInfo(name = "Quartz ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = 20 * 45)
@Override @Override
public boolean quartzAbility(Player player) { public boolean quartzAbility(Player player) {
return TargetingUtils.areaAffect(player.getLocation(),15,target -> !main.man().trustBackend.trusts(player,target), this::raiseEntity); AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
ShaperAbility shaper = (ShaperAbility) shaperInstance;
return TargetingUtils.areaAffect(player.getLocation(),15,target -> !main.man().trustBackend.trusts(player,target) && !shaper.activeShellTasks.containsKey(target.getUniqueId()), this::raiseEntity);
} }
@MaterialInfo(name = "Redstone ", description = "Pins your enemy 4 blocks into the air for 30 seconds, or until they loose half their current health", cooldownTicks = 20 * 45) @MaterialInfo(name = "Redstone ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = 20 * 45)
@Override @Override
public boolean redstoneAbility(Player player) { public boolean redstoneAbility(Player player) {
return TargetingUtils.areaAffect(player.getLocation(),15,target -> !main.man().trustBackend.trusts(player,target), this::raiseEntity); AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
ShaperAbility shaper = (ShaperAbility) shaperInstance;
return TargetingUtils.areaAffect(player.getLocation(),15,target -> !main.man().trustBackend.trusts(player,target) && !shaper.activeShellTasks.containsKey(target.getUniqueId()), this::raiseEntity);
} }
@MaterialInfo(name = "Resin ", description = "Pins your enemy 4 blocks into the air for 30 seconds, or until they loose half their current health", cooldownTicks = 20 * 45) @MaterialInfo(name = "Resin ", description = "Pins your enemy 4 blocks into the air for 6 seconds, or until they loose half their current health", cooldownTicks = 20 * 45)
@Override @Override
public boolean resinAbility(Player player) { public boolean resinAbility(Player player) {
return TargetingUtils.areaAffect(player.getLocation(),15,target -> !main.man().trustBackend.trusts(player,target), this::raiseEntity); AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
ShaperAbility shaper = (ShaperAbility) shaperInstance;
return TargetingUtils.areaAffect(player.getLocation(),15,target -> !main.man().trustBackend.trusts(player,target) && !shaper.activeShellTasks.containsKey(target.getUniqueId()), this::raiseEntity);
} }
} }

View File

@@ -37,6 +37,9 @@ public class RibAbility extends AbstractAbility {
} }
private void executeResinEruption(Player caster, Material activatingTrimMaterial, int spikeCount, double areaRadius, int activeDurationTicks, Material groundParticleMaterial) { private void executeResinEruption(Player caster, Material activatingTrimMaterial, int spikeCount, double areaRadius, int activeDurationTicks, Material groundParticleMaterial) {
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
ShaperAbility shaper = (ShaperAbility) shaperInstance;
World world = caster.getWorld(); World world = caster.getWorld();
if (world == null) return; if (world == null) return;
@@ -50,7 +53,7 @@ public class RibAbility extends AbstractAbility {
point.getWorld().spawnParticle(Particle.FLAME,point,1,0.1,0.1,0.1,0.01); point.getWorld().spawnParticle(Particle.FLAME,point,1,0.1,0.1,0.1,0.01);
point.getWorld().spawnParticle(Particle.SMOKE,point,1,0.1,0.1,0.1,0.1); point.getWorld().spawnParticle(Particle.SMOKE,point,1,0.1,0.1,0.1,0.1);
point.getWorld().spawnParticle(Particle.CAMPFIRE_COSY_SMOKE,point,1,0.1,0.1,0.1,0.1); point.getWorld().spawnParticle(Particle.CAMPFIRE_COSY_SMOKE,point,1,0.1,0.1,0.1,0.1);
TargetingUtils.areaAffect(point,1, liv->!liv.equals(caster) && !liv.isDead() && !main.man().trustBackend.trusts(caster,liv), target->{ TargetingUtils.areaAffect(point,1, liv->!liv.equals(caster) && !liv.isDead() && !main.man().trustBackend.trusts(caster,liv) && !shaper.activeShellTasks.containsKey(liv.getUniqueId()), target->{
target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS,20*20,1,true,false,false)); target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS,20*20,1,true,false,false));
target.setFireTicks(20*20); target.setFireTicks(20*20);
}); });
@@ -142,7 +145,7 @@ public class RibAbility extends AbstractAbility {
} }
if (ticksElapsed >= spikeRiseAnimationTicks / 2 && ticksElapsed <= spikeRiseAnimationTicks + 4 && !damageDealt) { if (ticksElapsed >= spikeRiseAnimationTicks / 2 && ticksElapsed <= spikeRiseAnimationTicks + 4 && !damageDealt) {
TargetingUtils.areaAffect(finalSpikeBase,1,target -> !target.equals(caster) && !main.man().trustBackend.trusts(caster,target),target -> { TargetingUtils.areaAffect(finalSpikeBase,1,target -> !target.equals(caster) && !main.man().trustBackend.trusts(caster,target) && !shaper.activeShellTasks.containsKey(target.getUniqueId()),target -> {
damageDealt = true; damageDealt = true;
target.damage(7.0, caster); target.damage(7.0, caster);

View File

@@ -13,6 +13,8 @@ import org.bukkit.block.data.BlockData;
import org.bukkit.damage.DamageSource; import org.bukkit.damage.DamageSource;
import org.bukkit.damage.DamageType; import org.bukkit.damage.DamageType;
import org.bukkit.entity.*; import org.bukkit.entity.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.inventory.meta.trim.TrimPattern; import org.bukkit.inventory.meta.trim.TrimPattern;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Transformation; import org.bukkit.util.Transformation;
@@ -31,9 +33,12 @@ public class SentryAbility extends AbstractAbility {
} }
public static void spawnSentry(Location loc, Player owner, Material legsMat, Material turretMat, int ammo, long secondsAlive, long cooldownTicks) { public static void spawnSentry(Location loc, Player owner, Material legsMat, Material turretMat, int ammo, long secondsAlive, long cooldownTicks) {
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
ShaperAbility shaper = (ShaperAbility) shaperInstance;
World w = loc.getWorld(); World w = loc.getWorld();
loc = w.getHighestBlockAt((int) loc.x(), (int) loc.z()).getLocation().add(0,1,0); loc = w.getHighestBlockAt((int) loc.x(), (int) loc.z()).getLocation().add(0,1,0);
Location spawn = loc.clone().subtract(0,2,0); Location spawn = loc.clone().subtract(0,2,0);
List<Entity> turretParts = new ArrayList<>(); List<Entity> turretParts = new ArrayList<>();
// 1) Spawn the rotating turret (dispenser model) // 1) Spawn the rotating turret (dispenser model)
@@ -54,14 +59,12 @@ public class SentryAbility extends AbstractAbility {
turretParts.add(turret); turretParts.add(turret);
Slime dummy = w.spawn(turret.getLocation(),Slime.class,slime->{ Shulker dummy = w.spawn(turret.getLocation().clone().subtract(0,3,0),Shulker.class,shulker->{
slime.setInvisible(true); shulker.setInvisible(true);
slime.setSize(2); shulker.setHealth(10);
slime.setHealth(10); shulker.customName(Text.color("%s's Sentry\n".formatted(owner.getName())));
// TODO: Make this not a slime. shulker.setAI(false);
slime.customName(Text.color("%s's Sentry\n".formatted(owner.getName()))); shulker.addScoreboardTag("$/TrimServer/ Temp");
slime.setAI(false);
slime.addScoreboardTag("$/TrimServer/ Temp");
}); });
turretParts.add(dummy); turretParts.add(dummy);
@@ -113,7 +116,7 @@ public class SentryAbility extends AbstractAbility {
String bar = Text.generateProgressBar(10, maxAmmo, chamber); String bar = Text.generateProgressBar(10, maxAmmo, chamber);
meter.text(Text.color("%s's Sentry\n".formatted(owner.getName()) + "Ammo " + bar)); meter.text(Text.color("%s's Sentry\n".formatted(owner.getName()) + "Ammo " + bar));
Optional<Player> target = TargetingUtils.getClosestPlayer(finalLoc,15,p -> !p.isDead() && !p.equals(owner) && !main.man().trustBackend.trusts(owner,p)); Optional<Player> target = TargetingUtils.getClosestPlayer(finalLoc,15,p -> !p.isDead() && !p.equals(owner) && !main.man().trustBackend.trusts(owner,p) && !shaper.activeShellTasks.containsKey(p.getUniqueId()));
if (target.isPresent()) { if (target.isPresent()) {
Player tracked = target.get(); Player tracked = target.get();
@@ -205,6 +208,14 @@ public class SentryAbility extends AbstractAbility {
},20 * secondsAlive); },20 * secondsAlive);
} }
@EventHandler
public void onShulkerDeath(EntityDeathEvent e) {
if (!(e.getEntity() instanceof Shulker shulker)) return;
if (!shulker.getScoreboardTags().contains("$/TrimServer/ Temp")) return;
e.getDrops().clear();
}
@MaterialInfo(name = "Amethyst ", description = "Spawns a sentry which shoots the nearest player", cooldownTicks = 20 * 10) @MaterialInfo(name = "Amethyst ", description = "Spawns a sentry which shoots the nearest player", cooldownTicks = 20 * 10)
@Override @Override
public boolean amethystAbility(Player player) { public boolean amethystAbility(Player player) {

View File

@@ -14,6 +14,7 @@ import org.bukkit.Particle;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.damage.DamageSource; import org.bukkit.damage.DamageSource;
import org.bukkit.damage.DamageType; import org.bukkit.damage.DamageType;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.meta.trim.TrimPattern; import org.bukkit.inventory.meta.trim.TrimPattern;
@@ -21,6 +22,7 @@ import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import java.util.List;
import java.util.Optional; import java.util.Optional;
@PatternInfo(name = "Warden's Call", description = "Now I am become warden, destroyer of ears.") @PatternInfo(name = "Warden's Call", description = "Now I am become warden, destroyer of ears.")
@@ -50,11 +52,13 @@ public class SilenceAbility extends AbstractAbility {
blast.playWithin(40); blast.playWithin(40);
CustomDisplayRaytracer.traceWithReflection(chestLocation,direction,30,0.5,4,point->{ CustomDisplayRaytracer.traceWithReflection(chestLocation,direction,30,0.5,4,point->{
point.getWorld().spawnParticle(Particle.SONIC_BOOM, point.getLoc(), 1, 0, 0, 0, 0); point.getWorld().spawnParticle(Particle.SONIC_BOOM, point.getLoc(), 1, 0, 0, 0, 0);
Optional<LivingEntity> target = TargetingUtils.getClosestLivingEntity(point.getLoc(),1,entity -> !entity.equals(player) && !entity.isDead() && !main.man().trustBackend.trusts(player,entity) && !shaper.activeShellTasks.containsKey(entity.getUniqueId())); List<Entity> targets = point.getNearbyEntities(player,5,true,0.5, entity -> entity instanceof LivingEntity && !entity.equals(player) && !entity.isDead() && !main.man().trustBackend.trusts(player.getUniqueId(),entity.getUniqueId()) && !shaper.activeShellTasks.containsKey(entity.getUniqueId()));
target.ifPresent(value -> PlayerUtils.dealTrueDamage(value, DamageSource.builder(DamageType.SONIC_BOOM).withDirectEntity(player).build(), 10)); targets.forEach(target -> {
Verbose.send("Traced warden beam:"); PlayerUtils.dealTrueDamage((LivingEntity) target, DamageSource.builder(DamageType.SONIC_BOOM).withDirectEntity(player).build(), 10);
return target.isPresent(); });
Verbose.send("Traced warden beam");
return !targets.isEmpty();
},(point,blockHit) -> { },(point,blockHit) -> {
Verbose.send("Block was hit at %s. Return Value !Passable: %s",blockHit.getLocation(),!blockHit.isPassable()); Verbose.send("Block was hit at %s. Return Value !Passable: %s",blockHit.getLocation(),!blockHit.isPassable());
return !blockHit.isPassable(); return !blockHit.isPassable();

View File

@@ -5,7 +5,6 @@ import me.trouper.trimserver.server.systems.abilities.PatternInfo;
import me.trouper.trimserver.server.systems.abilities.AbstractAbility; import me.trouper.trimserver.server.systems.abilities.AbstractAbility;
import me.trouper.trimserver.utils.SoundPlayer; import me.trouper.trimserver.utils.SoundPlayer;
import me.trouper.trimserver.utils.TargetingUtils; import me.trouper.trimserver.utils.TargetingUtils;
import me.trouper.trimserver.utils.Text;
import me.trouper.trimserver.utils.visual.DisplayUtils; import me.trouper.trimserver.utils.visual.DisplayUtils;
import me.trouper.trimserver.utils.visual.BlockDisplayRaytracer; import me.trouper.trimserver.utils.visual.BlockDisplayRaytracer;
@@ -38,6 +37,9 @@ public class SpireAbility extends AbstractAbility {
} }
private void createEnderStorm(Player player, Material material, int duration, int spireHeight) { private void createEnderStorm(Player player, Material material, int duration, int spireHeight) {
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
ShaperAbility shaper = (ShaperAbility) shaperInstance;
// Cancel any existing spire for this player // Cancel any existing spire for this player
if (activeTasks.containsKey(player.getUniqueId())) { if (activeTasks.containsKey(player.getUniqueId())) {
activeTasks.get(player.getUniqueId()).cancel(); activeTasks.get(player.getUniqueId()).cancel();
@@ -82,7 +84,7 @@ public class SpireAbility extends AbstractAbility {
double sphereRadius = spireHeight * 0.75; double sphereRadius = spireHeight * 0.75;
// Create initial sphere particle effect // Create initial sphere particle effect
Color sphereColor = getColorForMaterial(material); Color sphereColor = getColor(material);
Consumer<Location> particleAction = DisplayUtils.DUST_PARTICLE_FACTORY.apply(sphereColor, 1.2f); Consumer<Location> particleAction = DisplayUtils.DUST_PARTICLE_FACTORY.apply(sphereColor, 1.2f);
// Create expanding sphere effect // Create expanding sphere effect
@@ -130,7 +132,7 @@ public class SpireAbility extends AbstractAbility {
// Fire shulker bullets every 15 ticks (0.75 seconds) // Fire shulker bullets every 15 ticks (0.75 seconds)
if (tickCounter % 15 == 0) { if (tickCounter % 15 == 0) {
List<Player> targets = world.getNearbyEntities(sphereCenter, sphereRadius, sphereRadius, sphereRadius).stream() List<Player> targets = world.getNearbyEntities(sphereCenter, sphereRadius, sphereRadius, sphereRadius).stream()
.filter(entity -> entity instanceof Player && !entity.equals(player) && !main.man().trustBackend.trusts(player, (LivingEntity) entity)) .filter(entity -> entity instanceof Player && !entity.equals(player) && !main.man().trustBackend.trusts(player.getUniqueId(), entity.getUniqueId()) && !shaper.activeShellTasks.containsKey(entity.getUniqueId()))
.map(entity -> (Player) entity) .map(entity -> (Player) entity)
.toList(); .toList();
@@ -336,7 +338,7 @@ public class SpireAbility extends AbstractAbility {
} }
} }
private Color getColorForMaterial(Material material) { private Color getColor(Material material) {
return switch (material) { return switch (material) {
case AMETHYST_BLOCK -> Color.fromRGB(137, 0, 201); case AMETHYST_BLOCK -> Color.fromRGB(137, 0, 201);
case COPPER_BLOCK -> Color.fromRGB(184, 115, 51); case COPPER_BLOCK -> Color.fromRGB(184, 115, 51);

View File

@@ -28,11 +28,14 @@ public class TideAbility extends AbstractAbility {
} }
public void spawnTidalWave(Player caster) { public void spawnTidalWave(Player caster) {
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
ShaperAbility shaper = (ShaperAbility) shaperInstance;
Vector direction = caster.getLocation().getDirection(); Vector direction = caster.getLocation().getDirection();
DisplayUtils.waveFan(caster.getLocation().add(0, 2,0),10,direction,90,0.1, point->{ DisplayUtils.waveFan(caster.getLocation().add(0, 2,0),10,direction,90,0.1, point->{
point.getWorld().spawnParticle(Particle.BLOCK_CRUMBLE,point,8,0.1,0.1,0.1,0.1, Material.BLUE_STAINED_GLASS.createBlockData()); point.getWorld().spawnParticle(Particle.BLOCK_CRUMBLE,point,8,0.1,0.1,0.1,0.1, Material.BLUE_STAINED_GLASS.createBlockData());
TargetingUtils.areaAffect(point,0.3,5,0.3,target -> !main.man().trustBackend.trusts(caster,target),target -> { TargetingUtils.areaAffect(point,0.3,5,0.3,target -> !main.man().trustBackend.trusts(caster,target) && !shaper.activeShellTasks.containsKey(target.getUniqueId()),target -> {
SoundPlayer blockSound = new SoundPlayer(target.getLocation(), Sound.ENTITY_PLAYER_SPLASH, 1, 0.5F); SoundPlayer blockSound = new SoundPlayer(target.getLocation(), Sound.ENTITY_PLAYER_SPLASH, 1, 0.5F);
Vector dir = target.getLocation().toVector().subtract(caster.getLocation().toVector()).normalize(); Vector dir = target.getLocation().toVector().subtract(caster.getLocation().toVector()).normalize();
double strength = 0.5; double strength = 0.5;

View File

@@ -31,6 +31,10 @@ public class WayfinderAbility extends AbstractAbility {
public void stomp(Player caster) { public void stomp(Player caster) {
if (caster.getLocation().clone().subtract(0,1,0).getBlock().isPassable()) return; if (caster.getLocation().clone().subtract(0,1,0).getBlock().isPassable()) return;
AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
ShaperAbility shaper = (ShaperAbility) shaperInstance;
caster.setVelocity(caster.getVelocity().setY(caster.getVelocity().getY() + 1.5)); caster.setVelocity(caster.getVelocity().setY(caster.getVelocity().getY() + 1.5));
SoundPlayer jump = new SoundPlayer(caster.getLocation(), Sound.ENTITY_ENDER_DRAGON_FLAP, 1, 2); SoundPlayer jump = new SoundPlayer(caster.getLocation(), Sound.ENTITY_ENDER_DRAGON_FLAP, 1, 2);
jump.playWithin(10); jump.playWithin(10);
@@ -59,7 +63,7 @@ public class WayfinderAbility extends AbstractAbility {
block.setCancelDrop(true); block.setCancelDrop(true);
}); });
TargetingUtils.areaAffect(caster.getLocation(),10,target -> !target.isDead() && !target.equals(caster) && !main.man().trustBackend.trusts(caster,target),target->{ TargetingUtils.areaAffect(caster.getLocation(),10,target -> !target.isDead() && !target.equals(caster) && !main.man().trustBackend.trusts(caster,target) && !shaper.activeShellTasks.containsKey(target.getUniqueId()),target->{
SoundPlayer hit = new SoundPlayer(target.getLocation(), Sound.ENTITY_EVOKER_FANGS_ATTACK, 1, 2); SoundPlayer hit = new SoundPlayer(target.getLocation(), Sound.ENTITY_EVOKER_FANGS_ATTACK, 1, 2);
Vector direction = target.getLocation().toVector().subtract(caster.getEyeLocation().toVector()).normalize(); Vector direction = target.getLocation().toVector().subtract(caster.getEyeLocation().toVector()).normalize();
target.setVelocity(direction.multiply(0.5).setY(0.3)); target.setVelocity(direction.multiply(0.5).setY(0.3));

View File

@@ -29,11 +29,13 @@ public class WildAbility extends AbstractAbility {
} }
public void pullVine(Player caster, Player target, Material vineMaterial) { public void pullVine(Player caster, Player target, Material vineMaterial) {
// --- Basic Validation --- AbstractAbility shaperInstance = main.man().abilityBackend.getAbility(TrimPattern.SHAPER);
ShaperAbility shaper = (ShaperAbility) shaperInstance;
if (caster == null || !caster.isOnline() || target == null || !target.isOnline() || caster.equals(target)) return; if (caster == null || !caster.isOnline() || target == null || !target.isOnline() || caster.equals(target)) return;
if (shaper.activeShellTasks.containsKey(target.getUniqueId())) return;
if (caster.getWorld() != target.getWorld()) return; if (caster.getWorld() != target.getWorld()) return;
// --- Configuration --- // --- Configuration ---
final Location casterStartLoc = caster.getLocation().clone().add(0,1,0); final Location casterStartLoc = caster.getLocation().clone().add(0,1,0);
final double maxDistance = 20.0; final double maxDistance = 20.0;