src/vehicle.cpp
branchnoai
changeset 10645 8cbdb511a674
parent 10513 33cb70ff2f5d
child 10715 6bdf79ffb022
equal deleted inserted replaced
10644:6c4314786d68 10645:8cbdb511a674
   589 	 *  other artic parts. */
   589 	 *  other artic parts. */
   590 	if ((this->type == VEH_TRAIN && EngineHasArticPart(this)) || (this->type == VEH_ROAD && RoadVehHasArticPart(this))) {
   590 	if ((this->type == VEH_TRAIN && EngineHasArticPart(this)) || (this->type == VEH_ROAD && RoadVehHasArticPart(this))) {
   591 		delete this->Next();
   591 		delete this->Next();
   592 	}
   592 	}
   593 
   593 
   594 	Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
   594 	extern void StopGlobalFollowVehicle(const Vehicle *v);
   595 	if (w != NULL && w->viewport->follow_vehicle == this->index) {
   595 	StopGlobalFollowVehicle(this);
   596 		ScrollMainWindowTo(this->x_pos, this->y_pos, true); // lock the main view on the vehicle's last position
       
   597 		w->viewport->follow_vehicle = INVALID_VEHICLE;
       
   598 	}
       
   599 }
   596 }
   600 
   597 
   601 Vehicle::~Vehicle()
   598 Vehicle::~Vehicle()
   602 {
   599 {
   603 	free(this->name);
   600 	free(this->name);
   951 	/* Do not show getting-old message if autorenew is active (and it can replace the vehicle) */
   948 	/* Do not show getting-old message if autorenew is active (and it can replace the vehicle) */
   952 	if (GetPlayer(v->owner)->engine_renew && GetEngine(v->engine_type)->player_avail != 0) return;
   949 	if (GetPlayer(v->owner)->engine_renew && GetEngine(v->engine_type)->player_avail != 0) return;
   953 
   950 
   954 	SetDParam(0, _vehicle_type_names[v->type]);
   951 	SetDParam(0, _vehicle_type_names[v->type]);
   955 	SetDParam(1, v->unitnumber);
   952 	SetDParam(1, v->unitnumber);
   956 	AddNewsItem(msg, NM_SMALL, NF_VIEWPORT | NF_VEHICLE, NT_ADVICE, DNC_NONE, v->index, 0);
   953 	AddNewsItem(msg, NS_ADVICE, v->index, 0);
   957 }
   954 }
   958 
   955 
   959 void AgeVehicle(Vehicle *v)
   956 void AgeVehicle(Vehicle *v)
   960 {
   957 {
   961 	if (v->age < 65535) v->age++;
   958 	if (v->age < 65535) v->age++;
  1551  * Calculates how full a vehicle is.
  1548  * Calculates how full a vehicle is.
  1552  * @param v The Vehicle to check. For trains, use the first engine.
  1549  * @param v The Vehicle to check. For trains, use the first engine.
  1553  * @param color The string to show depending on if we are unloading or loading
  1550  * @param color The string to show depending on if we are unloading or loading
  1554  * @return A percentage of how full the Vehicle is.
  1551  * @return A percentage of how full the Vehicle is.
  1555  */
  1552  */
  1556 uint8 CalcPercentVehicleFilled(Vehicle *v, StringID *color)
  1553 uint8 CalcPercentVehicleFilled(const Vehicle *v, StringID *color)
  1557 {
  1554 {
  1558 	int count = 0;
  1555 	int count = 0;
  1559 	int max = 0;
  1556 	int max = 0;
  1560 	int cars = 0;
  1557 	int cars = 0;
  1561 	int unloading = 0;
  1558 	int unloading = 0;
  1650 				v->leave_depot_instantly = false; // We ensure that the vehicle stays in the depot
  1647 				v->leave_depot_instantly = false; // We ensure that the vehicle stays in the depot
  1651 				if (v->owner == _local_player) {
  1648 				if (v->owner == _local_player) {
  1652 					/* Notify the user that we stopped the vehicle */
  1649 					/* Notify the user that we stopped the vehicle */
  1653 					SetDParam(0, _vehicle_type_names[v->type]);
  1650 					SetDParam(0, _vehicle_type_names[v->type]);
  1654 					SetDParam(1, v->unitnumber);
  1651 					SetDParam(1, v->unitnumber);
  1655 					AddNewsItem(STR_ORDER_REFIT_FAILED, NM_SMALL, NF_VIEWPORT | NF_VEHICLE, NT_ADVICE, DNC_NONE, v->index, 0);
  1652 					AddNewsItem(STR_ORDER_REFIT_FAILED, NS_ADVICE, v->index, 0);
  1656 				}
  1653 				}
  1657 			} else if (v->owner == _local_player && cost.GetCost() != 0) {
  1654 			} else if (v->owner == _local_player && cost.GetCost() != 0) {
  1658 				ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost.GetCost());
  1655 				ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost.GetCost());
  1659 			}
  1656 			}
  1660 		}
  1657 		}
  1676 					case VEH_AIRCRAFT: string = STR_A014_AIRCRAFT_IS_WAITING_IN;    break;
  1673 					case VEH_AIRCRAFT: string = STR_A014_AIRCRAFT_IS_WAITING_IN;    break;
  1677 					default: NOT_REACHED(); string = STR_EMPTY; // Set the string to something to avoid a compiler warning
  1674 					default: NOT_REACHED(); string = STR_EMPTY; // Set the string to something to avoid a compiler warning
  1678 				}
  1675 				}
  1679 
  1676 
  1680 				SetDParam(0, v->unitnumber);
  1677 				SetDParam(0, v->unitnumber);
  1681 				AddNewsItem(string, NM_SMALL, NF_VIEWPORT | NF_VEHICLE, NT_ADVICE, DNC_NONE, v->index, 0);
  1678 				AddNewsItem(string, NS_ADVICE, v->index, 0);
  1682 			}
  1679 			}
  1683 			AI_Event(v->owner, new AIEventVehicleWaitingInDepot(v->index));
  1680 			AI_Event(v->owner, new AIEventVehicleWaitingInDepot(v->index));
  1684 		}
  1681 		}
  1685 	}
  1682 	}
  1686 }
  1683 }
  1736 	if (!IsUniqueVehicleName(_cmd_text)) return_cmd_error(STR_NAME_MUST_BE_UNIQUE);
  1733 	if (!IsUniqueVehicleName(_cmd_text)) return_cmd_error(STR_NAME_MUST_BE_UNIQUE);
  1737 
  1734 
  1738 	if (flags & DC_EXEC) {
  1735 	if (flags & DC_EXEC) {
  1739 		free(v->name);
  1736 		free(v->name);
  1740 		v->name = strdup(_cmd_text);
  1737 		v->name = strdup(_cmd_text);
  1741 		ResortVehicleLists();
  1738 		InvalidateWindowClassesData(WC_TRAINS_LIST, 1);
  1742 		MarkWholeScreenDirty();
  1739 		MarkWholeScreenDirty();
  1743 	}
  1740 	}
  1744 
  1741 
  1745 	return CommandCost();
  1742 	return CommandCost();
  1746 }
  1743 }
  1867 	if (v->vehstatus & VS_CRASHED) return INVALID_TRACKDIR;
  1864 	if (v->vehstatus & VS_CRASHED) return INVALID_TRACKDIR;
  1868 
  1865 
  1869 	switch (v->type) {
  1866 	switch (v->type) {
  1870 		case VEH_TRAIN:
  1867 		case VEH_TRAIN:
  1871 			if (v->u.rail.track == TRACK_BIT_DEPOT) // We'll assume the train is facing outwards
  1868 			if (v->u.rail.track == TRACK_BIT_DEPOT) // We'll assume the train is facing outwards
  1872 				return DiagdirToDiagTrackdir(GetRailDepotDirection(v->tile)); // Train in depot
  1869 				return DiagDirToDiagTrackdir(GetRailDepotDirection(v->tile)); // Train in depot
  1873 
  1870 
  1874 			if (v->u.rail.track == TRACK_BIT_WORMHOLE) // train in tunnel, so just use his direction and assume a diagonal track
  1871 			if (v->u.rail.track == TRACK_BIT_WORMHOLE) // train in tunnel, so just use his direction and assume a diagonal track
  1875 				return DiagdirToDiagTrackdir(DirToDiagDir(v->direction));
  1872 				return DiagDirToDiagTrackdir(DirToDiagDir(v->direction));
  1876 
  1873 
  1877 			return TrackDirectionToTrackdir(FindFirstTrack(v->u.rail.track), v->direction);
  1874 			return TrackDirectionToTrackdir(FindFirstTrack(v->u.rail.track), v->direction);
  1878 
  1875 
  1879 		case VEH_SHIP:
  1876 		case VEH_SHIP:
  1880 			if (v->IsInDepot())
  1877 			if (v->IsInDepot())
  1881 				// We'll assume the ship is facing outwards
  1878 				// We'll assume the ship is facing outwards
  1882 				return DiagdirToDiagTrackdir(GetShipDepotDirection(v->tile));
  1879 				return DiagDirToDiagTrackdir(GetShipDepotDirection(v->tile));
  1883 
  1880 
  1884 			return TrackDirectionToTrackdir(FindFirstTrack(v->u.ship.state), v->direction);
  1881 			return TrackDirectionToTrackdir(FindFirstTrack(v->u.ship.state), v->direction);
  1885 
  1882 
  1886 		case VEH_ROAD:
  1883 		case VEH_ROAD:
  1887 			if (v->IsInDepot()) // We'll assume the road vehicle is facing outwards
  1884 			if (v->IsInDepot()) // We'll assume the road vehicle is facing outwards
  1888 				return DiagdirToDiagTrackdir(GetRoadDepotDirection(v->tile));
  1885 				return DiagDirToDiagTrackdir(GetRoadDepotDirection(v->tile));
  1889 
  1886 
  1890 			if (IsStandardRoadStopTile(v->tile)) // We'll assume the road vehicle is facing outwards
  1887 			if (IsStandardRoadStopTile(v->tile)) // We'll assume the road vehicle is facing outwards
  1891 				return DiagdirToDiagTrackdir(GetRoadStopDir(v->tile)); // Road vehicle in a station
  1888 				return DiagDirToDiagTrackdir(GetRoadStopDir(v->tile)); // Road vehicle in a station
  1892 
  1889 
  1893 			if (IsDriveThroughStopTile(v->tile)) return DiagdirToDiagTrackdir(DirToDiagDir(v->direction));
  1890 			if (IsDriveThroughStopTile(v->tile)) return DiagDirToDiagTrackdir(DirToDiagDir(v->direction));
  1894 
  1891 
  1895 			/* If vehicle's state is a valid track direction (vehicle is not turning around) return it */
  1892 			/* If vehicle's state is a valid track direction (vehicle is not turning around) return it */
  1896 			if (!IsReversingRoadTrackdir((Trackdir)v->u.road.state)) return (Trackdir)v->u.road.state;
  1893 			if (!IsReversingRoadTrackdir((Trackdir)v->u.road.state)) return (Trackdir)v->u.road.state;
  1897 
  1894 
  1898 			/* Vehicle is turning around, get the direction from vehicle's direction */
  1895 			/* Vehicle is turning around, get the direction from vehicle's direction */
  1899 			return DiagdirToDiagTrackdir(DirToDiagDir(v->direction));
  1896 			return DiagDirToDiagTrackdir(DirToDiagDir(v->direction));
  1900 
  1897 
  1901 		/* case VEH_AIRCRAFT: case VEH_EFFECT: case VEH_DISASTER: */
  1898 		/* case VEH_AIRCRAFT: case VEH_EFFECT: case VEH_DISASTER: */
  1902 		default: return INVALID_TRACKDIR;
  1899 		default: return INVALID_TRACKDIR;
  1903 	}
  1900 	}
  1904 }
  1901 }
  2757 		/* The vehicle should be free since we are restoring something we just sold. */
  2754 		/* The vehicle should be free since we are restoring something we just sold. */
  2758 		assert(!dest->IsValid());
  2755 		assert(!dest->IsValid());
  2759 		memcpy(dest, backup, sizeof(Vehicle));
  2756 		memcpy(dest, backup, sizeof(Vehicle));
  2760 
  2757 
  2761 		/* We decreased the engine count when we sold the engines so we will increase it again. */
  2758 		/* We decreased the engine count when we sold the engines so we will increase it again. */
  2762 		if (IsEngineCountable(backup)) p->num_engines[backup->engine_type]++;
  2759 		if (IsEngineCountable(backup)) {
       
  2760 			p->num_engines[backup->engine_type]++;
       
  2761 			if (IsValidGroupID(backup->group_id)) GetGroup(backup->group_id)->num_engines[backup->engine_type]++;
       
  2762 			if (backup->IsPrimaryVehicle()) IncreaseGroupNumVehicle(backup->group_id);
       
  2763 		}
  2763 
  2764 
  2764 		/* Update hash. */
  2765 		/* Update hash. */
  2765 		Vehicle *dummy = dest;
  2766 		Vehicle *dummy = dest;
  2766 		dest->old_new_hash = &dummy;
  2767 		dest->old_new_hash = &dummy;
  2767 		dest->left_coord = INVALID_COORD;
  2768 		dest->left_coord = INVALID_COORD;
  2804  */
  2805  */
  2805 Vehicle *BackuppedVehicle::Restore(Vehicle *v, Player *p)
  2806 Vehicle *BackuppedVehicle::Restore(Vehicle *v, Player *p)
  2806 {
  2807 {
  2807 	if (!ContainsBackup()) return v;
  2808 	if (!ContainsBackup()) return v;
  2808 	if (v != NULL) {
  2809 	if (v != NULL) {
  2809 		ChangeVehicleViewWindow(v, INVALID_VEHICLE);
  2810 		ChangeVehicleViewWindow(v->index, INVALID_VEHICLE);
  2810 		DoCommand(0, v->index, 1, DC_EXEC, GetCmdSellVeh(v));
  2811 		DoCommand(0, v->index, 1, DC_EXEC, GetCmdSellVeh(v));
  2811 	}
  2812 	}
  2812 	v = RestoreBackupVehicle(this->vehicles, p);
  2813 	v = RestoreBackupVehicle(this->vehicles, p);
  2813 	ChangeVehicleViewWindow(INVALID_VEHICLE, v);
  2814 	ChangeVehicleViewWindow(INVALID_VEHICLE, v->index);
  2814 	if (orders != NULL) RestoreVehicleOrdersBruteForce(v, orders);
  2815 	if (orders != NULL) RestoreVehicleOrdersBruteForce(v, orders);
  2815 	if (economy != NULL) economy->Restore();
  2816 	if (economy != NULL) economy->Restore();
  2816 	/* If we stored cargo as well then we should restore it. */
  2817 	/* If we stored cargo as well then we should restore it. */
  2817 	cargo_packets->RestoreBackup();
  2818 	cargo_packets->RestoreBackup();
  2818 	return v;
  2819 	return v;