@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;
  }
Example #3
0
    @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;
	}