Search in sources :

Example 11 with MaterialBrush

use of com.elmakers.mine.bukkit.api.block.MaterialBrush in project MagicPlugin by elBukkit.

the class IterateSpell method onCast.

@Override
public SpellResult onCast(ConfigurationSection parameters) {
    boolean incrementData = parameters.getBoolean("increment_data", false);
    int radius = parameters.getInt("radius", 0);
    // radius = (int)(radius * mage.getRadiusMultiplier());
    int size = parameters.getInt("size", DEFAULT_SIZE);
    boolean reverse = parameters.getBoolean("reverse", false);
    boolean requireBlock = parameters.getBoolean("require_block", false);
    size = (int) (mage.getConstructionMultiplier() * size);
    boolean reverseTargeting = parameters.getBoolean("transparent_reverse", false);
    if (reverseTargeting) {
        setReverseTargeting(true);
    }
    Block target = getTargetBlock();
    if (target == null) {
        return SpellResult.NO_TARGET;
    }
    if (!hasBuildPermission(target) || !hasBuildPermission(getLocation().getBlock())) {
        return SpellResult.INSUFFICIENT_PERMISSION;
    }
    int iterateBlocks = (int) getLocation().distance(target.getLocation());
    if (iterateBlocks <= 0)
        return SpellResult.NO_TARGET;
    iterateBlocks = Math.min(iterateBlocks, size);
    Vector targetLoc = new Vector(target.getX(), target.getY(), target.getZ());
    Vector playerLoc = getEyeLocation().toVector();
    Vector aim = null;
    if (reverse) {
        aim = playerLoc;
        aim.subtract(targetLoc);
        aim.normalize();
    } else {
        aim = targetLoc;
        aim.subtract(playerLoc);
        aim.normalize();
        targetLoc = playerLoc;
        // Move out a bit for safety!
        targetLoc.add(aim);
        targetLoc.add(aim);
    }
    MaterialBrush buildWith = getBrush();
    buildWith.setTarget(target.getLocation());
    buildWith.update(mage, target.getLocation());
    for (int dr = 0; dr <= radius; dr++) {
        int spokes = 1;
        // TODO: Handle radius > 1 algorithmically....
        if (dr > 0) {
            // 8, 16, 24, 32
            spokes = dr * 8;
        }
        for (int dspoke = 0; dspoke < spokes; dspoke++) {
            Vector currentLoc = targetLoc.clone();
            if (dr > 0) {
                // Arbitrary axis rotation would be better, but... math is hard! :P
                // TODO: Arbitrary axis rotation.
                double q = dspoke * Math.PI * 2 / spokes;
                if (aim.getY() > 0.7) {
                    Vector axis = new Vector(1, 0, 0);
                    Vector perp = aim.clone().crossProduct(axis).multiply(dr);
                    double x = perp.getZ() * Math.sin(q) - perp.getX() * Math.cos(q);
                    double z = perp.getZ() * Math.cos(q) - perp.getX() * Math.sin(q);
                    perp.setX(x);
                    perp.setZ(z);
                    currentLoc.add(perp);
                } else if (aim.getX() > 0.7) {
                    Vector axis = new Vector(0, 1, 0);
                    Vector perp = aim.clone().crossProduct(axis).multiply(dr);
                    double y = perp.getZ() * Math.sin(q) - perp.getY() * Math.cos(q);
                    double z = perp.getZ() * Math.cos(q) - perp.getY() * Math.sin(q);
                    perp.setY(y);
                    perp.setZ(z);
                    currentLoc.add(perp);
                } else {
                    Vector axis = new Vector(0, 1, 0);
                    Vector perp = aim.clone().crossProduct(axis).multiply(dr);
                    double y = perp.getX() * Math.sin(q) - perp.getY() * Math.cos(q);
                    double x = perp.getX() * Math.cos(q) - perp.getY() * Math.sin(q);
                    perp.setY(y);
                    perp.setX(x);
                    currentLoc.add(perp);
                }
            }
            for (int i = 0; i < iterateBlocks; i++) {
                Block currentTarget = target.getWorld().getBlockAt(currentLoc.getBlockX(), currentLoc.getBlockY(), currentLoc.getBlockZ());
                if (!isTargetable(currentTarget) && isDestructible(currentTarget) && hasBuildPermission(currentTarget)) {
                    registerForUndo(currentTarget);
                    buildWith.update(mage, currentTarget.getLocation());
                    if (incrementData) {
                        short data = buildWith.getData();
                        data = i > 15 ? 15 : (short) i;
                        buildWith.setData(data);
                    }
                    if (requireBlock) {
                        Block lowerBlock = currentTarget.getRelative(BlockFace.DOWN);
                        if (lowerBlock.getType() == Material.AIR || lowerBlock.getType() == buildWith.getMaterial()) {
                            currentLoc.add(aim);
                            continue;
                        }
                    }
                    buildWith.modify(currentTarget);
                    controller.updateBlock(currentTarget);
                    Location effectLocation = currentTarget.getLocation();
                    effectLocation.add(0.5f, 0.5f, 0.5f);
                    if (dr == 0) {
                        Material material = buildWith.getMaterial();
                        // TODO: Customize with effects system
                        if (material == Material.AIR) {
                            effectLocation.getWorld().playEffect(effectLocation, Effect.STEP_SOUND, Material.OBSIDIAN.getId());
                        } else {
                            effectLocation.getWorld().playEffect(effectLocation, Effect.STEP_SOUND, material.getId());
                        }
                    }
                }
                currentLoc.add(aim);
            }
        }
    }
    registerForUndo();
    return SpellResult.CAST;
}
Also used : MaterialBrush(com.elmakers.mine.bukkit.api.block.MaterialBrush) Block(org.bukkit.block.Block) Material(org.bukkit.Material) Vector(org.bukkit.util.Vector) Location(org.bukkit.Location)

Example 12 with MaterialBrush

use of com.elmakers.mine.bukkit.api.block.MaterialBrush in project MagicPlugin by elBukkit.

the class TransmuteSpell method onCast.

@Override
public SpellResult onCast(ConfigurationSection parameters) {
    BlockList transmuteAction = null;
    /*
         * Use target if targeting
         */
    Block target = getTargetBlock();
    if (target != null) {
        UndoQueue undoQueue = mage.getUndoQueue();
        transmuteAction = undoQueue.getLast(target);
    }
    if (transmuteAction == null) {
        UndoQueue undoQueue = mage.getUndoQueue();
        transmuteAction = undoQueue.getLast();
    }
    if (transmuteAction == null) {
        return SpellResult.NO_TARGET;
    }
    MaterialBrush buildWith = getBrush();
    for (BlockData undoBlock : transmuteAction) {
        Block block = undoBlock.getBlock();
        buildWith.modify(block);
    }
    return SpellResult.CAST;
}
Also used : UndoQueue(com.elmakers.mine.bukkit.api.block.UndoQueue) MaterialBrush(com.elmakers.mine.bukkit.api.block.MaterialBrush) BlockList(com.elmakers.mine.bukkit.api.block.BlockList) Block(org.bukkit.block.Block) BlockData(com.elmakers.mine.bukkit.api.block.BlockData)

Example 13 with MaterialBrush

use of com.elmakers.mine.bukkit.api.block.MaterialBrush in project MagicPlugin by elBukkit.

the class PlaneAction method reset.

@Override
public void reset(CastContext context) {
    super.reset(context);
    MaterialBrush brush = context.getBrush();
    Location targetLocation = context.getTargetLocation();
    Location orientLocation = targetLocation.clone();
    switch(brushAxis) {
        case X:
            orientLocation.setY(orientLocation.getY() + 1);
            orientLocation.setZ(orientLocation.getZ() + 1);
            break;
        case Z:
            orientLocation.setX(orientLocation.getX() + 1);
            orientLocation.setY(orientLocation.getY() + 1);
            break;
        default:
            orientLocation.setX(orientLocation.getX() + 1);
            orientLocation.setZ(orientLocation.getZ() + 1);
            break;
    }
    brush.setTarget(orientLocation, targetLocation);
}
Also used : MaterialBrush(com.elmakers.mine.bukkit.api.block.MaterialBrush) Location(org.bukkit.Location)

Example 14 with MaterialBrush

use of com.elmakers.mine.bukkit.api.block.MaterialBrush in project MagicPlugin by elBukkit.

the class ModifyBlockAction method perform.

@SuppressWarnings("deprecation")
@Override
public SpellResult perform(CastContext context) {
    MaterialBrush brush = context.getBrush();
    if (brush == null) {
        return SpellResult.FAIL;
    }
    Block block = context.getTargetBlock();
    if (brush.isErase()) {
        if (!context.hasBreakPermission(block)) {
            return SpellResult.INSUFFICIENT_PERMISSION;
        }
    } else {
        if (!context.hasBuildPermission(block)) {
            return SpellResult.INSUFFICIENT_PERMISSION;
        }
    }
    if (commit) {
        if (!context.areAnyDestructible(block)) {
            return SpellResult.NO_TARGET;
        }
    } else if (!context.isDestructible(block)) {
        return SpellResult.NO_TARGET;
    }
    Material previousMaterial = block.getType();
    byte previousData = block.getData();
    Mage mage = context.getMage();
    brush.update(mage, context.getTargetSourceLocation());
    if (!brush.isDifferent(block)) {
        return SpellResult.NO_TARGET;
    }
    if (!brush.isReady()) {
        brush.prepare();
        return SpellResult.PENDING;
    }
    if (!brush.isValid()) {
        return SpellResult.FAIL;
    }
    if (consumeBlocks && !context.isConsumeFree() && !brush.isErase()) {
        UndoList undoList = context.getUndoList();
        if (undoList != null) {
            undoList.setConsumed(true);
        }
        ItemStack requires = brush.getItemStack(1);
        if (!mage.hasItem(requires, consumeVariants)) {
            String requiresMessage = context.getMessage("insufficient_resources");
            context.sendMessage(requiresMessage.replace("$cost", brush.getName()));
            return SpellResult.STOP;
        }
        mage.removeItem(requires, consumeVariants);
    }
    if (!commit) {
        context.registerForUndo(block);
        if (brush.isErase()) {
            context.clearAttachables(block);
        }
    }
    UndoList undoList = context.getUndoList();
    if (undoList != null) {
        undoList.setApplyPhysics(applyPhysics);
    }
    brush.modify(block, applyPhysics);
    boolean spawnFalling = spawnFallingBlocks && previousMaterial != Material.AIR;
    if (spawnFalling && fallingProbability < 1) {
        spawnFalling = context.getRandom().nextDouble() < fallingProbability;
    }
    if (spawnFalling) {
        Location blockLocation = block.getLocation();
        Location blockCenter = new Location(blockLocation.getWorld(), blockLocation.getX() + 0.5, blockLocation.getY() + 0.5, blockLocation.getZ() + 0.5);
        Vector fallingBlockVelocity = null;
        if (fallingBlockSpeed > 0) {
            Location source = context.getTargetCenterLocation();
            fallingBlockVelocity = blockCenter.clone().subtract(source).toVector();
            fallingBlockVelocity.normalize();
            if (fallingBlockDirection != null) {
                fallingBlockVelocity.add(fallingBlockDirection).normalize();
            }
            fallingBlockVelocity.multiply(fallingBlockSpeed);
        }
        if (fallingBlockVelocity != null && (Double.isNaN(fallingBlockVelocity.getX()) || Double.isNaN(fallingBlockVelocity.getY()) || Double.isNaN(fallingBlockVelocity.getZ()) || Double.isInfinite(fallingBlockVelocity.getX()) || Double.isInfinite(fallingBlockVelocity.getY()) || Double.isInfinite(fallingBlockVelocity.getZ()))) {
            fallingBlockVelocity = null;
        }
        boolean spawned = false;
        if (usePhysicsBlocks) {
            spawned = context.getController().spawnPhysicsBlock(blockCenter, previousMaterial, previousData, fallingBlockVelocity);
        }
        if (!spawned) {
            FallingBlock falling = block.getWorld().spawnFallingBlock(blockCenter, previousMaterial, previousData);
            falling.setDropItem(false);
            if (fallingBlockVelocity != null) {
                SafetyUtils.setVelocity(falling, fallingBlockVelocity);
            }
            if (fallingBlockMaxDamage > 0 && fallingBlockFallDamage > 0) {
                CompatibilityUtils.setFallingBlockDamage(falling, fallingBlockFallDamage, fallingBlockMaxDamage);
            } else {
                falling.setHurtEntities(fallingBlocksHurt);
            }
            context.registerForUndo(falling);
        }
    }
    if (breakable > 0) {
        context.registerBreakable(block, breakable);
    }
    if (backfireChance > 0) {
        context.registerReflective(block, backfireChance);
    }
    if (commit) {
        com.elmakers.mine.bukkit.api.block.BlockData blockData = com.elmakers.mine.bukkit.block.UndoList.register(block);
        blockData.commit();
    }
    return SpellResult.CAST;
}
Also used : Material(org.bukkit.Material) FallingBlock(org.bukkit.entity.FallingBlock) MaterialBrush(com.elmakers.mine.bukkit.api.block.MaterialBrush) UndoList(com.elmakers.mine.bukkit.api.block.UndoList) Mage(com.elmakers.mine.bukkit.api.magic.Mage) Block(org.bukkit.block.Block) FallingBlock(org.bukkit.entity.FallingBlock) ItemStack(org.bukkit.inventory.ItemStack) Vector(org.bukkit.util.Vector) Location(org.bukkit.Location)

Example 15 with MaterialBrush

use of com.elmakers.mine.bukkit.api.block.MaterialBrush in project MagicPlugin by elBukkit.

the class CheckBlockAction method isAllowed.

protected boolean isAllowed(CastContext context) {
    MaterialBrush brush = context.getBrush();
    Block block = context.getTargetBlock();
    if (block == null) {
        return false;
    }
    if (allowed != null) {
        if (!allowed.testBlock(block))
            return false;
    } else {
        if (brush != null && brush.isErase()) {
            if (!context.hasBreakPermission(block)) {
                return false;
            }
        } else {
            if (!context.hasBuildPermission(block)) {
                return false;
            }
        }
        if (!context.isDestructible(block)) {
            return false;
        }
    }
    return true;
}
Also used : MaterialBrush(com.elmakers.mine.bukkit.api.block.MaterialBrush) Block(org.bukkit.block.Block)

Aggregations

MaterialBrush (com.elmakers.mine.bukkit.api.block.MaterialBrush)20 Block (org.bukkit.block.Block)14 Location (org.bukkit.Location)8 Vector (org.bukkit.util.Vector)7 Material (org.bukkit.Material)6 FallingBlock (org.bukkit.entity.FallingBlock)4 Target (com.elmakers.mine.bukkit.utility.Target)3 UndoList (com.elmakers.mine.bukkit.api.block.UndoList)2 Mage (com.elmakers.mine.bukkit.api.magic.Mage)2 ConstructionType (com.elmakers.mine.bukkit.block.ConstructionType)2 UndoList (com.elmakers.mine.bukkit.block.UndoList)2 BlockFace (org.bukkit.block.BlockFace)2 BlockState (org.bukkit.block.BlockState)2 ItemStack (org.bukkit.inventory.ItemStack)2 BlockData (com.elmakers.mine.bukkit.api.block.BlockData)1 BlockList (com.elmakers.mine.bukkit.api.block.BlockList)1 MaterialAndData (com.elmakers.mine.bukkit.api.block.MaterialAndData)1 UndoQueue (com.elmakers.mine.bukkit.api.block.UndoQueue)1 EntityData (com.elmakers.mine.bukkit.api.entity.EntityData)1 ConstructBatch (com.elmakers.mine.bukkit.batch.ConstructBatch)1