@Override public SpellResult step(CastContext context) { Block attachBlock = context.getTargetBlock(); BlockFace direction = BlockFace.UP; Block targetBlock = attachBlock.getRelative(direction); int distance = 0; while (context.isTargetable(targetBlock) && distance <= MAX_SEARCH_DISTANCE) { distance++; attachBlock = targetBlock; targetBlock = attachBlock.getRelative(direction); } if (context.isTargetable(targetBlock)) { return SpellResult.NO_TARGET; } actionContext.setTargetLocation(targetBlock.getLocation()); context.getBrush().setTarget(attachBlock.getLocation(), targetBlock.getLocation()); return startActions(); }
@Override public SpellResult perform(CastContext context) { Block targetBlock = context.getTargetBlock(); Entity currentEntity = current == null ? null : current.get(); current = null; if (currentEntity != null) { currentEntity.remove(); } targetBlock = targetBlock.getRelative(BlockFace.UP); Location spawnLocation = targetBlock.getLocation(); Location sourceLocation = context.getLocation(); spawnLocation.setPitch(sourceLocation.getPitch()); spawnLocation.setYaw(sourceLocation.getYaw()); MageController controller = context.getController(); if (entityData == null) { String randomType = RandomUtils.weightedRandom(entityTypeProbability); try { entityData = controller.getMob(randomType); if (entityData == null) { entityData = new com.elmakers.mine.bukkit.entity.EntityData( EntityType.valueOf(randomType.toUpperCase())); } } catch (Throwable ex) { entityData = null; } } if (entityData == null) { return SpellResult.FAIL; } if (force) { controller.setForceSpawn(true); } Entity spawnedEntity = null; try { spawnedEntity = entityData.spawn(context.getController(), spawnLocation, spawnReason); } catch (Exception ex) { ex.printStackTrace(); } if (force) { controller.setForceSpawn(false); } if (spawnedEntity == null) { return SpellResult.FAIL; } if (!loot) { spawnedEntity.setMetadata("nodrops", new FixedMetadataValue(controller.getPlugin(), true)); } if (speed > 0) { Vector motion = direction; if (motion == null) { motion = context.getDirection(); } else { motion = motion.clone(); } if (dyOffset != 0) { motion.setY(motion.getY() + dyOffset); } motion.normalize(); motion.multiply(speed); CompatibilityUtils.setEntityMotion(spawnedEntity, motion); } Collection<EffectPlayer> projectileEffects = context.getEffects("spawned"); for (EffectPlayer effectPlayer : projectileEffects) { effectPlayer.start(spawnedEntity.getLocation(), spawnedEntity, null, null); } context.registerForUndo(spawnedEntity); if (track) { current = new WeakReference<Entity>(spawnedEntity); } if (setTarget) { context.setTargetEntity(spawnedEntity); } return SpellResult.CAST; }
@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; }