Skip to content

Commit

Permalink
Slyyam wind changes
Browse files Browse the repository at this point in the history
  • Loading branch information
slyyam authored Feb 23, 2024
1 parent b695257 commit 9c6d9ff
Show file tree
Hide file tree
Showing 8 changed files with 262 additions and 164 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ public enum ClassAbility {
GUARDING_BOLT("Guarding Bolt"),
LAST_BREATH("Last Breath"),
SKYHOOK("Skyhook"),
SLIPSTREAM("Slipstream"),
AEROBLAST("Aeroblast"),
WHIRLWIND("Whirlwind"),
HOWLINGWINDS("Howling Winds"),
WIND_WALK_DEPTHS("Wind Walk"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
import com.playmonumenta.plugins.depths.abilities.steelsage.Scrapshot;
import com.playmonumenta.plugins.depths.abilities.steelsage.Sidearm;
import com.playmonumenta.plugins.depths.abilities.steelsage.SteelStallion;
import com.playmonumenta.plugins.depths.abilities.windwalker.Aeroblast;
import com.playmonumenta.plugins.depths.abilities.windwalker.Aeromancy;
import com.playmonumenta.plugins.depths.abilities.windwalker.DepthsDodging;
import com.playmonumenta.plugins.depths.abilities.windwalker.DepthsWindWalk;
Expand All @@ -102,7 +103,6 @@
import com.playmonumenta.plugins.depths.abilities.windwalker.OneWithTheWind;
import com.playmonumenta.plugins.depths.abilities.windwalker.RestoringDraft;
import com.playmonumenta.plugins.depths.abilities.windwalker.Skyhook;
import com.playmonumenta.plugins.depths.abilities.windwalker.Slipstream;
import com.playmonumenta.plugins.depths.abilities.windwalker.Whirlwind;
import com.playmonumenta.plugins.depths.abilities.windwalker.WindsweptCombos;
import com.playmonumenta.plugins.depths.guis.DepthsGUICommands;
Expand Down Expand Up @@ -536,6 +536,7 @@ public static Collection<DepthsAbilityInfo<?>> getAbilities() {
DepthsVolley.INFO,

//Windwalker abilities
Aeroblast.INFO,
Aeromancy.INFO,
DepthsDodging.INFO,
GuardingBolt.INFO,
Expand All @@ -544,7 +545,6 @@ public static Collection<DepthsAbilityInfo<?>> getAbilities() {
OneWithTheWind.INFO,
RestoringDraft.INFO,
Skyhook.INFO,
Slipstream.INFO,
DepthsWindWalk.INFO,
Whirlwind.INFO,
WindsweptCombos.INFO,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
package com.playmonumenta.plugins.depths.abilities.windwalker;

import com.playmonumenta.plugins.Plugin;
import com.playmonumenta.plugins.abilities.AbilityTriggerInfo;
import com.playmonumenta.plugins.abilities.Description;
import com.playmonumenta.plugins.abilities.DescriptionBuilder;
import com.playmonumenta.plugins.classes.ClassAbility;
import com.playmonumenta.plugins.depths.DepthsTree;
import com.playmonumenta.plugins.depths.abilities.DepthsAbility;
import com.playmonumenta.plugins.depths.abilities.DepthsAbilityInfo;
import com.playmonumenta.plugins.depths.abilities.DepthsTrigger;
import com.playmonumenta.plugins.depths.charmfactory.CharmEffects;
import com.playmonumenta.plugins.effects.PercentSpeed;
import com.playmonumenta.plugins.events.DamageEvent;
import com.playmonumenta.plugins.itemstats.abilities.CharmManager;
import com.playmonumenta.plugins.particle.PartialParticle;
import com.playmonumenta.plugins.utils.DamageUtils;
import com.playmonumenta.plugins.utils.EntityUtils;
import com.playmonumenta.plugins.utils.FastUtils;
import com.playmonumenta.plugins.utils.Hitbox;
import com.playmonumenta.plugins.utils.LocationUtils;
import com.playmonumenta.plugins.utils.ParticleUtils;
import com.playmonumenta.plugins.utils.ScoreboardUtils;
import com.playmonumenta.plugins.utils.VectorUtils;
import net.kyori.adventure.text.format.TextColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.Sound;
import org.bukkit.SoundCategory;
import org.bukkit.World;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.BoundingBox;
import org.bukkit.util.Vector;

public class Aeroblast extends DepthsAbility {

public static final String ABILITY_NAME = "Aeroblast";
public static final double[] DAMAGE = {6, 7, 8, 9, 10, 12};
public static final int COOLDOWN = 6 * 20;
private static final int DURATION = 3 * 20;
private static final double SPEED_AMPLIFIER = 0.2;
private static final String PERCENT_SPEED_EFFECT_NAME = "AeroblastSpeedEffect";
private static final int SIZE = 4;
private static final float KNOCKBACK_SPEED = 2f;

public static final String CHARM_COOLDOWN = "Aeroblast Cooldown";

public static final DepthsAbilityInfo<Aeroblast> INFO =
new DepthsAbilityInfo<>(Aeroblast.class, ABILITY_NAME, Aeroblast::new, DepthsTree.WINDWALKER, DepthsTrigger.SHIFT_RIGHT_CLICK)
.linkedSpell(ClassAbility.AEROBLAST)
.cooldown(CHARM_COOLDOWN, COOLDOWN)
.addTrigger(new AbilityTriggerInfo<>("cast", "cast", Aeroblast::cast, DepthsTrigger.SHIFT_RIGHT_CLICK))
.displayItem(Material.PHANTOM_MEMBRANE)
.descriptions(Aeroblast::getDescription);

private final float mKnockbackSpeed;
private final int mDuration;
private final double mSpeed;
private final double mDamage;
private final double mSize;

public Aeroblast(Plugin plugin, Player player) {
super(plugin, player, INFO);
mKnockbackSpeed = (float) CharmManager.calculateFlatAndPercentValue(mPlayer, CharmEffects.AEROBLAST_KNOCKBACK.mEffectName, KNOCKBACK_SPEED);
mDuration = CharmManager.getDuration(mPlayer, CharmEffects.AEROBLAST_SPEED_DURATION.mEffectName, DURATION);
mSpeed = SPEED_AMPLIFIER + CharmManager.getLevelPercentDecimal(mPlayer, CharmEffects.AEROBLAST_SPEED_AMPLIFIER.mEffectName);
mDamage = CharmManager.calculateFlatAndPercentValue(mPlayer, CharmEffects.AEROBLAST_DAMAGE.mEffectName, DAMAGE[mRarity - 1]);
mSize = CharmManager.getRadius(mPlayer, CharmEffects.AEROBLAST_SIZE.mEffectName, SIZE);
}

public boolean cast() {
if (isOnCooldown()) {
return false;
}
putOnCooldown();
new PartialParticle(Particle.EXPLOSION_NORMAL, mPlayer.getLocation().add(0, 1, 0), 20, 0.5, 0.5, 0.5, 0.075f).spawnAsPlayerActive(mPlayer);
mPlugin.mEffectManager.addEffect(mPlayer, PERCENT_SPEED_EFFECT_NAME, new PercentSpeed(mDuration, mSpeed, PERCENT_SPEED_EFFECT_NAME));

Location startLoc = mPlayer.getEyeLocation();
Location slightOffsetLoc = startLoc.clone().add(startLoc.clone().getDirection().multiply(0.25));
Location endLoc = LocationUtils.rayTraceToBlock(mPlayer, mSize);
World world = startLoc.getWorld();
world.playSound(slightOffsetLoc, Sound.ENTITY_EVOKER_CAST_SPELL, SoundCategory.PLAYERS, 1.25f, 1.5f);
world.playSound(slightOffsetLoc, Sound.ENTITY_BLAZE_SHOOT, SoundCategory.PLAYERS, 1.25f, 1.5f);
world.playSound(slightOffsetLoc, Sound.ENTITY_PLAYER_ATTACK_STRONG, SoundCategory.PLAYERS, 1.25f, 0.5f);
world.playSound(slightOffsetLoc, Sound.ENTITY_ENDER_DRAGON_FLAP, SoundCategory.PLAYERS, 1.25f, 0.7f);

Vector velocity = mPlayer.getLocation().getDirection().multiply(-0.75);
mPlayer.setVelocity(velocity.setY(Math.max(0.1, velocity.getY())));

for (LivingEntity mob : Hitbox.approximateCylinder(startLoc, endLoc, mSize / 2, false).accuracy(0.5).getHitMobs()) {
DamageUtils.damage(mPlayer, mob, DamageEvent.DamageType.MAGIC, mDamage, mInfo.getLinkedSpell());
if (!EntityUtils.isBoss(mob) && !ScoreboardUtils.checkTag(mob, "callicarpa_flower") && !ScoreboardUtils.checkTag(mob, "hoglin_menace") && mob.hasAI()) {
Vector vel = mPlayer.getEyeLocation().getDirection().setY(0.15).multiply(mKnockbackSpeed);
mob.setVelocity(vel);

new BukkitRunnable() {
int mTicks = 0;

@Override
public void run() {
if (mTicks > 15) {
this.cancel();
}

BoundingBox offsetBox = mob.getBoundingBox().clone();
offsetBox.shift(mPlayer.getEyeLocation().getDirection().getX(), 0.15, mPlayer.getEyeLocation().getDirection().getZ());
offsetBox.expand(-0.2, -0.4, -0.2);

if (LocationUtils.collidesWithBlocks(offsetBox, mob.getWorld())) {
// handle collision
explode(mob, world);
this.cancel();
return;
}
mTicks++;
}
}.runTaskTimer(mPlugin, 0, 1);
}
}

new BukkitRunnable() {
final Location mLoc = mPlayer.getEyeLocation();
final Vector mIncrement = mLoc.getDirection().multiply(1.5);

@Override
public void run() {
for (int i = 0; i < 4; i++) {
mLoc.add(mIncrement.clone().multiply(0.25));

if (LocationUtils.collidesWithBlocks(BoundingBox.of(mLoc.clone().add(0.4, 0.4, 0.4), mLoc.clone().add(-0.4, -0.4, -0.4)), mLoc.getWorld(), false) || mLoc.distance(startLoc) > mSize) {
new PartialParticle(Particle.EXPLOSION_NORMAL, mLoc, 20, 0.05, 0.05, 0.05, 0.2).spawnAsPlayerActive(mPlayer);
this.cancel();
break;
}
}
new PartialParticle(Particle.CLOUD, mLoc.clone(), 1, 0.1, 0.1, 0.1, 0.1).spawnAsPlayerActive(mPlayer);
ParticleUtils.drawParticleCircleExplosion(mPlayer, mLoc.clone().setDirection(mIncrement), 0, mSize, 0, 90, 30, 0.275f,
true, 0, 0, Particle.EXPLOSION_NORMAL);

for (int i = 0; i < 3; i++) {
Vector dir = VectorUtils.rotateTargetDirection(mLoc.getDirection(), 90, FastUtils.randomDoubleInRange(-225, 45));
Location l = mLoc.clone().add(dir.multiply(FastUtils.randomDoubleInRange(0.9, mSize / 2)));
ParticleUtils.drawParticleLineSlash(l, l.getDirection(), 0, 1.5, 0.1, 5,
(Location lineLoc, double middleProgress, double endProgress, boolean middle) -> new PartialParticle(Particle.ELECTRIC_SPARK, lineLoc, 1, 0, 0, 0, 0.05)
.spawnAsPlayerActive(mPlayer));
}

}
}.runTaskTimer(mPlugin, 0, 1);

return true;
}

private void explode(LivingEntity mob, World world) {
DamageUtils.damage(mPlayer, mob, DamageEvent.DamageType.MAGIC, mDamage * 1.5, mInfo.getLinkedSpell(), true);
new PartialParticle(Particle.CRIT, mob.getLocation().add(0, 1, 0), 100, 0.1, 0.1, 0.1, 1.25).spawnAsPlayerActive(mPlayer);
new PartialParticle(Particle.EXPLOSION_LARGE, mob.getLocation().add(0, 1, 0), 1, 0, 0, 0, 0.2).spawnAsPlayerActive(mPlayer);
world.playSound(mob.getLocation(), Sound.ENTITY_BLAZE_HURT, SoundCategory.PLAYERS, 2f, 1.5f);
world.playSound(mob.getLocation(), Sound.ENTITY_PLAYER_ATTACK_STRONG, SoundCategory.PLAYERS, 2f, 0.5f);
world.playSound(mob.getLocation(), Sound.BLOCK_POINTED_DRIPSTONE_LAND, SoundCategory.PLAYERS, 2.25f, 0.5f);
world.playSound(mob.getLocation(), Sound.ENTITY_PLAYER_ATTACK_CRIT, SoundCategory.PLAYERS, 2.25f, 0.5f);
}

private static Description<Aeroblast> getDescription(int rarity, TextColor color) {
return new DescriptionBuilder<Aeroblast>(color)
.add("Right click while sneaking to blow a front-facing gust of wind, dealing ")
.addDepthsDamage(a -> a.mDamage, DAMAGE[rarity - 1], true)
.add(" magic damage to all mobs up to ")
.add(a -> a.mSize, SIZE)
.add(" blocks away, and knocking back all non-boss enemies. Deal an additional ")
.addDepthsDamage(a -> a.mDamage * 1.5, DAMAGE[rarity - 1] * 1.5, true)
.add(" magic damage if enemies hit by this ability collide with a wall within 0.75 seconds. " +
"Additionally, casting this ability slightly knocks you backwards and grants you ")
.addPercent(a -> a.mSpeed, SPEED_AMPLIFIER)
.add(" speed for ")
.addDuration(a -> a.mDuration, DURATION)
.add(" seconds.")
.addCooldown(COOLDOWN);
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ public class DepthsWindWalk extends DepthsAbility {
public static final String CHARM_COOLDOWN = "Wind Walk Cooldown";

public static final DepthsAbilityInfo<DepthsWindWalk> INFO =
new DepthsAbilityInfo<>(DepthsWindWalk.class, "Wind Walk", DepthsWindWalk::new, DepthsTree.WINDWALKER, DepthsTrigger.SHIFT_RIGHT_CLICK)
new DepthsAbilityInfo<>(DepthsWindWalk.class, "Wind Walk", DepthsWindWalk::new, DepthsTree.WINDWALKER, DepthsTrigger.RIGHT_CLICK)
.linkedSpell(ClassAbility.WIND_WALK_DEPTHS)
.cooldown(CHARM_COOLDOWN, COOLDOWN)
.addTrigger(new AbilityTriggerInfo<>("cast", "cast", DepthsWindWalk::cast, DepthsTrigger.SHIFT_RIGHT_CLICK))
.addTrigger(new AbilityTriggerInfo<>("cast", "cast", DepthsWindWalk::cast, DepthsTrigger.RIGHT_CLICK))
.displayItem(Material.WHITE_DYE)
.descriptions(DepthsWindWalk::getDescription);

Expand Down Expand Up @@ -144,8 +144,8 @@ public void run() {
@Override
public void onHurt(DamageEvent event, @Nullable Entity damager, @Nullable LivingEntity source) {
if (source != null
&& (event.getType() == DamageEvent.DamageType.MELEE)
&& mIsWalking) {
&& (event.getType() == DamageEvent.DamageType.MELEE)
&& mIsWalking) {
event.setCancelled(true);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@
import com.playmonumenta.plugins.depths.abilities.DepthsAbilityInfo;
import com.playmonumenta.plugins.depths.abilities.DepthsTrigger;
import com.playmonumenta.plugins.depths.charmfactory.CharmEffects;
import com.playmonumenta.plugins.itemstats.ItemStatManager;
import com.playmonumenta.plugins.itemstats.abilities.CharmManager;
import com.playmonumenta.plugins.particle.PartialParticle;
import com.playmonumenta.plugins.utils.AbilityUtils;
import com.playmonumenta.plugins.utils.EntityUtils;
import java.util.Map;
import java.util.WeakHashMap;
import net.kyori.adventure.text.format.TextColor;
import org.bukkit.Location;
import org.bukkit.Material;
Expand All @@ -22,6 +26,7 @@
import org.bukkit.World;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Snowball;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;

Expand All @@ -31,12 +36,13 @@ public class HowlingWinds extends DepthsAbility {
public static final int COOLDOWN = 20 * 20;
public static final int VULN_RADIUS = 4;
public static final int PULL_RADIUS = 16;
public static final int DISTANCE = 6;
public static final int DISTANCE = 12;
public static final int[] PULL_INTERVAL = {20, 18, 16, 14, 12, 8};
public static final double[] VULN_AMPLIFIER = {0.075, 0.1, 0.125, 0.15, 0.175, 0.225};
public static final int DURATION_TICKS = 5 * 20;
public static final double PULL_VELOCITY = 0.9;
public static final double BASE_RATIO = 0.15;
private final Map<Snowball, ItemStatManager.PlayerItemStats> mProjectiles = new WeakHashMap<>();

public static final String CHARM_COOLDOWN = "Howling Winds Cooldown";

Expand Down Expand Up @@ -71,23 +77,48 @@ public boolean cast() {
}
putOnCooldown();

Location loc = mPlayer.getEyeLocation();
World world = mPlayer.getWorld();
world.playSound(loc, Sound.ENTITY_HORSE_BREATHE, SoundCategory.PLAYERS, 0.8f, 0.25f);
world.playSound(loc, Sound.BLOCK_BUBBLE_COLUMN_WHIRLPOOL_INSIDE, SoundCategory.PLAYERS, 1.0f, 1.2f);
new PartialParticle(Particle.CLOUD, mPlayer.getLocation(), 15, 0.25f, 0.1f, 0.25f).spawnAsPlayerActive(mPlayer);
Vector dir = loc.getDirection().normalize();
for (int i = 0; i < mDistance; i++) {
loc.add(dir);

new PartialParticle(Particle.FIREWORKS_SPARK, loc, 5, 0.1, 0.1, 0.1, 0.1).spawnAsPlayerActive(mPlayer);
new PartialParticle(Particle.CLOUD, loc, 5, 0.1, 0.1, 0.1, 0.1).spawnAsPlayerActive(mPlayer);
int size = EntityUtils.getNearbyMobs(loc, 2, mPlayer).size();
if (loc.getBlock().getType().isSolid() || i >= mDistance - 1 || size > 0) {
explode(loc);
break;
Location loc = mPlayer.getLocation();
world.playSound(loc, Sound.ENTITY_HORSE_BREATHE, 1.0f, 0.25f);
Snowball proj = AbilityUtils.spawnAbilitySnowball(mPlugin, mPlayer, world, 1.25, "HowlingWindsProjectile", Particle.CLOUD);
ItemStatManager.PlayerItemStats playerItemStats = mPlugin.mItemStatManager.getPlayerItemStatsCopy(mPlayer);
mProjectiles.put(proj, playerItemStats);
// Clear out list just in case
mProjectiles.keySet().removeIf(p -> p.isDead() || !p.isValid() || p.getTicksLived() >= 100);
new BukkitRunnable() {
int mT = 0;
final Location mPlayerLocation = mPlayer.getLocation();

@Override
public void run() {
if (mProjectiles.get(proj) != playerItemStats) {
mPlugin.mProjectileEffectTimers.removeEntity(proj);
this.cancel();
}

if (proj.getLocation().distance(mPlayerLocation) > mDistance) {
proj.remove();
mPlugin.mProjectileEffectTimers.removeEntity(proj);
this.cancel();
}

// max time limit to avoid weird scenarios
if (mT > 100) {
mPlugin.mProjectileEffectTimers.removeEntity(proj);
proj.remove();
this.cancel();
}

if (proj.isDead()) {
if (mProjectiles.remove(proj) != null) {
explode(proj.getLocation());
}
mPlugin.mProjectileEffectTimers.removeEntity(proj);
this.cancel();
}
mT++;
}
}
}.runTaskTimer(mPlugin, 0, 1);

return true;
}
Expand Down Expand Up @@ -141,11 +172,12 @@ public void run() {

private static Description<HowlingWinds> getDescription(int rarity, TextColor color) {
return new DescriptionBuilder<HowlingWinds>(color)
.add("Swap hands to summon a hurricane that lasts ")
.addDuration(a -> a.mDuration, DURATION_TICKS)
.add(" seconds at the location you are looking at, up to ")

.add("Swap hands to throw a projectile that travels up to ")
.add(a -> a.mDistance, DISTANCE)
.add(" blocks away. The hurricane strongly pulls enemies within ")
.add(" blocks away. Upon hitting a mob, block, or reaching its max distance, it explodes and generates a hurricane that lasts ")
.addDuration(a -> a.mDuration, DURATION_TICKS)
.add(" seconds. The hurricane strongly pulls enemies within ")
.add(a -> a.mRadius, PULL_RADIUS)
.add(" blocks towards its center on spawn and continues pulling every ")
.addDuration(a -> PULL_INTERVAL[rarity - 1], PULL_INTERVAL[rarity - 1], true, true)
Expand Down
Loading

0 comments on commit 9c6d9ff

Please sign in to comment.