Search in sources :

Example 1 with ProjectileExplodeEvent

use of me.deecaad.weaponmechanics.weapon.weaponevents.ProjectileExplodeEvent in project MechanicsMain by WeaponMechanics.

the class Explosion method explode.

public void explode(LivingEntity cause, Location origin, WeaponProjectile projectile) {
    // Handle worldguard flags
    WorldGuardCompatibility worldGuard = CompatibilityAPI.getWorldGuardCompatibility();
    EntityWrapper entityWrapper = WeaponMechanics.getEntityWrapper(cause);
    if (!worldGuard.testFlag(origin, entityWrapper instanceof PlayerWrapper ? ((PlayerWrapper) entityWrapper).getPlayer() : null, "weapon-explode")) {
        Object obj = worldGuard.getValue(origin, "weapon-explode-message");
        if (obj != null && !obj.toString().isEmpty()) {
            entityWrapper.getEntity().sendMessage(StringUtil.color(obj.toString()));
        }
        return;
    }
    // triggered instead of the explosion.
    if (projectile != null && airStrike != null && projectile.getIntTag("airstrike-bomb") == 0) {
        airStrike.trigger(origin, cause, projectile);
        return;
    }
    List<Block> blocks;
    BlockRegenSorter sorter;
    DoubleMap<LivingEntity> entities;
    if (projectile != null) {
        // This event is not cancellable. If developers want to cancel
        // explosions, they should use ProjectilePreExplodeEvent
        ProjectileExplodeEvent event = new ProjectileExplodeEvent(projectile, shape.getBlocks(origin), new LayerDistanceSorter(origin, this), exposure.mapExposures(origin, shape));
        Bukkit.getPluginManager().callEvent(event);
        blocks = event.getBlocks();
        sorter = event.getSorter();
        entities = event.getEntities();
    } else {
        blocks = shape.getBlocks(origin);
        sorter = new LayerDistanceSorter(origin, this);
        entities = exposure.mapExposures(origin, shape);
    }
    int initialCapacity = Math.max(blocks.size(), 10);
    List<Block> transparent = new ArrayList<>(initialCapacity);
    List<Block> solid = new ArrayList<>(initialCapacity);
    // redstone contraptions.
    for (Block block : blocks) {
        if (block.getType().isSolid()) {
            solid.add(block);
        } else if (!block.isEmpty()) {
            transparent.add(block);
        }
    }
    // regenerate in a random order.
    try {
        if (sorter == null) {
            debug.debug("Null sorter used while regenerating explosion... Was this intentional?");
        } else {
            solid.sort(sorter);
        }
    } catch (IllegalArgumentException e) {
        debug.log(LogLevel.ERROR, "A plugin modified the explosion block sorter with an illegal sorter! " + "Please report this error to the developers of that plugin. Sorter: " + sorter.getClass(), e);
    }
    // spawn falling blocks. We also don't need to worry about regeneration.
    if (blockDamage != null) {
        int timeOffset = regeneration == null ? -1 : (solid.size() * regeneration.getInterval() / regeneration.getMaxBlocksPerUpdate());
        damageBlocks(transparent, true, origin, timeOffset);
        damageBlocks(solid, false, origin, 0);
    }
    if (projectile != null && projectile.getWeaponTitle() != null) {
        WeaponMechanics.getWeaponHandler().getDamageHandler().tryUseExplosion(projectile, origin, entities);
        // higher your exposure, the greater the knockback.
        if (isKnockback) {
            Vector originVector = origin.toVector();
            for (DoubleEntry<LivingEntity> entry : entities.entrySet()) {
                LivingEntity entity = entry.getKey();
                double exposure = entry.getValue();
                // Normalized vector between the explosion and entity involved
                Vector between = VectorUtil.setLength(entity.getLocation().toVector().subtract(originVector), exposure);
                Vector motion = entity.getVelocity().add(between);
                entity.setVelocity(motion);
            }
        }
        if (cluster != null)
            cluster.trigger(projectile, cause, origin);
    } else {
        // size explosion they may want
        for (DoubleEntry<LivingEntity> entry : entities.entrySet()) {
            LivingEntity entity = entry.getKey();
            double impact = entry.getValue();
            entity.sendMessage(StringUtil.color("&cYou suffered " + impact * 100 + "% of the impact"));
        }
    }
    if (flashbang != null)
        flashbang.trigger(exposure, projectile, origin);
    if (mechanics != null)
        mechanics.use(new CastData(entityWrapper, origin, projectile == null ? null : projectile.getWeaponTitle(), projectile == null ? null : projectile.getWeaponStack()));
}
Also used : CastData(me.deecaad.weaponmechanics.mechanics.CastData) BlockRegenSorter(me.deecaad.weaponmechanics.weapon.explode.regeneration.BlockRegenSorter) LayerDistanceSorter(me.deecaad.weaponmechanics.weapon.explode.regeneration.LayerDistanceSorter) ArrayList(java.util.ArrayList) PlayerWrapper(me.deecaad.weaponmechanics.wrappers.PlayerWrapper) LivingEntity(org.bukkit.entity.LivingEntity) WorldGuardCompatibility(me.deecaad.core.compatibility.worldguard.WorldGuardCompatibility) EntityWrapper(me.deecaad.weaponmechanics.wrappers.EntityWrapper) Block(org.bukkit.block.Block) Vector(org.bukkit.util.Vector) ProjectileExplodeEvent(me.deecaad.weaponmechanics.weapon.weaponevents.ProjectileExplodeEvent)

Aggregations

ArrayList (java.util.ArrayList)1 WorldGuardCompatibility (me.deecaad.core.compatibility.worldguard.WorldGuardCompatibility)1 CastData (me.deecaad.weaponmechanics.mechanics.CastData)1 BlockRegenSorter (me.deecaad.weaponmechanics.weapon.explode.regeneration.BlockRegenSorter)1 LayerDistanceSorter (me.deecaad.weaponmechanics.weapon.explode.regeneration.LayerDistanceSorter)1 ProjectileExplodeEvent (me.deecaad.weaponmechanics.weapon.weaponevents.ProjectileExplodeEvent)1 EntityWrapper (me.deecaad.weaponmechanics.wrappers.EntityWrapper)1 PlayerWrapper (me.deecaad.weaponmechanics.wrappers.PlayerWrapper)1 Block (org.bukkit.block.Block)1 LivingEntity (org.bukkit.entity.LivingEntity)1 Vector (org.bukkit.util.Vector)1