mirror of
https://github.com/TotalFreedomMC/TF-ProjectKorra.git
synced 2024-06-10 14:24:58 +00:00
3c1d6b7b85
## Additions * Adds Blue Fire SubElement. > *Adds related damage, cooldown, and range modifiers for configuration * Adds Sticks, Sponges, and Chorus Fruit to cookable HeatControl items. * Adds Smoker, BlastFurnace, and extinguished Campfires to blocks which FireBlast can light. * Adds new TempBlock constructor which takes in a `long revertTime` parameter * Adds new blocks to block lists in configuration >* Adds new nether plants to plantBlocks list >* Adds new earth blocks to earthBlocks list ## Fixes * Fixes AvatarState buffs overriding day related buffs for firebending. * Fixes Blaze not going up hills, going through walls (mostly), jumping gaps. * Fixes Furnaces and related blocks not smelting after being activated by FireBlast ## Removals * Removes BlazeArc dependencies for Fire Abilities which ignite the ground. * Removes smoke particles from Fire bending to increase visibility and better emulate the show. ## Misc. Changes * Changes API versioning to 1.16.1 * Fire from Firebending no longer reverts all at once. * Changes Combustion animation to be more beam-like rather than a rehash of FireBlast. * Changes Add, Remove, Display command to properly display space for Blue Fire. * Changes `ElementalAbility#isFire()` to check for SOUL_FIRE_FLAME. * Changes isIgnitable to check whether fire can be placed at that location rather than solely based on flammability. * Changes firebending abilities to use `FireAbility#playFirebendingParticles()` & `FireAbility#createTempFire()` where applicable. * Changes `FireAbility#playFirebendingParticles()` to play blue fire particles when player has the BlueFire subelement.
276 lines
7.7 KiB
Java
276 lines
7.7 KiB
Java
package com.projectkorra.projectkorra.firebending;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
import org.bukkit.Location;
|
|
import org.bukkit.block.Block;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.scheduler.BukkitRunnable;
|
|
import org.bukkit.util.Vector;
|
|
|
|
import com.projectkorra.projectkorra.GeneralMethods;
|
|
import com.projectkorra.projectkorra.ProjectKorra;
|
|
import com.projectkorra.projectkorra.Element.SubElement;
|
|
import com.projectkorra.projectkorra.ability.BlueFireAbility;
|
|
import com.projectkorra.projectkorra.ability.FireAbility;
|
|
import com.projectkorra.projectkorra.attribute.Attribute;
|
|
|
|
public class FireBurst extends FireAbility {
|
|
|
|
@Attribute("Charged")
|
|
private boolean charged;
|
|
@Attribute(Attribute.DAMAGE)
|
|
private int damage;
|
|
@Attribute(Attribute.CHARGE_DURATION)
|
|
private long chargeTime;
|
|
@Attribute(Attribute.RANGE)
|
|
private long range;
|
|
@Attribute(Attribute.COOLDOWN)
|
|
private long cooldown;
|
|
private double angleTheta;
|
|
private double anglePhi;
|
|
private double particlesPercentage;
|
|
private ArrayList<FireBlast> blasts;
|
|
|
|
public FireBurst(final Player player) {
|
|
super(player);
|
|
|
|
this.charged = false;
|
|
this.damage = getConfig().getInt("Abilities.Fire.FireBurst.Damage");
|
|
this.chargeTime = getConfig().getLong("Abilities.Fire.FireBurst.ChargeTime");
|
|
this.range = getConfig().getLong("Abilities.Fire.FireBurst.Range");
|
|
this.cooldown = getConfig().getLong("Abilities.Fire.FireBurst.Cooldown");
|
|
this.angleTheta = getConfig().getDouble("Abilities.Fire.FireBurst.AngleTheta");
|
|
this.anglePhi = getConfig().getDouble("Abilities.Fire.FireBurst.AnglePhi");
|
|
this.particlesPercentage = getConfig().getDouble("Abilities.Fire.FireBurst.ParticlesPercentage");
|
|
this.blasts = new ArrayList<>();
|
|
|
|
if (!this.bPlayer.canBend(this) || hasAbility(player, FireBurst.class)) {
|
|
return;
|
|
}
|
|
|
|
long chargeTimeMod = 0;
|
|
|
|
if (isDay(player.getWorld())) {
|
|
chargeTimeMod = (long) (this.getDayFactor(chargeTime) - chargeTime);
|
|
}
|
|
|
|
chargeTimeMod = (long) (bPlayer.canUseSubElement(SubElement.BLUE_FIRE) ? (chargeTime / BlueFireAbility.getCooldownFactor() - chargeTime) + chargeTimeMod : chargeTimeMod);
|
|
|
|
if (this.bPlayer.isAvatarState()) {
|
|
this.chargeTime = getConfig().getLong("Abilities.Avatar.AvatarState.Fire.FireBurst.Damage");
|
|
this.damage = getConfig().getInt("Abilities.Avatar.AvatarState.Fire.FireBurst.Damage");
|
|
this.cooldown = getConfig().getLong("Abilities.Avatar.AvatarState.Fire.FireBurst.Cooldown");
|
|
}
|
|
|
|
this.chargeTime += chargeTimeMod;
|
|
|
|
this.start();
|
|
}
|
|
|
|
public static void coneBurst(final Player player) {
|
|
final FireBurst burst = getAbility(player, FireBurst.class);
|
|
if (burst != null) {
|
|
burst.coneBurst();
|
|
}
|
|
}
|
|
|
|
private void coneBurst() {
|
|
if (this.charged) {
|
|
final Location location = this.player.getEyeLocation();
|
|
final List<Block> safeBlocks = GeneralMethods.getBlocksAroundPoint(this.player.getLocation(), 2);
|
|
final Vector vector = location.getDirection();
|
|
|
|
final double angle = Math.toRadians(30);
|
|
double x, y, z;
|
|
final double r = 1;
|
|
|
|
for (double theta = 0; theta <= 180; theta += this.angleTheta) {
|
|
final double dphi = this.anglePhi / Math.sin(Math.toRadians(theta));
|
|
for (double phi = 0; phi < 360; phi += dphi) {
|
|
final double rphi = Math.toRadians(phi);
|
|
final double rtheta = Math.toRadians(theta);
|
|
|
|
x = r * Math.cos(rphi) * Math.sin(rtheta);
|
|
y = r * Math.sin(rphi) * Math.sin(rtheta);
|
|
z = r * Math.cos(rtheta);
|
|
final Vector direction = new Vector(x, z, y);
|
|
|
|
if (direction.angle(vector) <= angle) {
|
|
final FireBlast fblast = new FireBlast(location, direction.normalize(), this.player, this.damage, safeBlocks);
|
|
fblast.setRange(this.range);
|
|
fblast.setFireBurst(true);
|
|
}
|
|
}
|
|
}
|
|
this.bPlayer.addCooldown(this);
|
|
}
|
|
this.remove();
|
|
}
|
|
|
|
/**
|
|
* To combat the sphere FireBurst lag we are only going to show a certain
|
|
* percentage of FireBurst particles at a time per tick. As the bursts
|
|
* spread out then we can show more at a time.
|
|
*/
|
|
public void handleSmoothParticles() {
|
|
for (int i = 0; i < this.blasts.size(); i++) {
|
|
final FireBlast fblast = this.blasts.get(i);
|
|
final int toggleTime = (int) (i % (100.0 / this.particlesPercentage));
|
|
new BukkitRunnable() {
|
|
@Override
|
|
public void run() {
|
|
fblast.setShowParticles(true);
|
|
}
|
|
}.runTaskLater(ProjectKorra.plugin, toggleTime);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void progress() {
|
|
if (!this.bPlayer.canBendIgnoreCooldowns(this)) {
|
|
this.remove();
|
|
return;
|
|
}
|
|
|
|
if (System.currentTimeMillis() > this.getStartTime() + this.chargeTime && !this.charged) {
|
|
this.charged = true;
|
|
}
|
|
|
|
if (!this.player.isSneaking()) {
|
|
if (this.charged) {
|
|
this.sphereBurst();
|
|
} else {
|
|
this.remove();
|
|
}
|
|
} else if (this.charged) {
|
|
final Location location = this.player.getEyeLocation();
|
|
location.add(location.getDirection());
|
|
playFirebendingParticles(location, 1, .01, .01, .01);
|
|
}
|
|
}
|
|
|
|
private void sphereBurst() {
|
|
if (this.charged) {
|
|
final Location location = this.player.getEyeLocation();
|
|
final List<Block> safeblocks = GeneralMethods.getBlocksAroundPoint(this.player.getLocation(), 2);
|
|
double x, y, z;
|
|
final double r = 1;
|
|
|
|
for (double theta = 0; theta <= 180; theta += this.angleTheta) {
|
|
final double dphi = this.anglePhi / Math.sin(Math.toRadians(theta));
|
|
for (double phi = 0; phi < 360; phi += dphi) {
|
|
final double rphi = Math.toRadians(phi);
|
|
final double rtheta = Math.toRadians(theta);
|
|
|
|
x = r * Math.cos(rphi) * Math.sin(rtheta);
|
|
y = r * Math.sin(rphi) * Math.sin(rtheta);
|
|
z = r * Math.cos(rtheta);
|
|
|
|
final Vector direction = new Vector(x, z, y);
|
|
final FireBlast fblast = new FireBlast(location, direction.normalize(), this.player, this.damage, safeblocks);
|
|
|
|
fblast.setRange(this.range);
|
|
fblast.setShowParticles(false);
|
|
fblast.setFireBurst(true);
|
|
this.blasts.add(fblast);
|
|
}
|
|
}
|
|
this.bPlayer.addCooldown(this);
|
|
}
|
|
this.remove();
|
|
this.handleSmoothParticles();
|
|
}
|
|
|
|
@Override
|
|
public String getName() {
|
|
return "FireBurst";
|
|
}
|
|
|
|
@Override
|
|
public Location getLocation() {
|
|
return this.player != null ? this.player.getLocation() : null;
|
|
}
|
|
|
|
@Override
|
|
public long getCooldown() {
|
|
return this.cooldown;
|
|
}
|
|
|
|
@Override
|
|
public boolean isSneakAbility() {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean isHarmlessAbility() {
|
|
return false;
|
|
}
|
|
|
|
public boolean isCharged() {
|
|
return this.charged;
|
|
}
|
|
|
|
public void setCharged(final boolean charged) {
|
|
this.charged = charged;
|
|
}
|
|
|
|
public int getDamage() {
|
|
return this.damage;
|
|
}
|
|
|
|
public void setDamage(final int damage) {
|
|
this.damage = damage;
|
|
}
|
|
|
|
public long getChargeTime() {
|
|
return this.chargeTime;
|
|
}
|
|
|
|
public void setChargeTime(final long chargeTime) {
|
|
this.chargeTime = chargeTime;
|
|
}
|
|
|
|
public long getRange() {
|
|
return this.range;
|
|
}
|
|
|
|
public void setRange(final long range) {
|
|
this.range = range;
|
|
}
|
|
|
|
public double getAngleTheta() {
|
|
return this.angleTheta;
|
|
}
|
|
|
|
public void setAngleTheta(final double angleTheta) {
|
|
this.angleTheta = angleTheta;
|
|
}
|
|
|
|
public double getAnglePhi() {
|
|
return this.anglePhi;
|
|
}
|
|
|
|
public void setAnglePhi(final double anglePhi) {
|
|
this.anglePhi = anglePhi;
|
|
}
|
|
|
|
public double getParticlesPercentage() {
|
|
return this.particlesPercentage;
|
|
}
|
|
|
|
public void setParticlesPercentage(final double particlesPercentage) {
|
|
this.particlesPercentage = particlesPercentage;
|
|
}
|
|
|
|
public ArrayList<FireBlast> getBlasts() {
|
|
return this.blasts;
|
|
}
|
|
|
|
public void setCooldown(final long cooldown) {
|
|
this.cooldown = cooldown;
|
|
}
|
|
|
|
}
|