changeset 15956:cc4575d99aa1 draft

(svn r20644) -Codechange [FS#4086]: unify the vehicle breakdown code (Hirundo)
author rubidium <rubidium@openttd.org>
date Sat, 28 Aug 2010 14:01:50 +0000
parents a1603ce88b25
children 1452fca58b4f
files src/aircraft_cmd.cpp src/roadveh_cmd.cpp src/ship_cmd.cpp src/train_cmd.cpp src/vehicle.cpp src/vehicle_base.h
diffstat 6 files changed, 63 insertions(+), 124 deletions(-) [+]
line wrap: on
line diff
--- a/src/aircraft_cmd.cpp
+++ b/src/aircraft_cmd.cpp
@@ -1038,20 +1038,6 @@
 	return true;
 }
 
-static void HandleBrokenAircraft(Aircraft *v)
-{
-	if (v->breakdown_ctr != 1) {
-		v->breakdown_ctr = 1;
-		v->vehstatus |= VS_AIRCRAFT_BROKEN;
-
-		if (v->breakdowns_since_last_service != 255) {
-			v->breakdowns_since_last_service++;
-		}
-		SetWindowDirty(WC_VEHICLE_VIEW, v->index);
-		SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
-	}
-}
-
 
 static void HandleAircraftSmoke(Aircraft *v)
 {
@@ -1792,7 +1778,7 @@
 	/* aircraft is broken down? */
 	if (v->breakdown_ctr != 0) {
 		if (v->breakdown_ctr <= 2) {
-			HandleBrokenAircraft(v);
+			v->HandleBreakdown();
 		} else {
 			if (!v->current_order.IsType(OT_LOADING)) v->breakdown_ctr--;
 		}
--- a/src/roadveh_cmd.cpp
+++ b/src/roadveh_cmd.cpp
@@ -31,7 +31,6 @@
 #include "ai/ai.hpp"
 #include "depot_map.h"
 #include "effectvehicle_func.h"
-#include "effectvehicle_base.h"
 #include "roadstop_base.h"
 #include "spritecache.h"
 #include "core/random_func.hpp"
@@ -532,40 +531,6 @@
 	return false;
 }
 
-static void HandleBrokenRoadVeh(RoadVehicle *v)
-{
-	if (v->breakdown_ctr != 1) {
-		v->breakdown_ctr = 1;
-		v->cur_speed = 0;
-
-		if (v->breakdowns_since_last_service != 255) {
-			v->breakdowns_since_last_service++;
-		}
-
-		v->MarkDirty();
-		SetWindowDirty(WC_VEHICLE_VIEW, v->index);
-		SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
-
-		if (!PlayVehicleSound(v, VSE_BREAKDOWN)) {
-			SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ?
-				SND_0F_VEHICLE_BREAKDOWN : SND_35_COMEDY_BREAKDOWN, v);
-		}
-
-		if (!(v->vehstatus & VS_HIDDEN)) {
-			EffectVehicle *u = CreateEffectVehicleRel(v, 4, 4, 5, EV_BREAKDOWN_SMOKE);
-			if (u != NULL) u->animation_state = v->breakdown_delay * 2;
-		}
-	}
-
-	if ((v->tick_counter & 1) == 0) {
-		if (--v->breakdown_delay == 0) {
-			v->breakdown_ctr = 0;
-			v->MarkDirty();
-			SetWindowDirty(WC_VEHICLE_VIEW, v->index);
-		}
-	}
-}
-
 TileIndex RoadVehicle::GetOrderStationLocation(StationID station)
 {
 	if (station == this->last_station_visited) this->last_station_visited = INVALID_STATION;
@@ -1522,7 +1487,7 @@
 	/* road vehicle has broken down? */
 	if (v->breakdown_ctr != 0) {
 		if (v->breakdown_ctr <= 2) {
-			HandleBrokenRoadVeh(v);
+			v->HandleBreakdown();
 			return true;
 		}
 		if (!v->current_order.IsType(OT_LOADING)) v->breakdown_ctr--;
--- a/src/ship_cmd.cpp
+++ b/src/ship_cmd.cpp
@@ -30,8 +30,6 @@
 #include "date_func.h"
 #include "vehicle_func.h"
 #include "sound_func.h"
-#include "effectvehicle_func.h"
-#include "effectvehicle_base.h"
 #include "ai/ai.hpp"
 #include "pathfinder/opf/opf_ship.h"
 #include "landscape_type.h"
@@ -205,40 +203,6 @@
 	return TrackDirectionToTrackdir(FindFirstTrack(this->state), this->direction);
 }
 
-static void HandleBrokenShip(Vehicle *v)
-{
-	if (v->breakdown_ctr != 1) {
-		v->breakdown_ctr = 1;
-		v->cur_speed = 0;
-
-		if (v->breakdowns_since_last_service != 255) {
-			v->breakdowns_since_last_service++;
-		}
-
-		v->MarkDirty();
-		SetWindowDirty(WC_VEHICLE_VIEW, v->index);
-		SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
-
-		if (!PlayVehicleSound(v, VSE_BREAKDOWN)) {
-			SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ?
-				SND_10_TRAIN_BREAKDOWN : SND_3A_COMEDY_BREAKDOWN_2, v);
-		}
-
-		if (!(v->vehstatus & VS_HIDDEN)) {
-			EffectVehicle *u = CreateEffectVehicleRel(v, 4, 4, 5, EV_BREAKDOWN_SMOKE);
-			if (u != NULL) u->animation_state = v->breakdown_delay * 2;
-		}
-	}
-
-	if (!(v->tick_counter & 1)) {
-		if (!--v->breakdown_delay) {
-			v->breakdown_ctr = 0;
-			v->MarkDirty();
-			SetWindowDirty(WC_VEHICLE_VIEW, v->index);
-		}
-	}
-}
-
 void Ship::MarkDirty()
 {
 	this->UpdateViewport(false, false);
@@ -462,7 +426,7 @@
 
 	if (v->breakdown_ctr != 0) {
 		if (v->breakdown_ctr <= 2) {
-			HandleBrokenShip(v);
+			v->HandleBreakdown();
 			return;
 		}
 		if (!v->current_order.IsType(OT_LOADING)) v->breakdown_ctr--;
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -29,7 +29,6 @@
 #include "ai/ai.hpp"
 #include "newgrf_station.h"
 #include "effectvehicle_func.h"
-#include "effectvehicle_base.h"
 #include "gamelog.h"
 #include "network/network.h"
 #include "spritecache.h"
@@ -3543,40 +3542,6 @@
 	return true;
 }
 
-static void HandleBrokenTrain(Train *v)
-{
-	if (v->breakdown_ctr != 1) {
-		v->breakdown_ctr = 1;
-		v->cur_speed = 0;
-
-		if (v->breakdowns_since_last_service != 255) {
-			v->breakdowns_since_last_service++;
-		}
-
-		v->MarkDirty();
-		SetWindowDirty(WC_VEHICLE_VIEW, v->index);
-		SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
-
-		if (!PlayVehicleSound(v, VSE_BREAKDOWN)) {
-			SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ?
-				SND_10_TRAIN_BREAKDOWN : SND_3A_COMEDY_BREAKDOWN_2, v);
-		}
-
-		if (!(v->vehstatus & VS_HIDDEN)) {
-			EffectVehicle *u = CreateEffectVehicleRel(v, 4, 4, 5, EV_BREAKDOWN_SMOKE);
-			if (u != NULL) u->animation_state = v->breakdown_delay * 2;
-		}
-	}
-
-	if (!(v->tick_counter & 3)) {
-		if (!--v->breakdown_delay) {
-			v->breakdown_ctr = 0;
-			v->MarkDirty();
-			SetWindowDirty(WC_VEHICLE_VIEW, v->index);
-		}
-	}
-}
-
 /** Maximum speeds for train that is broken down or approaching line end */
 static const uint16 _breakdown_speeds[16] = {
 	225, 210, 195, 180, 165, 150, 135, 120, 105, 90, 75, 60, 45, 30, 15, 15
@@ -3753,7 +3718,7 @@
 	/* train is broken down? */
 	if (v->breakdown_ctr != 0) {
 		if (v->breakdown_ctr <= 2) {
-			HandleBrokenTrain(v);
+			v->HandleBreakdown();
 			return true;
 		}
 		if (!v->current_order.IsType(OT_LOADING)) v->breakdown_ctr--;
--- a/src/vehicle.cpp
+++ b/src/vehicle.cpp
@@ -46,6 +46,9 @@
 #include "core/random_func.hpp"
 #include "core/backup_type.hpp"
 #include "order_backup.h"
+#include "sound_func.h"
+#include "effectvehicle_func.h"
+#include "effectvehicle_base.h"
 
 #include "table/strings.h"
 
@@ -983,6 +986,56 @@
 	}
 }
 
+void Vehicle::HandleBreakdown()
+{
+	/* Possible states for Vehicle::breakdown_ctr
+	 * 0  - vehicle is running normally
+	 * 1  - vehicle is currently broken down
+	 * 2  - vehicle is going to break down now
+	 * >2 - vehicle is counting down to the actual breakdown event */
+	if (this->breakdown_ctr != 1) {
+		this->breakdown_ctr = 1;
+
+		if (this->breakdowns_since_last_service != 255) {
+			this->breakdowns_since_last_service++;
+		}
+
+		this->MarkDirty();
+		SetWindowDirty(WC_VEHICLE_VIEW, this->index);
+		SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
+
+		if (this->type == VEH_AIRCRAFT) {
+			/* Aircraft just need this flag, the rest is handled elsewhere */
+			this->vehstatus |= VS_AIRCRAFT_BROKEN;
+		} else {
+			this->cur_speed = 0;
+
+			if (!PlayVehicleSound(this, VSE_BREAKDOWN)) {
+				SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ?
+					(this->type == VEH_TRAIN ? SND_10_TRAIN_BREAKDOWN : SND_0F_VEHICLE_BREAKDOWN) :
+					(this->type == VEH_TRAIN ? SND_3A_COMEDY_BREAKDOWN_2 : SND_35_COMEDY_BREAKDOWN), this);
+			}
+
+			if (!(this->vehstatus & VS_HIDDEN)) {
+				EffectVehicle *u = CreateEffectVehicleRel(this, 4, 4, 5, EV_BREAKDOWN_SMOKE);
+				if (u != NULL) u->animation_state = this->breakdown_delay * 2;
+			}
+		}
+	}
+
+	/* Aircraft breakdowns end only when arriving at the airport */
+	if (this->type == VEH_AIRCRAFT) return;
+
+	/* For trains this function is called twice per tick, so decrease v->breakdown_delay at half the rate */
+	if ((this->tick_counter & (this->type == VEH_TRAIN ? 3 : 1)) == 0) {
+		if (--this->breakdown_delay == 0) {
+			this->breakdown_ctr = 0;
+			this->MarkDirty();
+			SetWindowDirty(WC_VEHICLE_VIEW, this->index);
+		}
+	}
+}
+
 void AgeVehicle(Vehicle *v)
 {
 	if (v->age < MAX_DAY) v->age++;
--- a/src/vehicle_base.h
+++ b/src/vehicle_base.h
@@ -523,6 +523,12 @@
 		this->service_interval = src->service_interval;
 	}
 
+	/**
+	 * Handle all of the aspects of a vehicle breakdown.
+	 * This includes adding smoke and sounds, and ending the breakdown when appropriate.
+	 */
+	void HandleBreakdown();
+
 	bool NeedsAutorenewing(const Company *c) const;
 
 	/**