TF-ProjectKorra/src/com/projectkorra/projectkorra/firebending/WallOfFire.java

360 lines
8.7 KiB
Java
Raw Normal View History

package com.projectkorra.projectkorra.firebending;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.FireAbility;
import com.projectkorra.projectkorra.firebending.util.FireDamageTimer;
import com.projectkorra.projectkorra.util.DamageHandler;
import com.projectkorra.projectkorra.util.ParticleEffect;
import com.projectkorra.projectkorra.util.TempBlock;
2016-01-13 21:14:34 +00:00
public class WallOfFire extends FireAbility {
private boolean active;
private int damageTick;
private int intervalTick;
private int range;
private int height;
private int width;
private int damage;
private long cooldown;
private long damageInterval;
private long duration;
private long time;
private long interval;
private double fireTicks;
private double maxAngle;
private Random random;
private Location origin;
2016-01-13 21:14:34 +00:00
private List<Block> blocks;
2017-01-16 06:48:20 +00:00
public WallOfFire(Player player) {
2016-01-13 21:14:34 +00:00
super(player);
2017-01-16 06:48:20 +00:00
2016-01-13 21:14:34 +00:00
this.active = true;
2016-01-16 21:07:14 +00:00
this.maxAngle = getConfig().getDouble("Abilities.Fire.WallOfFire.MaxAngle");
this.interval = getConfig().getLong("Abilities.Fire.WallOfFire.Interval");
2016-01-13 21:14:34 +00:00
this.range = getConfig().getInt("Abilities.Fire.WallOfFire.Range");
this.height = getConfig().getInt("Abilities.Fire.WallOfFire.Height");
this.width = getConfig().getInt("Abilities.Fire.WallOfFire.Width");
this.damage = getConfig().getInt("Abilities.Fire.WallOfFire.Damage");
this.cooldown = getConfig().getLong("Abilities.Fire.WallOfFire.Cooldown");
2016-01-16 21:07:14 +00:00
this.damageInterval = getConfig().getLong("Abilities.Fire.WallOfFire.DamageInterval");
2016-01-13 21:14:34 +00:00
this.duration = getConfig().getLong("Abilities.Fire.WallOfFire.Duration");
this.fireTicks = getConfig().getDouble("Abilities.Fire.WallOfFire.FireTicks");
this.random = new Random();
this.blocks = new ArrayList<>();
if (hasAbility(player, WallOfFire.class) && !bPlayer.isAvatarState()) {
return;
2016-01-13 21:14:34 +00:00
} else if (bPlayer.isOnCooldown(this)) {
return;
2016-01-13 21:14:34 +00:00
}
2017-01-16 06:48:20 +00:00
origin = GeneralMethods.getTargetedLocation(player, range);
2016-01-13 21:14:34 +00:00
if (isDay(player.getWorld())) {
width = (int) getDayFactor(width);
height = (int) getDayFactor(height);
duration = (long) getDayFactor(duration);
damage = (int) getDayFactor(damage);
}
1.8.5 (#813) ## Fixes * Fixed odd interactions between `Bloodbending` and `AvatarState`. * You can no longer be bloodbent while in `AvatarState` and going into the `AvatarState` while being bloodbent will break you free. * Fixed various errors in `Bloodbending`. * Fixed `SubElements` being saved incorrectly in the database. * Fixed a few cases where `Surge` would cause flooding. * Fixed various NoCheatPlus exemptions in our `DamageHandler`. (Thanks, RoboMWM) * Fixed ProjectKorra fire tick damage overriding other plugins fire tick damage. * Fixed `FireSpin` working underwater. * Fixed `EarthArmor` not properly obeying its cooldown. * Fixed `Combo Abilities` being displayed in `/pk display <Element>`. * Fixed `Extraction` cooldown being applied when the ability couldn't start. * Fixed `EarthTunnel` cooldown being applied when the ability couldn't start. * Fixed `IceSpike` field functionality not activating on `PhaseChange` blocks. * Fixed `FireWheel` hit location if used while looking down. * Fixed `Lightning` paralyze functionality. * Fixed `DensityShift` causing fall damage if used on other `DensityShift` blocks. * Fixed `Flight` cooldown being applied when the ability couldn't start. * Fixed `Flight` deactivating if used while on the ground. * Fixed `RapidPunch` cooldown being applied when the ability couldn't start. * Fixed `WaterArms` not returning water sources to bottles. * Fixed `WaterArms` not grabbing sources correctly. * Fixed `CollisionManager` attempting to detect collisions between abilities in different worlds. (Thanks, plushmonkey) * Fixed `CollisionManager` not resetting when a new manager is created. * Fixed `JetBlaze` and `JetBlast` not overriding `FireJet` duration. * Fixed `PhaseChange` not being able to melt snow blocks. * Fixed `FastSwim` being able to be used on a `Catapult` slot. * Fixed `FireManipulation` cooldown. * Fixed `Collapse` and `RaiseEarth`not working in `AvatarState`. * Fixed Waterbending causing concrete powder to harden. * Fixed `MetalClips` magnetize not pulling iron ingots if players had them in their hand. * Fixed `MetalClips` not disabling passives such as `FastSwim` on its targets. * Fixed `MetalClips` armor absorbing damage. * Fixed `MetalClips` magnetize not pulling if the launching portion of the move is on cooldown. * Fixed `MetalClips` not dropping iron ingots once a held target is killed. * Fixed `MetalClips` duplicating iron ingots by repeatedly hitting and pulling entities. * Fixed `MetalClips` duplicating iron ingots by hitting blocks. * Fixed addon Passive abilities not registering. * Fixed `/pk help <Element>` displaying incorrect/old links. * Fixed `/pk help <Element/Combo>` being case sensitive. * Fixed `/pk help` not allowing players to auto tab all non-hidden abilities. * Fixed `IllegalArgumentException` being thrown if server owners put an incorrect `ChatColor` for the `Chat.Branding.Color` value in `language.yml`. * Fixed `EarthArmor` allowing players to use `FastSwim` while the armor is activated. * Fixed incorrect cancellation of `BlockBreakEvent` when players bending is toggled off. * Fixed multiple instances of the same `CoreAbility` being present in auto tabbing due to certain move functionalities being split up between files. * Fixed Passive abilities and Combo abilities showing up in `/pk bind <Ability>` auto tabbing. * Fixed `WaterWave` and `WaterSpout` cohesive movement. * Fixed `DamageHandler` applying `DamageModifier.ARMOR` where it is not applicable. * Fixed `/pk check` command URL. * Fixed Passive abilities breaking when choosing an element while bending is toggled. * Fixed `WaterBubble` removing blocks placed by players while the ability is active. * Fixed potential infinite loop in `EarthGrab`. * Fixed `AirScooter` not disabling when a player would sneak. ## Additions * Added cooldown capability to `AirShield`, `AirSpout`, `Tornado`, `FastSwim`, `WaterBubble`, `EarthTunnel`, `AcrobaticStance`, and `WarriorStance`. * Added the clickable ProjectKorra branding message to the `/pk help` and `/pk who` commands. * Added `radius` config option to `EarthGrab`. * Added AvatarState configuration options for `IceSpike`, `IceBlast`, `Torrent`, `OctopusForm`, `WallOfFire`, `WaterSpout`, and all stock Combos. * Added aesthetic donation perk servers can give to their players in the `/pk who <Player>` command via the `bending.donor` permission. * Added config option for the lightning bending sound and lava bending sound. * Added `Pitch` and `Volume` config options for all configurable sounds. * Added identifiers on Addon Abilities in `/pk help <Ability>` and `/pk display`. ## General Changes * Reduced default config values of `AvatarState` ability modifiers. * Changed the way abilities display in `/pk help <Ability>` * Abilities now display whether they are Addons or not. * Abilities now display whether they are Combos or Passives. * Addon Abilities display their author and version. * Improved `AirScooter` behavior. It isn't perfect yet, but it is better. * Changed `EarthArmor` so it now breaks when a player teleports. * Changed cobblestone and obsidian created by `AirBlast` to `TempBlocks`. * Changed `/pk add Avatar` to add all four main elements. ## API Changes * Added `RevertTask` which runs whenever `TempBlock#revertBlock()` is called. * Moved `BendingPlayer` creation to a separate thread. * Changed initial `BendingPlayer` database storage to insert default values. * Improved `CollisionManager` performance by removing unnecessary detections. * Put logic in place to remove ability instances causing exceptions without breaking all other running abilities. (Thanks, PhanaticD) * Changed `PassiveManager` storage so Passive abilities are be stored by name/class instead of by `Element`. * Removed `PassiveManager#getPassivesByElement()`. * Added `CoreAbility#unloadAbility(Class clazz)` to unload an ability from a server. * Added `CoreAbility#getAddonPlugins()` to get the names and paths of all currently loaded addon plugins. Returned format: `<plugin name>::<abilities path>` * Changed `/pk reload` to add support for addon plugin reloading. ## Removals * Removed the Minecraft version from the `/pk version` command. * Removed `SandSpout`. * Removed `SandRun` remnant from `EarthPassive`. * Removed `AirBlast` collisions with other basic moves.
2017-08-04 04:54:22 +00:00
if (bPlayer.isAvatarState()) {
this.width = getConfig().getInt("Abilities.Avatar.AvatarState.Fire.WallOfFire.Width");
this.height = getConfig().getInt("Abilities.Avatar.AvatarState.Fire.WallOfFire.Height");
this.duration = getConfig().getLong("Abilities.Avatar.AvatarState.Fire.WallOfFire.Duration");
this.damage = getConfig().getInt("Abilities.Avatar.AvatarState.Fire.WallOfFire.Damage");
this.fireTicks = getConfig().getDouble("Abilities.Avatar.AvatarState.Fire.WallOfFire.FireTicks");
}
time = System.currentTimeMillis();
Block block = origin.getBlock();
if (block.isLiquid() || GeneralMethods.isSolid(block)) {
return;
}
Vector direction = player.getEyeLocation().getDirection();
Vector compare = direction.clone();
compare.setY(0);
2016-01-13 21:14:34 +00:00
if (Math.abs(direction.angle(compare)) > Math.toRadians(maxAngle)) {
return;
}
initializeBlocks();
2016-01-13 21:14:34 +00:00
start();
bPlayer.addCooldown(this);
}
private void affect(Entity entity) {
GeneralMethods.setVelocity(entity, new Vector(0, 0, 0));
if (entity instanceof LivingEntity) {
Block block = ((LivingEntity) entity).getEyeLocation().getBlock();
if (TempBlock.isTempBlock(block) && isIce(block)) {
return;
}
DamageHandler.damageEntity(entity, damage, this);
2016-01-13 21:14:34 +00:00
AirAbility.breakBreathbendingHold(entity);
}
entity.setFireTicks((int) (fireTicks * 20));
new FireDamageTimer(entity, player);
}
private void damage() {
double radius = height;
2016-01-13 21:14:34 +00:00
if (radius < width) {
radius = width;
2016-01-13 21:14:34 +00:00
}
2017-01-16 06:48:20 +00:00
radius = radius + 1;
List<Entity> entities = GeneralMethods.getEntitiesAroundPoint(origin, radius);
2016-01-13 21:14:34 +00:00
if (entities.contains(player)) {
entities.remove(player);
2016-01-13 21:14:34 +00:00
}
for (Entity entity : entities) {
2016-01-13 21:14:34 +00:00
if (GeneralMethods.isRegionProtectedFromBuild(this, entity.getLocation())) {
continue;
2016-01-13 21:14:34 +00:00
}
for (Block block : blocks) {
2016-01-13 21:14:34 +00:00
if (entity.getLocation().distanceSquared(block.getLocation()) <= 1.5 * 1.5) {
affect(entity);
break;
}
}
}
}
private void display() {
for (Block block : blocks) {
if (!isTransparent(block)) {
continue;
}
ParticleEffect.FLAME.display(block.getLocation(), 0.6F, 0.6F, 0.6F, 0, 3);
ParticleEffect.SMOKE.display(block.getLocation(), 0.6F, 0.6F, 0.6F, 0, 1);
2016-01-13 21:14:34 +00:00
if (random.nextInt(7) == 0) {
playFirebendingSound(block.getLocation());
}
}
}
private void initializeBlocks() {
Vector direction = player.getEyeLocation().getDirection();
direction = direction.normalize();
Vector ortholr = GeneralMethods.getOrthogonalVector(direction, 0, 1);
ortholr = ortholr.normalize();
Vector orthoud = GeneralMethods.getOrthogonalVector(direction, 90, 1);
orthoud = orthoud.normalize();
2016-01-13 21:14:34 +00:00
double w = width;
double h = height;
for (double i = -w; i <= w; i++) {
for (double j = -h; j <= h; j++) {
Location location = origin.clone().add(orthoud.clone().multiply(j));
location = location.add(ortholr.clone().multiply(i));
2016-01-13 21:14:34 +00:00
if (GeneralMethods.isRegionProtectedFromBuild(this, location)) {
continue;
2016-01-13 21:14:34 +00:00
}
Block block = location.getBlock();
2016-01-13 21:14:34 +00:00
if (!blocks.contains(block)) {
blocks.add(block);
2016-01-13 21:14:34 +00:00
}
}
}
}
2016-01-13 21:14:34 +00:00
@Override
public void progress() {
time = System.currentTimeMillis();
if (time - getStartTime() > cooldown) {
remove();
2016-01-13 21:14:34 +00:00
return;
} else if (!active) {
return;
} else if (time - getStartTime() > duration) {
active = false;
2016-01-13 21:14:34 +00:00
return;
}
if (time - getStartTime() > intervalTick * interval) {
2016-01-13 21:14:34 +00:00
intervalTick++;
display();
}
if (time - getStartTime() > damageTick * damageInterval) {
2016-01-13 21:14:34 +00:00
damageTick++;
damage();
}
}
2015-11-11 23:22:27 +00:00
2016-01-13 21:14:34 +00:00
@Override
public String getName() {
return "WallOfFire";
2015-11-11 20:19:45 +00:00
}
2015-11-11 23:22:27 +00:00
2016-01-13 21:14:34 +00:00
@Override
public Location getLocation() {
return origin;
2015-11-11 09:26:39 +00:00
}
2015-11-11 23:22:27 +00:00
2016-01-13 21:14:34 +00:00
@Override
public long getCooldown() {
return cooldown;
}
2017-01-16 06:48:20 +00:00
2016-01-13 21:14:34 +00:00
@Override
public boolean isSneakAbility() {
return false;
2015-11-11 20:19:45 +00:00
}
@Override
2016-01-13 21:14:34 +00:00
public boolean isHarmlessAbility() {
return false;
}
2017-01-16 06:48:20 +00:00
@Override
public List<Location> getLocations() {
ArrayList<Location> locations = new ArrayList<>();
for (Block block : blocks) {
locations.add(block.getLocation());
}
return locations;
}
2016-01-13 21:14:34 +00:00
public boolean isActive() {
return active;
}
2016-01-13 21:14:34 +00:00
public void setActive(boolean active) {
this.active = active;
}
2016-01-13 21:14:34 +00:00
public int getDamageTick() {
return damageTick;
}
2016-01-13 21:14:34 +00:00
public void setDamageTick(int damageTick) {
this.damageTick = damageTick;
}
2016-01-13 21:14:34 +00:00
public int getIntervalTick() {
return intervalTick;
}
public void setIntervalTick(int intervalTick) {
this.intervalTick = intervalTick;
}
public int getRange() {
return range;
}
public void setRange(int range) {
this.range = range;
}
2016-01-13 21:14:34 +00:00
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
2016-01-13 21:14:34 +00:00
public int getDamage() {
return damage;
}
public void setDamage(int damage) {
this.damage = damage;
}
public long getDamageInterval() {
return damageInterval;
}
public void setDamageInterval(long damageInterval) {
this.damageInterval = damageInterval;
}
public long getDuration() {
return duration;
}
public void setDuration(long duration) {
this.duration = duration;
}
public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
public long getInterval() {
return interval;
}
public void setInterval(long interval) {
this.interval = interval;
}
public double getFireTicks() {
return fireTicks;
}
public void setFireTicks(double fireTicks) {
this.fireTicks = fireTicks;
}
public double getMaxAngle() {
return maxAngle;
}
public void setMaxAngle(double maxAngle) {
this.maxAngle = maxAngle;
}
public Location getOrigin() {
return origin;
}
public void setOrigin(Location origin) {
this.origin = origin;
}
public List<Block> getBlocks() {
return blocks;
}
public void setCooldown(long cooldown) {
this.cooldown = cooldown;
}
}