/* Get how much to move without turning */
double yVel = Math.sin(Math.toRadians(getDirection()*45))*movement;
double xVel = Math.cos(Math.toRadians(getDirection()*45))*movement;
Vector2f newLocation = new Vector2f(this.getLocation());
newLocation.x += xVel;
newLocation.y += yVel;
Point newTile = new Point(Math.round(newLocation.x), Math.round(newLocation.y));
/* Get how much we have moved in this tile (0.0 - 1.0) */
float tileProgress = 0f;
if(getDirection() == 0){
tileProgress = newLocation.x - (float)oldTile.x + 0.5f;
}
else if(getDirection() == 2){
tileProgress = newLocation.y - (float)oldTile.y + 0.5f;
}
else if(getDirection() == 4){
tileProgress = (float)oldTile.x - newLocation.x + 0.5f;
}
else if(getDirection() == 6){
tileProgress = (float)oldTile.y - newLocation.y + 0.5f;
}
this.tileProgress = tileProgress;
if(prev == null){
/* Currently the train is active */
if(!oldTile.equals(newTile)){
/* We have moved in to a new tile, so calculate next turn */
this.mayTurn = true;
int nextDirection = this.getDirection();
boolean freeDirs[] = map.scanRideable(newTile.x, newTile.y);
int right = (getDirection()+2)%8;
int left = (getDirection()-2)%8;
if(left < 0)
left += 8;
if((!freeDirs[getDirection()] && freeDirs[right] && !freeDirs[left])
|| (!freeDirs[getDirection()] && freeDirs[right] && freeDirs[left] && this.getInterSectionDirection() == 0)){
/* Can only turn right */
nextDirection = this.getTurnDirection(2);
System.out.println("Forced right turn");
}
else if(!freeDirs[getDirection()] && !freeDirs[right] && freeDirs[left]){
/* Can only turn left */
nextDirection = this.getTurnDirection(-2);
System.out.println("Forced left turn");
}
else if((!freeDirs[getDirection()] && !freeDirs[right] && !freeDirs[left])){
/* Can only reverse */
nextDirection = this.getTurnDirection(-4);
System.out.println("Reversing");
}
else{
if(this.getInterSectionDirection() == LEFT && freeDirs[left]){
/* Can't go forward but can go right & left, left chosen */
nextDirection = this.getTurnDirection(-2);
this.intersectionControl = 0;
System.out.println("Left turn");
}
else if(this.getInterSectionDirection() == RIGHT && freeDirs[right]){
/* Can't go forward but can go right & left, right chosen */
nextDirection = this.getTurnDirection(2);
this.intersectionControl = 0;
System.out.println("Right turn");
}
}
/* Update model angles to have a smooth turn */
oldAngle = this.getDirection();
newAngle = nextDirection;
/* We are starting a turn, so set lastTurn to this tile */
if(this.getDirection() != nextDirection)
this.nextTurnPoint = new TurnPoint(newTile, nextDirection);
/* Adjust tileProgress, since we moved in to a new tile */
this.tileProgress = tileProgress-1f;
}
}
else{
/* Currently a coach is active */
if(prev.getNextTurnPoint() != null && (this.nextTurns.isEmpty() || !this.nextTurns.peekLast().getTile().equals(prev.getNextTurnPoint().getTile()))){
/* Query previous TrackRider's latest turn and compare it to the last one in this queue.
* Add it to the end of queue, if it isn't already there.
*/
this.nextTurns.add(prev.getNextTurnPoint());
}
if(!oldTile.equals(newTile)){
if(!this.nextTurns.isEmpty()){
/* There are turns queued */
if(newTile.equals(this.nextTurns.peekFirst().getTile())){
/* Current tile matches the tile at the front of turn queue, so execute a turn. */
this.mayTurn = true;
TurnPoint nextTurn = this.nextTurns.pollFirst();
this.nextTurnPoint = new TurnPoint(nextTurn.getTile(), nextTurn.getDirection());
}
}
/* Update model angles to have a smooth turn */
oldAngle = this.getDirection();
newAngle = (this.nextTurnPoint != null)?this.nextTurnPoint.getDirection():this.getDirection();
/* Adjust tileProgress, since we moved in to a new tile */
this.tileProgress = tileProgress-1f;
}
}
if(this.mayTurn && this.tileProgress > 0.5f){
/* Turn flag has been set and the TrackRider is over half way the current tile,
* so try to turn to the next direction.
*/
if(this.nextTurnPoint != null && this.getDirection() != this.nextTurnPoint.getDirection()){
/* Current direction is different from next turn direction, so turn */
this.setDirection(this.nextTurnPoint.getDirection());
/* Set position to the center of current tile and add how much is
* still needed to adjust position with the new direction in mind.
*/
double overhead = tileProgress-0.5f;
//System.out.println("Turn "+((prev==null)?"Train":"Coach")+" "+overhead);
yVel = Math.sin(Math.toRadians(getDirection()*45))*overhead;
xVel = Math.cos(Math.toRadians(getDirection()*45))*overhead;
newLocation.set((float)(newTile.x+xVel), (float)(newTile.y+yVel));
/* TrackRider has turned. Unset the turn point. */
this.nextTurnPoint = null;
}