Search in sources :

Example 1 with UndoList

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

the class ConstructSpell method onCast.

@Override
public SpellResult onCast(ConfigurationSection parameters) {
    Block target = null;
    boolean isSelect = getTargetType() == TargetType.SELECT;
    boolean finalCast = !isSelect || this.targetBlock != null;
    if (finalCast && parameters.getBoolean("select_self", true) && isLookingDown()) {
        target = mage.getLocation().getBlock().getRelative(BlockFace.DOWN);
    } else {
        Target t = getTarget();
        target = t.getBlock();
    }
    if (target == null) {
        return SpellResult.NO_TARGET;
    }
    MaterialBrush buildWith = getBrush();
    boolean hasPermission = buildWith != null && buildWith.isErase() ? hasBreakPermission(target) : hasBuildPermission(target);
    if (!hasPermission) {
        return SpellResult.INSUFFICIENT_PERMISSION;
    }
    int radius = parameters.getInt("radius", DEFAULT_RADIUS);
    radius = parameters.getInt("r", radius);
    radius = parameters.getInt("size", radius);
    boolean falling = parameters.getBoolean("falling", false);
    boolean physics = parameters.getBoolean("physics", false);
    boolean commit = parameters.getBoolean("commit", false);
    boolean consume = parameters.getBoolean("consume", false);
    double breakable = parameters.getDouble("breakable", 0);
    double backfireChance = parameters.getDouble("reflect_chance", 0);
    Vector orientTo = null;
    Vector bounds = null;
    if (parameters.getBoolean("use_brush_size", false)) {
        if (!buildWith.isReady()) {
            long timeout = System.currentTimeMillis() + 10000;
            while (System.currentTimeMillis() < timeout) {
                try {
                    Thread.sleep(500);
                    if (buildWith.isReady()) {
                        break;
                    }
                } catch (InterruptedException ex) {
                    break;
                }
            }
            if (!buildWith.isReady()) {
                return SpellResult.NO_ACTION;
            }
        }
        bounds = buildWith.getSize();
        radius = (int) Math.max(Math.max(bounds.getX() / 2, bounds.getZ() / 2), bounds.getY());
    } else if (isSelect) {
        if (targetLocation2 != null) {
            this.targetBlock = targetLocation2.getBlock();
        }
        if (targetBlock == null || !targetBlock.getWorld().equals(target.getWorld())) {
            targetBlock = target;
            activate();
            return SpellResult.TARGET_SELECTED;
        } else {
            radius = (int) targetBlock.getLocation().distance(target.getLocation());
            if (parameters.getBoolean("orient")) {
                orientTo = target.getLocation().toVector().subtract(targetBlock.getLocation().toVector());
                orientTo.setX(Math.abs(orientTo.getX()));
                orientTo.setY(Math.abs(orientTo.getY()));
                orientTo.setZ(Math.abs(orientTo.getZ()));
                if (orientTo.getX() < orientTo.getZ() && orientTo.getX() < orientTo.getY()) {
                    orientTo = new Vector(1, 0, 0);
                } else if (orientTo.getZ() < orientTo.getX() && orientTo.getZ() < orientTo.getY()) {
                    orientTo = new Vector(0, 0, 1);
                } else {
                    orientTo = new Vector(0, 1, 0);
                }
            }
            target = targetBlock;
            targetBlock = null;
        }
    } else if (parameters.getBoolean("orient")) {
        // orientTo = mage.getLocation().toVector().crossProduct(target.getLocation().toVector());
        orientTo = mage.getLocation().toVector().subtract(target.getLocation().toVector());
        orientTo.setX(Math.abs(orientTo.getX()));
        orientTo.setY(Math.abs(orientTo.getY()));
        orientTo.setZ(Math.abs(orientTo.getZ()));
        if (orientTo.getX() > orientTo.getZ() && orientTo.getX() > orientTo.getY()) {
            orientTo = new Vector(1, 0, 0);
        } else if (orientTo.getZ() > orientTo.getX() && orientTo.getZ() > orientTo.getY()) {
            orientTo = new Vector(0, 0, 1);
        } else {
            orientTo = new Vector(0, 1, 0);
        }
    }
    if (!parameters.contains("radius")) {
        int maxDimension = parameters.getInt("max_dimension", DEFAULT_MAX_DIMENSION);
        maxDimension = parameters.getInt("md", maxDimension);
        maxDimension = (int) (mage.getConstructionMultiplier() * maxDimension);
        int diameter = radius * 2;
        if (diameter > maxDimension) {
            return SpellResult.FAIL;
        }
    }
    // TODO : Is this needed? Or just use "ty"?
    if (parameters.contains("y_offset")) {
        target = target.getRelative(BlockFace.UP, parameters.getInt("y_offset", 0));
    }
    buildWith.setTarget(target.getLocation());
    ConstructionType conType = DEFAULT_CONSTRUCTION_TYPE;
    int thickness = parameters.getInt("thickness", 0);
    String typeString = parameters.getString("type", "");
    ConstructionType testType = ConstructionType.parseString(typeString, ConstructionType.UNKNOWN);
    if (testType != ConstructionType.UNKNOWN) {
        conType = testType;
    }
    ConstructBatch batch = new ConstructBatch(this, target.getLocation(), conType, radius, thickness, falling, orientTo);
    batch.setCommit(commit);
    batch.setConsume(consume);
    UndoList undoList = getUndoList();
    if (undoList != null && !currentCast.isConsumeFree()) {
        undoList.setConsumed(consume);
    }
    if (parameters.getBoolean("replace", false)) {
        List<com.elmakers.mine.bukkit.api.block.MaterialAndData> replaceMaterials = new ArrayList<>();
        MaterialAndData wildReplace = new MaterialAndData(target);
        if (!parameters.getBoolean("match_data", true)) {
            wildReplace.setData(null);
        }
        // Hacky, but generally desired - maybe abstract to a parameterized list?
        Material targetMaterial = target.getType();
        if (targetMaterial == Material.STATIONARY_WATER || targetMaterial == Material.WATER || targetMaterial == Material.STATIONARY_LAVA || targetMaterial == Material.LAVA) {
            wildReplace.setData(null);
        }
        replaceMaterials.add(wildReplace);
        batch.setReplace(replaceMaterials);
    }
    // Check for command block overrides
    if (parameters.contains("commands")) {
        ConfigurationSection commandMap = parameters.getConfigurationSection("commands");
        Set<String> keys = commandMap.getKeys(false);
        for (String key : keys) {
            batch.addCommandMapping(key, commandMap.getString(key));
        }
    }
    if (falling) {
        float force = (float) parameters.getDouble("speed", 0);
        batch.setFallingDirection(ConfigurationUtils.getVector(parameters, "falling_direction"));
        batch.setFallingBlockSpeed(force);
    }
    batch.setApplyPhysics(physics);
    if (breakable > 0) {
        batch.setBreakable(breakable);
    }
    if (backfireChance > 0) {
        batch.setBackfireChance(backfireChance);
    }
    if (parameters.contains("orient_dimension_max")) {
        batch.setOrientDimensionMax(parameters.getInt("orient_dimension_max"));
    } else if (parameters.contains("odmax")) {
        batch.setOrientDimensionMax(parameters.getInt("odmax"));
    }
    if (parameters.contains("orient_dimension_min")) {
        batch.setOrientDimensionMin(parameters.getInt("orient_dimension_min"));
    } else if (parameters.contains("odmin")) {
        batch.setOrientDimensionMin(parameters.getInt("odmin"));
    }
    if (parameters.getBoolean("power", false)) {
        batch.setPower(true);
    }
    if (bounds != null) {
        batch.setBounds(bounds);
        batch.setOrientDimensionMin(0);
    }
    boolean success = mage.addBatch(batch);
    deactivate();
    return success ? SpellResult.CAST : SpellResult.FAIL;
}
Also used : ConstructBatch(com.elmakers.mine.bukkit.batch.ConstructBatch) ConstructionType(com.elmakers.mine.bukkit.block.ConstructionType) ArrayList(java.util.ArrayList) Material(org.bukkit.Material) Target(com.elmakers.mine.bukkit.utility.Target) MaterialBrush(com.elmakers.mine.bukkit.api.block.MaterialBrush) UndoList(com.elmakers.mine.bukkit.block.UndoList) MaterialAndData(com.elmakers.mine.bukkit.block.MaterialAndData) Block(org.bukkit.block.Block) Vector(org.bukkit.util.Vector) ConfigurationSection(org.bukkit.configuration.ConfigurationSection)

Example 2 with UndoList

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

the class UndoableSpell method getUndoList.

public UndoList getUndoList() {
    if (modifiedBlocks == null) {
        modifiedBlocks = new UndoList(mage, this.getName());
        modifiedBlocks.setSpell(this);
        configureUndoList();
    }
    return modifiedBlocks;
}
Also used : UndoList(com.elmakers.mine.bukkit.block.UndoList)

Example 3 with UndoList

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

the class RegenerateBatch method finish.

@Override
public void finish() {
    if (!finished) {
        UndoList modified = spell.getUndoList();
        modified.prune();
        restoredBlocks.setBatch(null);
        super.finish();
    }
}
Also used : UndoList(com.elmakers.mine.bukkit.block.UndoList)

Example 4 with UndoList

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

the class TreeAction method perform.

@Override
public SpellResult perform(CastContext context) {
    Block target = context.getTargetBlock();
    if (requireSapling && target.getType() != Material.SAPLING) {
        return SpellResult.NO_TARGET;
    }
    if (!context.hasBuildPermission(target)) {
        return SpellResult.INSUFFICIENT_PERMISSION;
    }
    World world = context.getWorld();
    Location treeLoc = new Location(world, target.getX(), target.getY() + 1, target.getZ(), 0, 0);
    Random random = context.getRandom();
    TreeType useType = null;
    if (treeType != null) {
        useType = treeType;
    } else if (biomeMap != null) {
        Biome biome = treeLoc.getWorld().getBiome(treeLoc.getBlockX(), treeLoc.getBlockZ());
        List<TreeType> types = biomeMap.get(biome);
        if (types != null) {
            useType = types.get(random.nextInt(types.size()));
        }
    }
    if (useType == null) {
        useType = TreeType.values()[random.nextInt(TreeType.values().length)];
    }
    UndoList restoreOnFail = new UndoList(context.getMage(), context.getSpell().getName());
    Block treeBlock = treeLoc.getBlock();
    if (!context.isDestructible(treeBlock)) {
        return SpellResult.NO_TARGET;
    }
    restoreOnFail.add(treeBlock);
    treeLoc.getBlock().setType(Material.AIR);
    boolean result = world.generateTree(treeLoc, useType);
    if (!result) {
        UndoList undoList = new UndoList(context.getMage(), context.getSpell().getName());
        for (int z = -2; z <= 2; z++) {
            for (int x = -2; x <= 2; x++) {
                Block clearBlock = treeBlock.getRelative(x, 0, z);
                Block lowerBlock = clearBlock.getRelative(BlockFace.DOWN);
                if (context.isDestructible(clearBlock) && lowerBlock.getType() != target.getType()) {
                    undoList.add(lowerBlock);
                    lowerBlock.setType(target.getType());
                }
                if (x == 0 && z == 0)
                    continue;
                if (!context.isDestructible(clearBlock))
                    continue;
                restoreOnFail.add(clearBlock);
                clearBlock.setType(Material.AIR);
            }
        }
        result = world.generateTree(treeLoc, useType);
        context.addWork(100);
        undoList.undo(true);
    }
    if (result) {
        context.addWork(500);
    } else {
        context.addWork(100);
        restoreOnFail.undo(true);
    }
    return result ? SpellResult.CAST : SpellResult.FAIL;
}
Also used : TreeType(org.bukkit.TreeType) Biome(org.bukkit.block.Biome) Random(java.util.Random) UndoList(com.elmakers.mine.bukkit.block.UndoList) Block(org.bukkit.block.Block) UndoList(com.elmakers.mine.bukkit.block.UndoList) ArrayList(java.util.ArrayList) List(java.util.List) World(org.bukkit.World) Location(org.bukkit.Location)

Example 5 with UndoList

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

the class UndoableSpell method prepareForUndo.

public void prepareForUndo() {
    UndoList list = getUndoList();
    mage.prepareForUndo(list);
}
Also used : UndoList(com.elmakers.mine.bukkit.block.UndoList)

Aggregations

UndoList (com.elmakers.mine.bukkit.block.UndoList)7 Block (org.bukkit.block.Block)3 MaterialBrush (com.elmakers.mine.bukkit.api.block.MaterialBrush)2 ArrayList (java.util.ArrayList)2 Location (org.bukkit.Location)2 ConstructBatch (com.elmakers.mine.bukkit.batch.ConstructBatch)1 FillBatch (com.elmakers.mine.bukkit.batch.FillBatch)1 ConstructionType (com.elmakers.mine.bukkit.block.ConstructionType)1 MaterialAndData (com.elmakers.mine.bukkit.block.MaterialAndData)1 Target (com.elmakers.mine.bukkit.utility.Target)1 List (java.util.List)1 Random (java.util.Random)1 Material (org.bukkit.Material)1 TreeType (org.bukkit.TreeType)1 World (org.bukkit.World)1 Biome (org.bukkit.block.Biome)1 ConfigurationSection (org.bukkit.configuration.ConfigurationSection)1 Vector (org.bukkit.util.Vector)1