Fix Cannon TNT firing in the wrong direction and clean up the projectile code, making it more modular.
This commit is contained in:
parent
29b3f03abf
commit
0a32eed15d
@ -1480,4 +1480,28 @@ public class UtilBlock
|
||||
IBlockData ibd = net.minecraft.server.v1_8_R3.Block.getById(type).fromLegacyData(data);
|
||||
chunk.a(pos, ibd);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if all of the blocks within the specified radius of the specified origin block are boundless ({@link UtilItem#isBoundless}.)
|
||||
*/
|
||||
public static boolean boundless(Location origin, double radius)
|
||||
{
|
||||
for (Block block : getInRadius(origin, radius).keySet())
|
||||
{
|
||||
if (!UtilItem.isBoundless(block.getType()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if there are any non-boundless ({@link UtilItem#isBoundless}) blocks within the specified radius of the specified origin block.
|
||||
*/
|
||||
public static boolean boundless(Block origin, double radius)
|
||||
{
|
||||
return boundless(origin.getLocation(), radius);
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
package mineplex.game.clans.clans.siege.weapon;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@ -39,7 +37,6 @@ import mineplex.game.clans.clans.ClanInfo;
|
||||
import mineplex.game.clans.clans.siege.SiegeManager;
|
||||
import mineplex.game.clans.clans.siege.events.SiegeWeaponExplodeEvent;
|
||||
import mineplex.game.clans.clans.siege.repository.tokens.SiegeWeaponToken;
|
||||
import mineplex.game.clans.clans.siege.weapon.projectile.ProjectileAttributes;
|
||||
import mineplex.game.clans.clans.siege.weapon.projectile.WeaponProjectile;
|
||||
import mineplex.game.clans.clans.siege.weapon.util.AccessRule;
|
||||
import mineplex.game.clans.clans.siege.weapon.util.AccessType;
|
||||
@ -76,8 +73,6 @@ public class Cannon extends SiegeWeapon
|
||||
|
||||
_baseDamage = 650;
|
||||
|
||||
setProjectileAttributes(new ProjectileAttributes().setPrimedTnt().setDoCrater().craterSize(3).craterChanceOfAir(2.d));
|
||||
|
||||
setFireRule(new AccessRule(AccessType.LCLICK_BB, player -> {
|
||||
if (!isRiding(player))
|
||||
{
|
||||
@ -160,8 +155,6 @@ public class Cannon extends SiegeWeapon
|
||||
|
||||
_baseDamage = 650;
|
||||
|
||||
setProjectileAttributes(new ProjectileAttributes().setPrimedTnt().setDoCrater().craterSize(3).craterChanceOfAir(2.d));
|
||||
|
||||
setFireRule(new AccessRule(AccessType.LCLICK_BB, player -> {
|
||||
if (!isRiding(player))
|
||||
{
|
||||
@ -360,12 +353,14 @@ public class Cannon extends SiegeWeapon
|
||||
}
|
||||
|
||||
@Override
|
||||
public void CustomFire(WeaponProjectile projectile)
|
||||
protected WeaponProjectile CustomFire(double yawRot, double verticalVel, double horizontalVel)
|
||||
{
|
||||
projectile.setLocation(projectile.getLocation().add(.0, .2, .0));
|
||||
Location location = UtilAlg.moveForward(new Location(_location.getWorld(), _location.getX(), _location.getY() + .2, _location.getZ(), (float) yawRot, (float) 0), 0.35, (float) yawRot, false);
|
||||
|
||||
UtilParticle.PlayParticleToAll(ParticleType.LARGE_EXPLODE, projectile.getLocation(), new Vector(0, 0, 0), .1f, 2, ViewDist.MAX);
|
||||
UtilServer.getServer().getOnlinePlayers().forEach(player -> player.playSound(projectile.getLocation(), Sound.EXPLODE, 1.f, 1.f));
|
||||
UtilParticle.PlayParticleToAll(ParticleType.LARGE_EXPLODE, location, new Vector(0, 0, 0), .1f, 2, ViewDist.MAX);
|
||||
UtilServer.getServer().getOnlinePlayers().forEach(player -> player.playSound(location, Sound.EXPLODE, 1.f, 1.f));
|
||||
|
||||
return new TntProjectile(this, location, yawRot, verticalVel, horizontalVel);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -54,7 +54,6 @@ import mineplex.game.clans.clans.siege.events.LoadSiegeWeaponEvent;
|
||||
import mineplex.game.clans.clans.siege.events.MountSiegeWeaponEvent;
|
||||
import mineplex.game.clans.clans.siege.events.SiegeWeaponExplodeEvent;
|
||||
import mineplex.game.clans.clans.siege.repository.tokens.SiegeWeaponToken;
|
||||
import mineplex.game.clans.clans.siege.weapon.projectile.ProjectileAttributes;
|
||||
import mineplex.game.clans.clans.siege.weapon.projectile.WeaponProjectile;
|
||||
import mineplex.game.clans.clans.siege.weapon.util.AccessRule;
|
||||
import mineplex.game.clans.clans.siege.weapon.util.AccessType;
|
||||
@ -138,7 +137,6 @@ public abstract class SiegeWeapon implements Listener
|
||||
|
||||
protected int _baseDamage;
|
||||
|
||||
protected ProjectileAttributes _projectileAttributes;
|
||||
protected WeaponProjectile _projectile;
|
||||
|
||||
public SiegeWeapon(int maxHealth, String name, SiegeWeaponToken token, ClansManager clansManager, SiegeManager siegeManager)
|
||||
@ -328,7 +326,7 @@ public abstract class SiegeWeapon implements Listener
|
||||
|
||||
_inventory.clear();
|
||||
|
||||
CustomFire(_projectile = new WeaponProjectile(this, _location.clone().add(.5, 0, .5), _projectileAttributes, ((ArmorStand) getEntity("WEAPON")).getHeadPose().getY(), vel[0], vel[1]));
|
||||
_projectile = CustomFire(((ArmorStand) getEntity("WEAPON")).getHeadPose().getY(), vel[0], vel[1]);
|
||||
}
|
||||
|
||||
protected void setFireRule(AccessRule rule)
|
||||
@ -366,11 +364,6 @@ public abstract class SiegeWeapon implements Listener
|
||||
_maxAmmunition = maxAmmunition;
|
||||
}
|
||||
|
||||
protected void setProjectileAttributes(ProjectileAttributes projectileAttributes)
|
||||
{
|
||||
_projectileAttributes = projectileAttributes;
|
||||
}
|
||||
|
||||
protected boolean isRiding(Player player)
|
||||
{
|
||||
return player.equals(getRider());
|
||||
@ -523,13 +516,13 @@ public abstract class SiegeWeapon implements Listener
|
||||
protected abstract double[] GetProjectileVelocity();
|
||||
protected abstract String GetNextState();
|
||||
protected abstract void FindEntities();
|
||||
protected abstract WeaponProjectile CustomFire(double yawRot, double verticalVel, double horizontalVel);
|
||||
protected void CustomTick() { return; }
|
||||
protected void CustomOnMount(Player player) { return; }
|
||||
protected void CustomLeftClick(Player player) { return; }
|
||||
protected void CustomRightClick(Player player) { return; }
|
||||
protected void CustomCleanup() { return; }
|
||||
protected void CustomUpdateState(String state) { return; }
|
||||
protected void CustomFire(WeaponProjectile projectile) { return; }
|
||||
protected double CustomRotate(double yaw) { return yaw; }
|
||||
protected boolean CustomDismount(Player player, Entity entity) { return false; }
|
||||
protected boolean CustomMount(Player player) { return false; }
|
||||
|
@ -0,0 +1,63 @@
|
||||
package mineplex.game.clans.clans.siege.weapon;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import mineplex.core.common.util.UtilAlg;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import mineplex.game.clans.clans.siege.weapon.projectile.WeaponProjectile;
|
||||
|
||||
public class TntProjectile extends WeaponProjectile
|
||||
{
|
||||
public TntProjectile(SiegeWeapon weapon, Location origin, double yawRot, double yVel, double xMulti)
|
||||
{
|
||||
super(weapon, origin, yawRot, yVel, xMulti);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onTntExplode(EntityExplodeEvent event)
|
||||
{
|
||||
if (event.getEntity().equals(_projectileEntity))
|
||||
{
|
||||
((TNTPrimed) event.getEntity()).setFuseTicks(60);
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onTntExplode(UpdateEvent event)
|
||||
{
|
||||
if (event.getType() != UpdateType.SEC)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
((TNTPrimed) _projectileEntity).setFuseTicks(60);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity spawn()
|
||||
{
|
||||
TNTPrimed tnt = _origin.getWorld().spawn(_origin, TNTPrimed.class);
|
||||
|
||||
Vector velocity = UtilAlg.getTrajectory(
|
||||
_origin,
|
||||
UtilAlg.moveForward(
|
||||
_origin,
|
||||
2.,
|
||||
(float) Math.toDegrees(_yawRot), false))
|
||||
.multiply(_xMulti)
|
||||
.setY(_yVel);
|
||||
|
||||
tnt.setVelocity(velocity);
|
||||
|
||||
return tnt;
|
||||
}
|
||||
|
||||
}
|
@ -39,14 +39,9 @@ public class Crater implements Listener
|
||||
|
||||
private final long _birthTime;
|
||||
|
||||
private final int _size;
|
||||
private final double _airChance;
|
||||
|
||||
private final boolean _fire;
|
||||
|
||||
private final List<CraterBlock> _blocks;
|
||||
|
||||
public Crater(SiegeWeapon weapon, WeaponProjectile projectile, Location origin, int size, double airChance, boolean doFire)
|
||||
public Crater(SiegeWeapon weapon, WeaponProjectile projectile, Location origin)
|
||||
{
|
||||
_weapon = weapon;
|
||||
_origin = origin;
|
||||
@ -54,10 +49,6 @@ public class Crater implements Listener
|
||||
_birthTime = System.currentTimeMillis();
|
||||
_blocks = new ArrayList<>();
|
||||
|
||||
_size = size;
|
||||
_airChance = airChance;
|
||||
_fire = doFire;
|
||||
|
||||
UtilServer.getPluginManager().registerEvents(this, _weapon.getClans().getPlugin());
|
||||
|
||||
createExplosion();
|
||||
|
@ -1,75 +0,0 @@
|
||||
package mineplex.game.clans.clans.siege.weapon.projectile;
|
||||
|
||||
import org.bukkit.Material;
|
||||
|
||||
public class ProjectileAttributes
|
||||
{
|
||||
protected boolean _isFallingBlock;
|
||||
protected Material _fallingBlockType;
|
||||
protected byte _fallingBlockData;
|
||||
|
||||
protected boolean _isPrimedTnt;
|
||||
|
||||
protected boolean _doCrater;
|
||||
protected int _craterSize;
|
||||
protected double _craterChanceOfAir;
|
||||
|
||||
protected boolean _craterDoFire;
|
||||
|
||||
public ProjectileAttributes setFallingBlock()
|
||||
{
|
||||
_isFallingBlock = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProjectileAttributes setFallingBlockType(Material type)
|
||||
{
|
||||
_fallingBlockType = type;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProjectileAttributes setFallingBlockData(byte data)
|
||||
{
|
||||
_fallingBlockData = data;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProjectileAttributes setPrimedTnt()
|
||||
{
|
||||
_isPrimedTnt = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProjectileAttributes setDoCrater()
|
||||
{
|
||||
_doCrater = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProjectileAttributes craterSize(int size)
|
||||
{
|
||||
_craterSize = size;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProjectileAttributes craterDoFire(boolean doFire)
|
||||
{
|
||||
_craterDoFire = doFire;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProjectileAttributes craterChanceOfAir(double chance)
|
||||
{
|
||||
_craterChanceOfAir = chance;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@ -23,55 +23,33 @@ import mineplex.core.updater.event.UpdateEvent;
|
||||
import mineplex.game.clans.clans.siege.events.SiegeWeaponExplodeEvent;
|
||||
import mineplex.game.clans.clans.siege.weapon.SiegeWeapon;
|
||||
|
||||
public class WeaponProjectile implements Listener
|
||||
public abstract class WeaponProjectile implements Listener
|
||||
{
|
||||
private ProjectileAttributes _attributes;
|
||||
private Location _origin;
|
||||
private Entity _projectileEntity;
|
||||
protected Location _origin;
|
||||
protected Entity _projectileEntity;
|
||||
|
||||
private SiegeWeapon _weapon;
|
||||
protected SiegeWeapon _weapon;
|
||||
|
||||
private double _yRot;
|
||||
private double _xMulti;
|
||||
private double _yVel;
|
||||
protected double _yawRot;
|
||||
protected double _xMulti;
|
||||
protected double _yVel;
|
||||
|
||||
private boolean _dead;
|
||||
protected boolean _dead;
|
||||
|
||||
private Player _shooter;
|
||||
protected Player _shooter;
|
||||
|
||||
public WeaponProjectile(SiegeWeapon weapon, Location origin, ProjectileAttributes attributes, double yRot, double yVel, double xMulti)
|
||||
public WeaponProjectile(SiegeWeapon weapon, Location origin, double yawRot, double yVel, double xMulti)
|
||||
{
|
||||
_shooter = weapon.getRider();
|
||||
_weapon = weapon;
|
||||
_origin = origin;
|
||||
_attributes = attributes;
|
||||
_yRot = yRot;
|
||||
_yawRot = yawRot;
|
||||
_yVel = yVel;
|
||||
_xMulti = xMulti;
|
||||
|
||||
UtilServer.getPluginManager().registerEvents(this, weapon.getClans().getPlugin());
|
||||
|
||||
spawn();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onTntExplode(EntityExplodeEvent event)
|
||||
{
|
||||
if (event.getEntity().equals(_projectileEntity))
|
||||
{
|
||||
((TNTPrimed) event.getEntity()).setFuseTicks(60);
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockFall(EntityChangeBlockEvent event)
|
||||
{
|
||||
if (!_dead && event.getEntity().equals(_projectileEntity))
|
||||
{
|
||||
die();
|
||||
event.setCancelled(true);
|
||||
}
|
||||
_projectileEntity = spawn();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@ -82,39 +60,30 @@ public class WeaponProjectile implements Listener
|
||||
return;
|
||||
}
|
||||
|
||||
if (_projectileEntity.isDead())
|
||||
if (_projectileEntity == null || _projectileEntity.isDead())
|
||||
{
|
||||
die();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_dead || _projectileEntity == null)
|
||||
if (_projectileEntity.getTicksLived() <= 10)
|
||||
{
|
||||
die();
|
||||
return;
|
||||
}
|
||||
|
||||
((TNTPrimed) _projectileEntity).setFuseTicks(60);
|
||||
boolean moving = Math.abs(_projectileEntity.getVelocity().getX()) > 0.01 || Math.abs(_projectileEntity.getVelocity().getZ()) > 0.01;
|
||||
|
||||
if ((Math.abs(_projectileEntity.getVelocity().getX()) < 0.01
|
||||
|| Math.abs(_projectileEntity.getVelocity().getZ()) < 0.01)
|
||||
&& UtilBlock.getInRadius(_projectileEntity.getLocation(), 2)
|
||||
.keySet()
|
||||
.stream()
|
||||
.filter(block -> !UtilItem.isBoundless(block.getType()))
|
||||
.iterator().hasNext() && _projectileEntity.getTicksLived() >= 10)
|
||||
// Some rough collision detection. Not perfect, but the best I could conjure up myself.
|
||||
if (!moving && !UtilBlock.boundless(_projectileEntity.getLocation(), 2))
|
||||
{
|
||||
SiegeWeaponExplodeEvent newEvent = new SiegeWeaponExplodeEvent(_weapon, this);
|
||||
|
||||
UtilServer.CallEvent(newEvent);
|
||||
SiegeWeaponExplodeEvent newEvent = UtilServer.CallEvent(new SiegeWeaponExplodeEvent(_weapon, this));
|
||||
|
||||
if (!newEvent.isCancelled())
|
||||
{
|
||||
new Crater(_weapon, this, _projectileEntity.getLocation(), _attributes._craterSize, _attributes._craterChanceOfAir, _attributes._craterDoFire);
|
||||
new Crater(_weapon, this, _projectileEntity.getLocation());
|
||||
UtilServer.getServer().getOnlinePlayers().forEach(player -> player.playSound(_projectileEntity.getLocation(), Sound.EXPLODE, 1.f, 1.f));
|
||||
}
|
||||
|
||||
UtilServer.getServer().getOnlinePlayers().forEach(player -> player.playSound(_projectileEntity.getLocation(), Sound.EXPLODE, 1.f, 1.f));
|
||||
|
||||
die();
|
||||
}
|
||||
}
|
||||
@ -147,48 +116,7 @@ public class WeaponProjectile implements Listener
|
||||
_dead = true;
|
||||
}
|
||||
|
||||
private void spawn()
|
||||
{
|
||||
if (_attributes._isFallingBlock)
|
||||
{
|
||||
FallingBlock fallingBlock = _origin.getWorld().spawnFallingBlock(_origin, _attributes._fallingBlockType, _attributes._fallingBlockData);
|
||||
|
||||
_projectileEntity = fallingBlock;
|
||||
|
||||
Vector velocity = UtilAlg.getTrajectory(
|
||||
_origin,
|
||||
UtilAlg.moveForward(
|
||||
_origin,
|
||||
2.,
|
||||
(float) Math.toDegrees(_yRot), false))
|
||||
.multiply(_xMulti)
|
||||
.setY(_yVel);
|
||||
|
||||
fallingBlock.setVelocity(velocity);
|
||||
}
|
||||
else if (_attributes._isPrimedTnt)
|
||||
{
|
||||
TNTPrimed tnt = _origin.getWorld().spawn(_origin, TNTPrimed.class);
|
||||
|
||||
_projectileEntity = tnt;
|
||||
|
||||
Vector velocity = UtilAlg.getTrajectory(
|
||||
_origin,
|
||||
UtilAlg.moveForward(
|
||||
_origin,
|
||||
2.,
|
||||
(float) Math.toDegrees(_yRot), false))
|
||||
.multiply(_xMulti)
|
||||
.setY(_yVel);
|
||||
|
||||
tnt.setVelocity(velocity);
|
||||
}
|
||||
}
|
||||
|
||||
public int getCraterSize()
|
||||
{
|
||||
return _attributes._craterSize;
|
||||
}
|
||||
public abstract Entity spawn();
|
||||
|
||||
public Player getShooter()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user