src/ship_cmd.cpp
branchNewGRF_ports
changeset 10994 cd9968b6f96b
parent 10991 d8811e327d12
equal deleted inserted replaced
10991:d8811e327d12 10994:cd9968b6f96b
   597 	if (!ShipAccelerate(v)) return;
   597 	if (!ShipAccelerate(v)) return;
   598 
   598 
   599 	BeginVehicleMove(v);
   599 	BeginVehicleMove(v);
   600 
   600 
   601 	GetNewVehiclePosResult gp = GetNewVehiclePos(v);
   601 	GetNewVehiclePosResult gp = GetNewVehiclePos(v);
   602 	if (gp.old_tile == gp.new_tile) {
   602 	if (v->u.ship.state != TRACK_BIT_WORMHOLE) {
   603 		/* Staying in tile */
   603 		/* Not on a bridge */
   604 		if (v->IsInDepot()) {
   604 		if (gp.old_tile == gp.new_tile) {
   605 			gp.x = v->x_pos;
   605 			/* Staying in tile */
   606 			gp.y = v->y_pos;
   606 			if (v->IsInDepot()) {
   607 		} else {
   607 				gp.x = v->x_pos;
   608 			/* Not inside depot */
   608 				gp.y = v->y_pos;
   609 			r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
   609 			} else {
   610 			if (HasBit(r, VETS_CANNOT_ENTER)) goto reverse_direction;
   610 				/* Not inside depot */
   611 
   611 				r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
   612 			/* A leave station order only needs one tick to get processed, so we can
   612 				if (HasBit(r, VETS_CANNOT_ENTER)) goto reverse_direction;
   613 			 * always skip ahead. */
   613 
   614 			if (v->current_order.IsType(OT_LEAVESTATION)) {
   614 				/* A leave station order only needs one tick to get processed, so we can
   615 				v->current_order.Free();
   615 				* always skip ahead. */
   616 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   616 				if (v->current_order.IsType(OT_LEAVESTATION)) {
   617 			} else if (v->dest_tile != 0) {
   617 					v->current_order.Free();
   618 				/* We have a target, let's see if we reached it... */
   618 					InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   619 				if (v->current_order.IsType(OT_GOTO_STATION) &&
   619 				} else if (v->dest_tile != 0) {
   620 						IsBuoyTile(v->dest_tile) &&
   620 					/* We have a target, let's see if we reached it... */
   621 						DistanceManhattan(v->dest_tile, gp.new_tile) <= 3) {
   621 					if (v->current_order.IsType(OT_GOTO_STATION) &&
   622 					/* We got within 3 tiles of our target buoy, so let's skip to our
   622 							IsBuoyTile(v->dest_tile) &&
   623 					 * next order */
   623 							DistanceManhattan(v->dest_tile, gp.new_tile) <= 3) {
   624 					UpdateVehicleTimetable(v, true);
   624 						/* We got within 3 tiles of our target buoy, so let's skip to our
   625 					v->cur_order_index++;
   625 						* next order */
   626 					v->current_order.MakeDummy();
   626 						UpdateVehicleTimetable(v, true);
   627 					InvalidateVehicleOrder(v);
   627 						v->cur_order_index++;
   628 				} else {
   628 						v->current_order.MakeDummy();
   629 					/* Non-buoy orders really need to reach the tile */
   629 						InvalidateVehicleOrder(v);
   630 					if (v->dest_tile == gp.new_tile) {
   630 					} else {
   631 						if (v->current_order.IsType(OT_GOTO_DEPOT)) {
   631 						/* Non-buoy orders really need to reach the tile */
   632 							if ((gp.x & 0xF) == 8 && (gp.y & 0xF) == 8) {
   632 						if (v->dest_tile == gp.new_tile) {
   633 								VehicleEnterDepot(v);
   633 							if (v->current_order.IsType(OT_GOTO_DEPOT)) {
   634 								return;
   634 								if ((gp.x & 0xF) == 8 && (gp.y & 0xF) == 8) {
   635 							}
   635 									VehicleEnterDepot(v);
   636 						} else if (v->current_order.IsType(OT_GOTO_STATION)) {
   636 									return;
   637 							v->last_station_visited = v->current_order.GetDestination();
   637 								}
   638 
   638 							} else if (v->current_order.IsType(OT_GOTO_STATION)) {
   639 							/* Process station in the orderlist. */
   639 								v->last_station_visited = v->current_order.GetDestination();
   640 							Station *st = GetStation(v->current_order.GetDestination());
   640 
   641 							if (st->facilities & FACIL_DOCK) { // ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations
   641 								/* Process station in the orderlist. */
   642 								ShipArrivesAt(v, st);
   642 								Station *st = GetStation(v->current_order.GetDestination());
   643 								v->BeginLoading();
   643 								if (st->facilities & FACIL_DOCK) { // ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations
   644 							} else { // leave stations without docks right aways
   644 									ShipArrivesAt(v, st);
   645 								v->current_order.MakeLeaveStation();
   645 									v->BeginLoading();
   646 								v->cur_order_index++;
   646 								} else { // leave stations without docks right aways
   647 								InvalidateVehicleOrder(v);
   647 									v->current_order.MakeLeaveStation();
       
   648 									v->cur_order_index++;
       
   649 									InvalidateVehicleOrder(v);
       
   650 								}
   648 							}
   651 							}
   649 						}
   652 						}
   650 					}
   653 					}
   651 				}
   654 				}
   652 			}
   655 			}
       
   656 		} else {
       
   657 			DiagDirection diagdir;
       
   658 			/* New tile */
       
   659 			if (TileX(gp.new_tile) >= MapMaxX() || TileY(gp.new_tile) >= MapMaxY()) {
       
   660 				goto reverse_direction;
       
   661 			}
       
   662 
       
   663 			dir = ShipGetNewDirectionFromTiles(gp.new_tile, gp.old_tile);
       
   664 			assert(dir == DIR_NE || dir == DIR_SE || dir == DIR_SW || dir == DIR_NW);
       
   665 			diagdir = DirToDiagDir(dir);
       
   666 			tracks = GetAvailShipTracks(gp.new_tile, diagdir);
       
   667 			if (tracks == TRACK_BIT_NONE) goto reverse_direction;
       
   668 
       
   669 			/* Choose a direction, and continue if we find one */
       
   670 			track = ChooseShipTrack(v, gp.new_tile, diagdir, tracks);
       
   671 			if (track == INVALID_TRACK) goto reverse_direction;
       
   672 
       
   673 			b = _ship_subcoord[diagdir][track];
       
   674 
       
   675 			gp.x = (gp.x & ~0xF) | b[0];
       
   676 			gp.y = (gp.y & ~0xF) | b[1];
       
   677 
       
   678 			/* Call the landscape function and tell it that the vehicle entered the tile */
       
   679 			r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
       
   680 			if (HasBit(r, VETS_CANNOT_ENTER)) goto reverse_direction;
       
   681 
       
   682 			if (!HasBit(r, VETS_ENTERED_WORMHOLE)) {
       
   683 				v->tile = gp.new_tile;
       
   684 				v->u.ship.state = TrackToTrackBits(track);
       
   685 			}
       
   686 
       
   687 			v->direction = (Direction)b[2];
   653 		}
   688 		}
   654 	} else {
   689 	} else {
   655 		DiagDirection diagdir;
   690 		/* On a bridge */
   656 		/* New tile */
   691 		if (!IsTileType(gp.new_tile, MP_TUNNELBRIDGE) || !HasBit(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) {
   657 		if (TileX(gp.new_tile) >= MapMaxX() || TileY(gp.new_tile) >= MapMaxY()) {
   692 			v->x_pos = gp.x;
   658 			goto reverse_direction;
   693 			v->y_pos = gp.y;
       
   694 			VehiclePositionChanged(v);
       
   695 			if (!(v->vehstatus & VS_HIDDEN)) EndVehicleMove(v);
       
   696 			return;
   659 		}
   697 		}
   660 
       
   661 		dir = ShipGetNewDirectionFromTiles(gp.new_tile, gp.old_tile);
       
   662 		assert(dir == DIR_NE || dir == DIR_SE || dir == DIR_SW || dir == DIR_NW);
       
   663 		diagdir = DirToDiagDir(dir);
       
   664 		tracks = GetAvailShipTracks(gp.new_tile, diagdir);
       
   665 		if (tracks == TRACK_BIT_NONE) goto reverse_direction;
       
   666 
       
   667 		/* Choose a direction, and continue if we find one */
       
   668 		track = ChooseShipTrack(v, gp.new_tile, diagdir, tracks);
       
   669 		if (track == INVALID_TRACK) goto reverse_direction;
       
   670 
       
   671 		b = _ship_subcoord[diagdir][track];
       
   672 
       
   673 		gp.x = (gp.x & ~0xF) | b[0];
       
   674 		gp.y = (gp.y & ~0xF) | b[1];
       
   675 
       
   676 		/* Call the landscape function and tell it that the vehicle entered the tile */
       
   677 		r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
       
   678 		if (HasBit(r, VETS_CANNOT_ENTER)) goto reverse_direction;
       
   679 
       
   680 		if (!HasBit(r, VETS_ENTERED_WORMHOLE)) {
       
   681 			v->tile = gp.new_tile;
       
   682 			v->u.ship.state = TrackToTrackBits(track);
       
   683 		}
       
   684 
       
   685 		v->direction = (Direction)b[2];
       
   686 	}
   698 	}
   687 
   699 
   688 	/* update image of ship, as well as delta XY */
   700 	/* update image of ship, as well as delta XY */
   689 	dir = ShipGetNewDirection(v, gp.x, gp.y);
   701 	dir = ShipGetNewDirection(v, gp.x, gp.y);
   690 	v->x_pos = gp.x;
   702 	v->x_pos = gp.x;