Beispiel #1
0
  private void chooseNewPath(MobileEntity me) {
    this.currentPath =
        me.findPathFromTo(me, (int) (this.destCell.getX()), (int) (this.destCell.getY()));
    this.currentPathIndex = 1;

    this.isNewPath = true;

    // It seems destination cell are blocked, try to choose nearest free cell as new destination
    // cell
    if (this.currentPath == null) {
      Pos newDestCell = chooseClosestToDestCell(me);

      // Give up
      if (newDestCell == null) {
        this.isNewPath = false;
        return;
      }

      this.destCell = newDestCell;
      this.currentPath =
          me.findPathFromTo(me, (int) (this.destCell.getX()), (int) (this.destCell.getY()));

      if (this.currentPath != null) {
        this.forceRange = false;
      }

      this.isNewPath = true;
    }
  }
Beispiel #2
0
  @Override
  public Activity tick(EntityActor a) {
    Pos nextCell = null;

    if (isCancelled || !(a instanceof MobileEntity)) {
      return nextActivity;
    }

    MobileEntity me = (MobileEntity) a;

    if (currentPath == null) {
      return nextActivity;
    }

    if (randomWaitTicks > 0) {
      randomWaitTicks--;
      return this;
    }

    nextCell = popPath(me);

    if (nextCell == null) {
      return this;
    }

    me.isMovingToCell = true;
    me.targetCellX = (int) nextCell.getX();
    me.targetCellY = (int) nextCell.getY();

    /*
     * 1. Turn to required facing
     * 2. Drag to required cell
     * 3. Continue moving
     *
     *         Movement system:
     *
     *                     +-----<------+
     *                     |            |
     *                     v            ^
     * Activity queue: MovePart --+     | (change facing and drag to target cell)
     *                            |     ^
     *                            v     |
     *                           Move ->+ (if we have next cell to move)
     */

    MovePart movePartActivity = new MovePart(this, me, me.getPos(), nextCell);
    if (this.isNewPath) {
      movePartActivity.setIsNewPath(true);

      this.isNewPath = false;
    }

    movePartActivity.tick(
        me); // Tick once to avoid tick skipping without movement when current activiy is Move

    return movePartActivity;
  }
Beispiel #3
0
    public MovePart(MoveInfantry aParentMove, MobileEntity aMe, Pos aStart, Pos aDestCell) {
      this.parentMove = aParentMove;

      this.me = aMe;
      this.me.targetCellX = (int) aDestCell.getX();
      this.me.targetCellY = (int) aDestCell.getY();

      int subOffsetXnext =
          (int) EntityInfantry.subcellOffsets[this.me.desiredSubcell.ordinal()].getX();
      int subOffsetYnext =
          (int) EntityInfantry.subcellOffsets[this.me.desiredSubcell.ordinal()].getY();

      int subOffsetXcurr =
          (int) EntityInfantry.subcellOffsets[this.me.currentSubcell.ordinal()].getX();
      int subOffsetYcurr =
          (int) EntityInfantry.subcellOffsets[this.me.currentSubcell.ordinal()].getY();

      this.end =
          new Pos(
              (aDestCell.getX() * 24) + subOffsetXnext, (aDestCell.getY() * 24) + subOffsetYnext);
      this.start = aStart;

      this.lengthInTicks = (int) (40 - (10 * me.getMoveSpeed()));

      int facing =
          RotationUtil.getRotationFromXY(start.getX(), start.getY(), end.getX(), end.getY());
      this.desiredFacing = RotationUtil.quantizeFacings(facing, this.me.getMaxFacings());
    }
Beispiel #4
0
    @Override
    public Activity tick(EntityActor a) {
      Pos nextPos;

      if (lengthInTicks > 1) {
        nextPos = PointsUtil.interpolatePos(start, end, ticks, lengthInTicks - 1);
      } else {
        nextPos = end;
      }

      if (me.currentFacing != this.desiredFacing) {
        me.currentFacing = this.desiredFacing % this.me.getMaxFacings();

        // Don't move while our turn is not finished for new direction
        if (isNewPath) {
          return this;
        }
      } else {
        this.isNewPath = false;
      }

      me.setPos(nextPos);

      ticks++;
      // If move is finished, return control to parent activity
      if ((me.getPos().getX() == end.getX() && me.getPos().getY() == end.getY())
          || ticks >= lengthInTicks) {
        me.currentFacing = this.desiredFacing % this.me.getMaxFacings();
        me.currentSubcell = me.desiredSubcell;
        me.finishMoving();

        // Parent Move activity is cancelled, lets switch to next activity (user send move order
        // when Move/PartMove activity is working)
        if (this.nextActivity instanceof MoveInfantry || parentMove.isCancelled()) {
          return this.nextActivity;
        } else {
          return parentMove;
        }
      } else {
        return this;
      }
    }
Beispiel #5
0
  private Pos popPath(MobileEntity me) {
    int px = 0, py = 0;

    if (this.currentPath == null
        || currentPathIndex >= this.currentPath.getLength()
        || this.currentPath.getLength() < 1) {
      this.currentPath = null;
      return null;
    }

    Step s = currentPath.getStep(currentPathIndex);
    px = s.getX();
    py = s.getY();

    Pos nextCell = new Pos(px, py);

    me.desiredSubcell = me.currentSubcell;
    if (!me.world.blockingEntityMap.isSubcellFree(nextCell, me.desiredSubcell)) {
      me.desiredSubcell = me.world.blockingEntityMap.getFreeSubCell(nextCell, me.currentSubcell);

      if (me.desiredSubcell == null) {
        me.desiredSubcell = me.currentSubcell;
      }
    }

    if (!me.canEnterCell(nextCell)) {
      // This building we ignore
      if (this.ignoreBuilding != null
          && me.world.getBuildingInCell(nextCell) == this.ignoreBuilding) {
        this.hasNotifiedBlocker = false;
        this.hasWaited = false;

        return null;
      }

      // See if we close enough
      float dx = destCell.getX() - nextCell.getX();
      float dy = destCell.getY() - nextCell.getY();

      if (dx * dx + dy * dy <= this.destRange * this.destRange) {
        // System.out.println("We're close enough. Range: " + Math.sqrt(dx * dx + dy * dy) + " <= "
        // + this.destRange);
        this.currentPathIndex = this.currentPath.getLength(); // stop and skip all path
        this.currentPath = null;

        return null;
      }

      // Notify all friendly blockers inside cell
      if (!this.hasNotifiedBlocker) {
        for (Influence i : me.world.blockingEntityMap.getCellInfluences(nextCell)) {
          Entity blocker = i.entity;

          if (blocker instanceof MobileEntity) {
            // Notify blocker
            if (blocker != null && ((MobileEntity) blocker).isFrendlyTo(me)) {
              ((MobileEntity) blocker).notifyBlocking(me);
            }
          }
        }

        this.hasNotifiedBlocker = true;
      }

      // Wait a bit
      if (!this.hasWaited) {
        this.waitTicksRemaining =
            me.getWaitAverageTime()
                + me.world.getRandomInt(-me.getWaitSpreadTime(), me.getWaitSpreadTime());

        // System.out.println("Waiting time: " + this.waitTicksRemaining);
        this.hasWaited = true;
        ((EntityInfantry) me).setCurrentAnimationState(AnimationState.WAITING);
      }

      if (--this.waitTicksRemaining >= 0) { // We're waiting now
        return null;
      }

      // We're totally blocked, try to calculate new path
      chooseNewPath(me);

      return null;
    }

    ((EntityInfantry) me).setCurrentAnimationState(AnimationState.MOVING);

    if (--this.ticksBeforeRepath <= 0) {
      this.ticksBeforeRepath = this.REPATHING_INTERVAL_TICKS;

      chooseNewPath(me);
    }

    this.currentPathIndex++;
    this.hasNotifiedBlocker = false;
    this.hasWaited = false;

    return nextCell;
  }
Beispiel #6
0
 public Pos chooseClosestToDestCell(MobileEntity me) {
   return me.world.chooseClosestPassableCellInRangeAroundOtherCell(
       me.getCellPos(), this.destCell, this.destRange);
 }