private Locality getNearestLocality(Position position) { if (!position.isOnPath()) return (Locality) position.getLocation(); // return position.getDestination(); if (position.getProgress() > 0.5) { return position.getDestination(); } else { return position.getStart(); } }
private void approach(Position subjectPosition, Position targetPosition) { // if (subject.isMoving()) return; //can't work with that precondition yet // double divisor = 1.0; /*//if (target.isMoving()) return; //Simply avoid cycles if (target.isMoving() && targetPosition.getDestination() == subjectPosition.getLocation()) { divisor = 2.0; return; //Since the target is coming towards us all we have to do is wait. } else if (target.isMoving()) { move(targetPosition.getDestination()); return; } else if (target.isMoving()) { subject.stop(); return; }*/ // The cases that are to be distinguished: target is moving towards us, target is moving away // from us, target stays // These can be distinguished in case the following precondition applies: target is max 1 // locality away Locality dest = localityInDirectionOf(subjectPosition, targetPosition); double timeDistance = targetPosition.getDistance(subjectPosition); if (!target.isMoving()) { // First case - target is staying // reaction go to target and stay when on height of target if (move(dest) && targetPosition.isOnPath()) { // Only in case target is on path the timer is required timedAttack(timeDistance); } return; } else if (targetPosition.getDestination() == dest) { // Second case - target is going away from us // reaction just move to the same location as target move(dest); } else { // Third case: Target is coming towards us timeDistance = timeDistance / 2.0; move(dest); // Instead of dividing timeDistance by 2.0 it can be left unmodified in case // move(dest) remains unused timedAttack(timeDistance); } /*if (targetPosition.getDestination() != subjectPosition.getLocation()) { dest = targetPosition.getDestination(); }*/ // if (!move(dest)) return; }
private void trimPath(Position s, Position t, List<Locality> path) { if (!s.isOnPath() && path.size() > 0 && s.getLocation() == path.get(0)) path.remove(0); else if (s.isOnPath() && (path.size() == 1 || (path.size() > 1 && (s.getDestination() == path.get(1) || s.getStart() == path.get(1))))) path.remove(0); if (t.isOnPath() && (path.size() == 1 || (path.size() > 1 && (path.get(path.size() - 2) == t.getStart() || path.get(path.size() - 2) == t.getDestination())))) path.remove(path.size() - 1); }
private boolean inRange(Position s, Position t) { return s.getDistance(t) <= 10.0; }
private void followPath(Position spos, List<Locality> path) { if (!spos.isOnPath() || !subject.isMoving() || path.get(0) != spos.getDestination()) { move(path.get(0)); } }
private Locality localityInDirectionOf(Position from, Position to) { if (!to.isOnPath()) return (Locality) to.getLocation(); if (!from.isOnPath()) { if (from.getLocation() == to.getDestination()) return to.getStart(); else return to.getDestination(); } if (from.getDestination() != to.getDestination()) { to = new Position( (Path) to.getLocation(), to.getDestination(), to.getStart(), 1.0 - to.getProgress()); } if (from.getDestination() != to.getDestination() || from.getStart() != to.getStart()) { return to.getDestination(); } if (to.getProgress() >= from.getProgress()) return to.getDestination(); return to.getStart(); }