changeset 16511:b9db78828e3d draft

(svn r21237) -Codechange: Move HandleLocomotiveSmokeCloud to Vehicle::ShowVisualEffect (Hirundo)
author rubidium <rubidium@openttd.org>
date Thu, 18 Nov 2010 14:15:27 +0000 (2010-11-18)
parents 1574497fdde6
children 419c2d6ebc51
files src/train_cmd.cpp src/vehicle.cpp src/vehicle_base.h
diffstat 3 files changed, 139 insertions(+), 132 deletions(-) [+]
line wrap: on
line diff
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -1886,137 +1886,6 @@
 	return true;
 }
 
-static const int8 _vehicle_smoke_pos[8] = {
-	1, 1, 1, 0, -1, -1, -1, 0
-};
-
-static void HandleLocomotiveSmokeCloud(const Vehicle *v)
-{
-	assert(v->IsPrimaryVehicle());
-	bool sound = false;
-
-	/* Do not show any smoke when:
-	 * - vehicle smoke is disabled by the player
-	 * - the vehicle is slowing down or stopped (by the player)
-	 * - the vehicle is moving very slowly
-	 */
-	if (_settings_game.vehicle.smoke_amount == 0 ||
-			v->vehstatus & (VS_TRAIN_SLOWING | VS_STOPPED) ||
-			v->cur_speed < 2) {
-		return;
-	}
-	if (v->type == VEH_TRAIN) {
-		const Train *t = Train::From(v);
-		/* For trains, do not show any smoke when:
-		 * - the train is reversing
-		 * - is entering a station with an order to stop there and its speed is equal to maximum station entering speed
-		 */
-		if (HasBit(t->flags, VRF_REVERSING) ||
-				(IsRailStationTile(t->tile) && t->IsFrontEngine() && t->current_order.ShouldStopAtStation(t, GetStationIndex(t->tile)) &&
-				t->cur_speed >= t->Train::GetCurrentMaxSpeed())) {
-			return;
-		}
-	}
-
-	const Vehicle *u = v;
-
-	do {
-		int effect_offset = GB(v->vcache.cached_vis_effect, VE_OFFSET_START, VE_OFFSET_COUNT) - VE_OFFSET_CENTRE;
-		byte effect_type = GB(v->vcache.cached_vis_effect, VE_TYPE_START, VE_TYPE_COUNT);
-		bool disable_effect = HasBit(v->vcache.cached_vis_effect, VE_DISABLE_EFFECT);
-
-		/* Show no smoke when:
-		 * - Smoke has been disabled for this vehicle
-		 * - The vehicle is not visible
-		 * - The vehicle is on a depot tile
-		 * - The vehicle is on a tunnel tile
-		 * - The vehicle is a train engine that is currently unpowered */
-		if (disable_effect ||
-				v->vehstatus & VS_HIDDEN ||
-				IsDepotTile(v->tile) ||
-				IsTunnelTile(v->tile) ||
-				(v->type == VEH_TRAIN &&
-				!HasPowerOnRail(Train::From(v)->railtype, GetTileRailType(v->tile)))) {
-			continue;
-		}
-
-		if (effect_type == VE_TYPE_DEFAULT) {
-			if (v->type == VEH_TRAIN && Train::From(v)->IsEngine()) {
-				/* Use default effect type for engine class. */
-				effect_type = RailVehInfo(v->engine_type)->engclass + 1;
-			} else {
-				/* No default effect exists, so continue */
-				continue;
-			}
-		}
-
-		int x = _vehicle_smoke_pos[v->direction] * effect_offset;
-		int y = _vehicle_smoke_pos[(v->direction + 2) % 8] * effect_offset;
-
-		if (v->type == VEH_TRAIN && HasBit(Train::From(v)->flags, VRF_REVERSE_DIRECTION)) {
-			x = -x;
-			y = -y;
-		}
-
-		switch (effect_type) {
-			case VE_TYPE_STEAM:
-				/* Steam smoke - amount is gradually falling until vehicle reaches its maximum speed, after that it's normal.
-				 * Details: while vehicle's current speed is gradually increasing, steam plumes' density decreases by one third each
-				 * third of its maximum speed spectrum. Steam emission finally normalises at very close to vehicle's maximum speed.
-				 * REGULATION:
-				 * - instead of 1, 4 / 2^smoke_amount (max. 2) is used to provide sufficient regulation to steam puffs' amount. */
-				if (GB(v->tick_counter, 0, ((4 >> _settings_game.vehicle.smoke_amount) + ((u->cur_speed * 3) / u->vcache.cached_max_speed))) == 0) {
-					CreateEffectVehicleRel(v, x, y, 10, EV_STEAM_SMOKE);
-					sound = true;
-				}
-				break;
-
-			case VE_TYPE_DIESEL: {
-				/* Diesel smoke - thicker when vehicle is starting, gradually subsiding till it reaches its maximum speed
-				 * when smoke emission stops.
-				 * Details: Vehicle's (max.) speed spectrum is divided into 32 parts. When max. speed is reached, chance for smoke
-				 * emission erodes by 32 (1/4). For trains, power and weight come in handy too to either increase smoke emission in
-				 * 6 steps (1000HP each) if the power is low or decrease smoke emission in 6 steps (512 tonnes each) if the train
-				 * isn't overweight. Power and weight contributions are expressed in a way that neither extreme power, nor
-				 * extreme weight can ruin the balance (e.g. FreightWagonMultiplier) in the formula. When the vehicle reaches
-				 * maximum speed no diesel_smoke is emitted.
-				 * REGULATION:
-				 * - up to which speed a diesel vehicle is emitting smoke (with reduced/small setting only until 1/2 of max_speed),
-				 * - in Chance16 - the last value is 512 / 2^smoke_amount (max. smoke when 128 = smoke_amount of 2). */
-				int power_weight_effect = 0;
-				if (v->type == VEH_TRAIN) {
-					power_weight_effect = (32 >> (Train::From(u)->acc_cache.cached_power >> 10)) - (32 >> (Train::From(u)->acc_cache.cached_weight >> 9));
-				}
-				if (u->cur_speed < (u->vcache.cached_max_speed >> (2 >> _settings_game.vehicle.smoke_amount)) &&
-						Chance16((64 - ((u->cur_speed << 5) / u->vcache.cached_max_speed) + power_weight_effect), (512 >> _settings_game.vehicle.smoke_amount))) {
-					CreateEffectVehicleRel(v, x, y, 10, EV_DIESEL_SMOKE);
-					sound = true;
-				}
-				break;
-			}
-
-			case VE_TYPE_ELECTRIC:
-				/* Electric train's spark - more often occurs when train is departing (more load)
-				 * Details: Electric locomotives are usually at least twice as powerful as their diesel counterparts, so spark
-				 * emissions are kept simple. Only when starting, creating huge force are sparks more likely to happen, but when
-				 * reaching its max. speed, quarter by quarter of it, chance decreases untill the usuall 2,22% at train's top speed.
-				 * REGULATION:
-				 * - in Chance16 the last value is 360 / 2^smoke_amount (max. sparks when 90 = smoke_amount of 2). */
-				if (GB(v->tick_counter, 0, 2) == 0 &&
-						Chance16((6 - ((u->cur_speed << 2) / u->vcache.cached_max_speed)), (360 >> _settings_game.vehicle.smoke_amount))) {
-					CreateEffectVehicleRel(v, x, y, 10, EV_ELECTRIC_SPARK);
-					sound = true;
-				}
-				break;
-
-			default:
-				break;
-		}
-	} while ((v = v->Next()) != NULL);
-
-	if (sound) PlayVehicleSound(u, VSE_VISUAL_EFFECT);
-}
-
 void Train::PlayLeaveStationSound() const
 {
 	static const SoundFx sfx[] = {
@@ -3722,7 +3591,7 @@
 
 	if (CheckTrainStayInDepot(v)) return true;
 
-	if (!mode) HandleLocomotiveSmokeCloud(v);
+	if (!mode) v->ShowVisualEffect();
 
 	/* We had no order but have an order now, do look ahead. */
 	if (!valid_order && !v->current_order.IsType(OT_NOTHING)) {
--- a/src/vehicle.cpp
+++ b/src/vehicle.cpp
@@ -50,6 +50,8 @@
 #include "effectvehicle_func.h"
 #include "effectvehicle_base.h"
 #include "vehiclelist.h"
+#include "tunnel_map.h"
+#include "depot_map.h"
 
 #include "table/strings.h"
 
@@ -1895,6 +1897,136 @@
 	}
 }
 
+static const int8 _vehicle_smoke_pos[8] = {
+	1, 1, 1, 0, -1, -1, -1, 0
+};
+
+void Vehicle::ShowVisualEffect() const
+{
+	assert(this->IsPrimaryVehicle());
+	bool sound = false;
+
+	/* Do not show any smoke when:
+	 * - vehicle smoke is disabled by the player
+	 * - the vehicle is slowing down or stopped (by the player)
+	 * - the vehicle is moving very slowly
+	 */
+	if (_settings_game.vehicle.smoke_amount == 0 ||
+			this->vehstatus & (VS_TRAIN_SLOWING | VS_STOPPED) ||
+			this->cur_speed < 2) {
+		return;
+	}
+	if (this->type == VEH_TRAIN) {
+		const Train *t = Train::From(this);
+		/* For trains, do not show any smoke when:
+		 * - the train is reversing
+		 * - is entering a station with an order to stop there and its speed is equal to maximum station entering speed
+		 */
+		if (HasBit(t->flags, VRF_REVERSING) ||
+				(IsRailStationTile(t->tile) && t->IsFrontEngine() && t->current_order.ShouldStopAtStation(t, GetStationIndex(t->tile)) &&
+				t->cur_speed >= t->Train::GetCurrentMaxSpeed())) {
+			return;
+		}
+	}
+
+	const Vehicle *v = this;
+
+	do {
+		int effect_offset = GB(v->vcache.cached_vis_effect, VE_OFFSET_START, VE_OFFSET_COUNT) - VE_OFFSET_CENTRE;
+		byte effect_type = GB(v->vcache.cached_vis_effect, VE_TYPE_START, VE_TYPE_COUNT);
+		bool disable_effect = HasBit(v->vcache.cached_vis_effect, VE_DISABLE_EFFECT);
+
+		/* Show no smoke when:
+		 * - Smoke has been disabled for this vehicle
+		 * - The vehicle is not visible
+		 * - The vehicle is on a depot tile
+		 * - The vehicle is on a tunnel tile
+		 * - The vehicle is a train engine that is currently unpowered */
+		if (disable_effect ||
+				v->vehstatus & VS_HIDDEN ||
+				IsDepotTile(v->tile) ||
+				IsTunnelTile(v->tile) ||
+				(v->type == VEH_TRAIN &&
+				!HasPowerOnRail(Train::From(v)->railtype, GetTileRailType(v->tile)))) {
+			continue;
+		}
+
+		if (effect_type == VE_TYPE_DEFAULT) {
+			if (v->type == VEH_TRAIN && Train::From(v)->IsEngine()) {
+				/* Use default effect type for engine class. */
+				effect_type = RailVehInfo(v->engine_type)->engclass + 1;
+			} else {
+				/* No default effect exists, so continue */
+				continue;
+			}
+		}
+
+		int x = _vehicle_smoke_pos[v->direction] * effect_offset;
+		int y = _vehicle_smoke_pos[(v->direction + 2) % 8] * effect_offset;
+
+		if (v->type == VEH_TRAIN && HasBit(Train::From(v)->flags, VRF_REVERSE_DIRECTION)) {
+			x = -x;
+			y = -y;
+		}
+
+		switch (effect_type) {
+			case VE_TYPE_STEAM:
+				/* Steam smoke - amount is gradually falling until vehicle reaches its maximum speed, after that it's normal.
+				 * Details: while vehicle's current speed is gradually increasing, steam plumes' density decreases by one third each
+				 * third of its maximum speed spectrum. Steam emission finally normalises at very close to vehicle's maximum speed.
+				 * REGULATION:
+				 * - instead of 1, 4 / 2^smoke_amount (max. 2) is used to provide sufficient regulation to steam puffs' amount. */
+				if (GB(v->tick_counter, 0, ((4 >> _settings_game.vehicle.smoke_amount) + ((this->cur_speed * 3) / this->vcache.cached_max_speed))) == 0) {
+					CreateEffectVehicleRel(v, x, y, 10, EV_STEAM_SMOKE);
+					sound = true;
+				}
+				break;
+
+			case VE_TYPE_DIESEL: {
+				/* Diesel smoke - thicker when vehicle is starting, gradually subsiding till it reaches its maximum speed
+				 * when smoke emission stops.
+				 * Details: Vehicle's (max.) speed spectrum is divided into 32 parts. When max. speed is reached, chance for smoke
+				 * emission erodes by 32 (1/4). For trains, power and weight come in handy too to either increase smoke emission in
+				 * 6 steps (1000HP each) if the power is low or decrease smoke emission in 6 steps (512 tonnes each) if the train
+				 * isn't overweight. Power and weight contributions are expressed in a way that neither extreme power, nor
+				 * extreme weight can ruin the balance (e.g. FreightWagonMultiplier) in the formula. When the vehicle reaches
+				 * maximum speed no diesel_smoke is emitted.
+				 * REGULATION:
+				 * - up to which speed a diesel vehicle is emitting smoke (with reduced/small setting only until 1/2 of max_speed),
+				 * - in Chance16 - the last value is 512 / 2^smoke_amount (max. smoke when 128 = smoke_amount of 2). */
+				int power_weight_effect = 0;
+				if (v->type == VEH_TRAIN) {
+					power_weight_effect = (32 >> (Train::From(this)->acc_cache.cached_power >> 10)) - (32 >> (Train::From(this)->acc_cache.cached_weight >> 9));
+				}
+				if (this->cur_speed < (this->vcache.cached_max_speed >> (2 >> _settings_game.vehicle.smoke_amount)) &&
+						Chance16((64 - ((this->cur_speed << 5) / this->vcache.cached_max_speed) + power_weight_effect), (512 >> _settings_game.vehicle.smoke_amount))) {
+					CreateEffectVehicleRel(v, x, y, 10, EV_DIESEL_SMOKE);
+					sound = true;
+				}
+				break;
+			}
+
+			case VE_TYPE_ELECTRIC:
+				/* Electric train's spark - more often occurs when train is departing (more load)
+				 * Details: Electric locomotives are usually at least twice as powerful as their diesel counterparts, so spark
+				 * emissions are kept simple. Only when starting, creating huge force are sparks more likely to happen, but when
+				 * reaching its max. speed, quarter by quarter of it, chance decreases untill the usuall 2,22% at train's top speed.
+				 * REGULATION:
+				 * - in Chance16 the last value is 360 / 2^smoke_amount (max. sparks when 90 = smoke_amount of 2). */
+				if (GB(v->tick_counter, 0, 2) == 0 &&
+						Chance16((6 - ((this->cur_speed << 2) / this->vcache.cached_max_speed)), (360 >> _settings_game.vehicle.smoke_amount))) {
+					CreateEffectVehicleRel(v, x, y, 10, EV_ELECTRIC_SPARK);
+					sound = true;
+				}
+				break;
+
+			default:
+				break;
+		}
+	} while ((v = v->Next()) != NULL);
+
+	if (sound) PlayVehicleSound(this, VSE_VISUAL_EFFECT);
+}
 
 void Vehicle::SetNext(Vehicle *next)
 {
--- a/src/vehicle_base.h
+++ b/src/vehicle_base.h
@@ -618,6 +618,12 @@
 	 */
 	void UpdateVisualEffect(bool allow_power_change = true);
 
+	/*
+	 * Draw visual effects (smoke and/or sparks) for a vehicle chain.
+	 * @pre this->IsPrimaryVehicle()
+	 */
+	void ShowVisualEffect() const;
+
 	/**
 	 * Increments cur_order_index, keeps care of the wrap-around and invalidates the GUI.
 	 * Note: current_order is not invalidated.