/** * Generates a list of possible step combinations that should be done at the beginning of a path * This implementation generates exactly one path, which is either no moves or one hex forward when velocity > 0 * @return "List" of all possible "starting" paths */ @Override protected List<MovePath> generateStartingPaths(MovePath startingEdge) { List<MovePath> startingPaths = new ArrayList<>(); // calculate max and min safe velocity // in space, we can go as slow or as fast as we want. IAero aero = (IAero) startingEdge.getEntity(); int maxThrust = AeroPathUtil.calculateMaxSafeThrust(aero); int maxVelocity = aero.getCurrentVelocity() + maxThrust; int minVelocity = Math.max(0, aero.getCurrentVelocity() - maxThrust); startingPaths.addAll(AeroPathUtil.generateValidAccelerations(startingEdge, minVelocity, maxVelocity)); // all non-zero-velocity paths must move at least one hex forward for(MovePath path : startingPaths) { if(path.getFinalVelocity() > 0) { path.addStep(MoveStepType.FORWARDS); } } return startingPaths; }
/** * Generate all possible paths given a starting movement path. * This includes increases and decreases in elevation. */ @Override protected List<MovePath> GenerateAllPaths(MovePath mp) { List<MovePath> altitudePaths = AeroPathUtil.generateValidAltitudeChanges(mp); List<MovePath> fullMovePaths = new ArrayList<>(); for(MovePath altitudePath : altitudePaths) { fullMovePaths.addAll(super.GenerateAllPaths(altitudePath.clone())); } return fullMovePaths; }
/** * Returns filtered collection by removing those objects that fail * {@link #shouldStay(T)} test. * * @param collection collection to be filtered * @return filtered collection */ @Override public Collection<MovePath> doFilter(Collection<MovePath> collection) { List<MovePath> filteredMoves = new ArrayList<>(); for (MovePath e : collection) { // if the path does not go off board, then we add it to the returned collection if (shouldStay(e)) { filteredMoves.add(e); } else { // if the path *does* go off board, we want to compare its length to // our current shortest off-board path and keep it in mind if it's both shorter and safe // at the end of the process, we will add the shortest path off board to the list of moves if(shortestPath == null || (shortestPath.length() > e.length()) && AeroPathUtil.isSafePathOffBoard(e)) { shortestPath = e; } } } return filteredMoves; }
/** * A quick determination that checks the given path for the most common causes of a PSR and whether it leads us off board. * The idea being that a safe path off board should not include any PSRs. * @param movePath The path to check * @return True or false */ public static boolean isSafePathOffBoard(MovePath movePath) { // common causes of PSR include, but are not limited to: // stalling your aircraft // crashing your aircraft into the ground // executing maneuvers // thrusting too hard // see your doctor if you experience any of these symptoms as it may lead to your aircraft transforming into a lawn dart return !willStall(movePath) && !willCrash(movePath) && movePath.fliesOffBoard() && !movePath.contains(MoveStepType.MANEUVER) && (movePath.getMpUsed() <= movePath.getEntity().getWalkMP()) && (movePath.getEntity().isAero() && (movePath.getMpUsed() <= ((IAero) movePath.getEntity()).getSI())); }
/** * Helper function that insinuates an "evade" step for aircraft that will not be shooting. * @param path The path to process */ private void evadeIfNotFiring(MovePath path, boolean possibleToInflictDamage) { Entity pathEntity = path.getEntity(); // we cannot evade if we are out of control if(pathEntity.isAero() && pathEntity.isAirborne() && ((IAero) pathEntity).isOutControlTotal()) { return; } // if we're an airborne aircraft // and we're not going to do any damage anyway // and we can do so without causing a PSR // then evade if(pathEntity.isAirborne() && !possibleToInflictDamage && (path.getMpUsed() <= AeroPathUtil.calculateMaxSafeThrust((IAero) path.getEntity()) - 2)) { path.addStep(MoveStepType.EVADE); } }
maxThrust = AeroPathUtil.calculateMaxSafeThrust(aero); int maxVelocity = Math.min(getMaximumVelocity(aero), aero.getCurrentVelocity() + maxThrust); int minVelocity = Math.max(getMinimumVelocity(aero), aero.getCurrentVelocity() - maxThrust); Collection<MovePath> validAccelerations = AeroPathUtil.generateValidAccelerations(startingEdge, minVelocity, maxVelocity);