public boolean advance() {
    Vector dir = loc.getDirection();
    dir.add(new Vector(0.0f, -0.008, 0.0f)); // Apply 'gravity'	
    loc.setDirection(dir);

    loc.add(dir.multiply(speed));
    loc.getWorld().createExplosion(loc, 0.0f, false);

    if (ItemManager.getId(loc.getBlock()) != CivData.AIR) {
      return true;
    }

    if (loc.distance(startLoc) > maxRange) {
      return true;
    }

    return false;
  }
示例#2
0
  public void target(TargetMode mode) {
    targetMode = mode == null ? TargetMode.STABILIZE : mode;
    switch (targetMode) {
      case FLEE:
      case HUNT:
      case DIRECTED:
        Target bestTarget = null;
        reverseTargetDistanceScore = true;
        if (targetType == TargetType.ANY || targetType == TargetType.MOB) {
          List<Entity> entities =
              CompatibilityUtils.getNearbyEntities(
                  center, huntMaxRange, huntMaxRange, huntMaxRange);
          for (Entity entity : entities) {
            // We'll get the players from the Mages list
            if (entity instanceof Player || !(entity instanceof LivingEntity) || entity.isDead())
              continue;
            if (!entity.getLocation().getWorld().equals(center.getWorld())) continue;
            LivingEntity li = (LivingEntity) entity;
            if (li.hasPotionEffect(PotionEffectType.INVISIBILITY)) continue;
            Target newScore =
                new Target(center, entity, huntMinRange, huntMaxRange, huntFov, false);
            int score = newScore.getScore();
            if (bestTarget == null || score > bestTarget.getScore()) {
              bestTarget = newScore;
            }
          }
        }
        if (targetType == TargetType.MAGE
            || targetType == TargetType.AUTOMATON
            || targetType == TargetType.ANY
            || targetType == TargetType.PLAYER) {
          Collection<Mage> mages = controller.getMages();
          for (Mage mage : mages) {
            if (mage == this.mage) continue;
            if (targetType == TargetType.AUTOMATON && mage.getPlayer() != null) continue;
            if (targetType == TargetType.PLAYER && mage.getPlayer() == null) continue;
            if (mage.isDead() || !mage.isOnline() || !mage.hasLocation()) continue;
            if (!mage.getLocation().getWorld().equals(center.getWorld())) continue;
            if (!mage.getLocation().getWorld().equals(center.getWorld())) continue;

            if (!mage.isPlayer()) {
              // Check for automata of the same type, kinda hacky.. ?
              Block block = mage.getLocation().getBlock();
              if (block.getType() == Material.COMMAND) {
                BlockState blockState = block.getState();
                if (blockState != null && blockState instanceof CommandBlock) {
                  CommandBlock command = (CommandBlock) blockState;
                  String commandString = command.getCommand();
                  if (commandString != null
                      && commandString.length() > 0
                      && commandString.startsWith("cast " + spell.getKey())) {
                    continue;
                  }
                }
              }
            } else {
              Player player = mage.getPlayer();
              if (player.hasPotionEffect(PotionEffectType.INVISIBILITY)) continue;
            }

            Target newScore = new Target(center, mage, huntMinRange, huntMaxRange, huntFov, false);
            int score = newScore.getScore();
            if (bestTarget == null || score > bestTarget.getScore()) {
              bestTarget = newScore;
            }
          }
        }

        if (bestTarget != null) {
          String targetDescription =
              bestTarget.getEntity() == null
                  ? "NONE"
                  : ((bestTarget instanceof Player)
                      ? ((Player) bestTarget.getEntity()).getName()
                      : bestTarget.getEntity().getType().name());

          if (DEBUG) {
            controller
                .getLogger()
                .info(
                    " *Tracking "
                        + targetDescription
                        + " score: "
                        + bestTarget.getScore()
                        + " location: "
                        + center
                        + " -> "
                        + bestTarget.getLocation()
                        + " move "
                        + commandMoveRangeSquared);
          }
          Vector direction = null;

          if (targetMode == TargetMode.DIRECTED) {
            direction = bestTarget.getLocation().getDirection();
            if (DEBUG) {
              controller.getLogger().info(" *Directed: " + direction);
            }
          } else {
            Location targetLocation = bestTarget.getLocation();
            direction = targetLocation.toVector().subtract(center.toVector());
          }

          if (direction != null) {
            center.setDirection(direction);
          }

          // Check for obstruction
          // TODO Think about this more..
          /*
          Block block = spell.getInteractBlock();
          if (block.getType() != Material.AIR && block.getType() != POWER_MATERIAL && !!birthMaterial.is(block)) {
          	// TODO: Use location.setDirection in 1.7+
          	center = CompatibilityUtils.setDirection(center, new Vector(0, 1, 0));
          }
          */

          if (level != null
              && center.distanceSquared(bestTarget.getLocation()) < castRange * castRange) {
            level.onTick(mage, birthMaterial);
          }

          // After ticking, re-position for movement. This way spells still fire towards the target.
          if (targetMode == TargetMode.FLEE) {
            direction = direction.multiply(-1);
            // Don't Flee upward
            if (direction.getY() > 0) {
              direction.setY(-direction.getY());
            }
          }
        }
        break;
      case GLIDE:
        reverseTargetDistanceScore = true;
        break;
      default:
        reverseTargetDistanceScore = false;
    }
  }
 @Override
 public SpellResult perform(CastContext context) {
   Entity sourceEntity = context.getEntity();
   Location sourceLocation = context.getEyeLocation().clone();
   Entity targetEntity = context.getTargetEntity();
   Location targetLocation = context.getTargetLocation();
   if (targetLocation != null) {
     targetLocation = targetLocation.clone();
   }
   Vector direction = context.getDirection().normalize();
   if (sourceLocation == null) {
     return SpellResult.LOCATION_REQUIRED;
   }
   if (targetSelf) {
     targetEntity = sourceEntity;
     targetLocation = sourceLocation;
   } else if (targetEntityLocation && targetEntity != null) {
     targetLocation = targetEntity.getLocation();
   }
   if (attachBlock) {
     Block previousBlock = context.getPreviousBlock();
     if (previousBlock != null) {
       Location current = targetLocation;
       targetLocation = previousBlock.getLocation();
       context.getBrush().setTarget(current, targetLocation);
     }
   }
   if (sourceOffset != null) {
     sourceLocation = sourceLocation.add(sourceOffset);
   }
   if (targetOffset != null && targetLocation != null) {
     targetLocation = targetLocation.add(targetOffset);
   }
   if (randomSourceOffset != null) {
     sourceLocation = RandomUtils.randomizeLocation(sourceLocation, randomSourceOffset);
   }
   if (randomTargetOffset != null && targetLocation != null) {
     targetLocation = RandomUtils.randomizeLocation(targetLocation, randomTargetOffset);
   }
   if (targetDirection != null && targetLocation != null) {
     targetLocation.setDirection(targetDirection);
   }
   if (sourceDirection != null) {
     sourceLocation.setDirection(sourceDirection);
     direction = sourceDirection.clone();
   }
   if (targetDirectionOffset != null && targetLocation != null) {
     targetLocation.setDirection(targetLocation.getDirection().add(targetDirectionOffset));
   }
   if (sourceDirectionOffset != null) {
     sourceLocation.setDirection(direction.add(sourceDirectionOffset));
   }
   if (sourceDirectionSpeed != null) {
     sourceLocation = sourceLocation.add(direction.clone().multiply(sourceDirectionSpeed));
   }
   if (targetDirectionSpeed != null && targetLocation != null) {
     targetLocation = targetLocation.add(direction.clone().multiply(targetDirectionSpeed));
   }
   if (sourceAtTarget && targetLocation != null) {
     sourceLocation.setX(targetLocation.getX());
     sourceLocation.setY(targetLocation.getY());
     sourceLocation.setZ(targetLocation.getZ());
     sourceLocation.setWorld(targetLocation.getWorld());
   }
   if (persistTarget) {
     context.setTargetLocation(targetLocation);
   }
   CastContext newContext =
       createContext(context, sourceEntity, sourceLocation, targetEntity, targetLocation);
   return super.perform(newContext);
 }