(svn r7592) -Feature: Add support for tractive effort to 'realistic' acceleration.
This commit is contained in:
		
							
								
								
									
										1
									
								
								engine.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								engine.h
									
									
									
									
									
								
							| @@ -27,6 +27,7 @@ typedef struct RailVehicleInfo { | |||||||
| 	                    //       kind of visual effect to generate for a vehicle (default, steam, diesel, electric). | 	                    //       kind of visual effect to generate for a vehicle (default, steam, diesel, electric). | ||||||
| 	                    //       Same goes for the callback result, which atm is only used to check if a wagon is powered. | 	                    //       Same goes for the callback result, which atm is only used to check if a wagon is powered. | ||||||
| 	byte shorten_factor; // length on main map for this type is 8 - shorten_factor | 	byte shorten_factor; // length on main map for this type is 8 - shorten_factor | ||||||
|  | 	byte tractive_effort; ///< Tractive effort coefficient | ||||||
| 	byte user_def_data; ///! Property 0x25: "User-defined bit mask" Used only for (very few) NewGRF vehicles | 	byte user_def_data; ///! Property 0x25: "User-defined bit mask" Used only for (very few) NewGRF vehicles | ||||||
| } RailVehicleInfo; | } RailVehicleInfo; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2604,6 +2604,7 @@ STR_VEHICLE_INFO_COST_WEIGHT_SPEED_POWER                        :{BLACK}Cost: {C | |||||||
| STR_885C_BROKEN_DOWN                                            :{RED}Broken down | STR_885C_BROKEN_DOWN                                            :{RED}Broken down | ||||||
| STR_885D_AGE_RUNNING_COST_YR                                    :{BLACK}Age: {LTBLUE}{STRING2}{BLACK}   Running Cost: {LTBLUE}{CURRENCY}/yr | STR_885D_AGE_RUNNING_COST_YR                                    :{BLACK}Age: {LTBLUE}{STRING2}{BLACK}   Running Cost: {LTBLUE}{CURRENCY}/yr | ||||||
| STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED                         :{BLACK}Weight: {LTBLUE}{WEIGHT_S}  {BLACK}Power: {LTBLUE}{POWER}{BLACK} Max. speed: {LTBLUE}{VELOCITY} | STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED                         :{BLACK}Weight: {LTBLUE}{WEIGHT_S}  {BLACK}Power: {LTBLUE}{POWER}{BLACK} Max. speed: {LTBLUE}{VELOCITY} | ||||||
|  | STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE                  :{BLACK}Weight: {LTBLUE}{WEIGHT_S} {BLACK}Power: {LTBLUE}{POWER}{BLACK} Max. speed: {LTBLUE}{VELOCITY} {BLACK}Max. T.E.: {LTBLUE}{FORCE} | ||||||
| STR_885F_PROFIT_THIS_YEAR_LAST_YEAR                             :{BLACK}Profit this year: {LTBLUE}{CURRENCY}  (last year: {CURRENCY}) | STR_885F_PROFIT_THIS_YEAR_LAST_YEAR                             :{BLACK}Profit this year: {LTBLUE}{CURRENCY}  (last year: {CURRENCY}) | ||||||
| STR_8860_RELIABILITY_BREAKDOWNS                                 :{BLACK}Reliability: {LTBLUE}{COMMA}%  {BLACK}Breakdowns since last service: {LTBLUE}{COMMA} | STR_8860_RELIABILITY_BREAKDOWNS                                 :{BLACK}Reliability: {LTBLUE}{COMMA}%  {BLACK}Breakdowns since last service: {LTBLUE}{COMMA} | ||||||
| STR_8861_STOPPED                                                :{RED}Stopped | STR_8861_STOPPED                                                :{RED}Stopped | ||||||
| @@ -3045,6 +3046,7 @@ STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT                          :{BLACK}Powered | |||||||
| STR_PURCHASE_INFO_REFITTABLE_TO                                 :{BLACK}Refittable to: {GOLD} | STR_PURCHASE_INFO_REFITTABLE_TO                                 :{BLACK}Refittable to: {GOLD} | ||||||
| STR_PURCHASE_INFO_ALL_TYPES                                     :All cargo types | STR_PURCHASE_INFO_ALL_TYPES                                     :All cargo types | ||||||
| STR_PURCHASE_INFO_ALL_BUT                                       :All but {GOLD} | STR_PURCHASE_INFO_ALL_BUT                                       :All but {GOLD} | ||||||
|  | STR_PURCHASE_INFO_MAX_TE                                        :{BLACK}Max. Tractive Effort: {GOLD}{FORCE} | ||||||
|  |  | ||||||
| ########### String for New Landscape Generator | ########### String for New Landscape Generator | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								newgrf.c
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								newgrf.c
									
									
									
									
									
								
							| @@ -416,6 +416,10 @@ static bool RailVehicleChangeInfo(uint engine, int numinfo, int prop, byte **buf | |||||||
| 			FOR_EACH_OBJECT ei[i].callbackmask = grf_load_byte(&buf); | 			FOR_EACH_OBJECT ei[i].callbackmask = grf_load_byte(&buf); | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
|  | 		case 0x1F: /* Tractive effort coefficient */ | ||||||
|  | 			FOR_EACH_OBJECT rvi[i].tractive_effort = grf_load_byte(&buf); | ||||||
|  | 			break; | ||||||
|  |  | ||||||
| 		case 0x21: /* Shorter vehicle */ | 		case 0x21: /* Shorter vehicle */ | ||||||
| 			FOR_EACH_OBJECT rvi[i].shorten_factor = grf_load_byte(&buf); | 			FOR_EACH_OBJECT rvi[i].shorten_factor = grf_load_byte(&buf); | ||||||
| 			break; | 			break; | ||||||
| @@ -466,7 +470,6 @@ static bool RailVehicleChangeInfo(uint engine, int numinfo, int prop, byte **buf | |||||||
|  |  | ||||||
| 		/* TODO */ | 		/* TODO */ | ||||||
| 		/* Fall-through for unimplemented one byte long properties. */ | 		/* Fall-through for unimplemented one byte long properties. */ | ||||||
| 		case 0x1F: /* Tractive effort */ |  | ||||||
| 		case 0x20: /* Air drag */ | 		case 0x20: /* Air drag */ | ||||||
| 		case 0x26: /* Retire vehicle early */ | 		case 0x26: /* Retire vehicle early */ | ||||||
| 			/* TODO */ | 			/* TODO */ | ||||||
| @@ -3692,3 +3695,4 @@ void LoadNewGRF(uint load_index, uint file_index) | |||||||
| 	CalculateRefitMasks(); | 	CalculateRefitMasks(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -341,8 +341,9 @@ const EngineInfo orig_engine_info[] = { | |||||||
|  * @param i capacity |  * @param i capacity | ||||||
|  * @param j cargo_type |  * @param j cargo_type | ||||||
|  * @param k ai_rank |  * @param k ai_rank | ||||||
|  |  * Tractive effort coefficient by default is the same as TTDPatch, 0.30*256=76 | ||||||
|  */ |  */ | ||||||
| #define RVI(a, b, c, d, e, f, g, h, i, j, k) { a, b, c, d, e, f, g, h, h, i, j, k, 0, 0, 0, 0, 0 } | #define RVI(a, b, c, d, e, f, g, h, i, j, k) { a, b, c, d, e, f, g, h, h, i, j, k, 0, 0, 0, 0, 76, 0 } | ||||||
| #define M RVI_MULTIHEAD | #define M RVI_MULTIHEAD | ||||||
| #define W RVI_WAGON | #define W RVI_WAGON | ||||||
| #define S 0 | #define S 0 | ||||||
|   | |||||||
							
								
								
									
										99
									
								
								train_cmd.c
									
									
									
									
									
								
							
							
						
						
									
										99
									
								
								train_cmd.c
									
									
									
									
									
								
							| @@ -54,6 +54,54 @@ byte FreightWagonMult(CargoID cargo) | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Recalculates the cached total power of a train. Should be called when the consist is changed | ||||||
|  |  * @param v First vehicle of the consist. | ||||||
|  |  */ | ||||||
|  | void TrainPowerChanged(Vehicle* v) | ||||||
|  | { | ||||||
|  | 	Vehicle* u; | ||||||
|  | 	uint32 power = 0; | ||||||
|  | 	uint32 max_te = 0; | ||||||
|  |  | ||||||
|  | 	for (u = v; u != NULL; u = u->next) { | ||||||
|  | 		const RailVehicleInfo *rvi_u; | ||||||
|  | 		bool engine_has_power = true; | ||||||
|  | 		bool wagon_has_power = true; | ||||||
|  |  | ||||||
|  | 		/* Power is not added for articulated parts */ | ||||||
|  | 		if (IsArticulatedPart(u)) continue; | ||||||
|  |  | ||||||
|  | 		if (IsLevelCrossingTile(u->tile)) { | ||||||
|  | 			if (!HasPowerOnRail(u->u.rail.railtype, GetRailTypeCrossing(u->tile))) engine_has_power = false; | ||||||
|  | 			if (!HasPowerOnRail(v->u.rail.railtype, GetRailTypeCrossing(u->tile))) wagon_has_power = false; | ||||||
|  | 		} else { | ||||||
|  | 			if (!HasPowerOnRail(u->u.rail.railtype, GetRailType(u->tile))) engine_has_power = false; | ||||||
|  | 			if (!HasPowerOnRail(v->u.rail.railtype, GetRailType(u->tile))) wagon_has_power = false; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		rvi_u = RailVehInfo(u->engine_type); | ||||||
|  |  | ||||||
|  | 		if (engine_has_power && rvi_u->power != 0) { | ||||||
|  | 			power += rvi_u->power; | ||||||
|  | 			/* Tractive effort in (tonnes * 1000 * 10 =) N */ | ||||||
|  | 			max_te += (u->u.rail.cached_veh_weight * 10000 * rvi_u->tractive_effort) / 256; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON) && (wagon_has_power)) { | ||||||
|  | 			power += RailVehInfo(u->u.rail.first_engine)->pow_wag_power; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (v->u.rail.cached_power != power || v->u.rail.cached_max_te != max_te) { | ||||||
|  | 		v->u.rail.cached_power = power; | ||||||
|  | 		v->u.rail.cached_max_te = max_te; | ||||||
|  | 		InvalidateWindow(WC_VEHICLE_DETAILS, v->index); | ||||||
|  | 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Recalculates the cached weight of a train and its vehicles. Should be called each time the cargo on |  * Recalculates the cached weight of a train and its vehicles. Should be called each time the cargo on | ||||||
|  * the consist changes. |  * the consist changes. | ||||||
| @@ -87,47 +135,11 @@ static void TrainCargoChanged(Vehicle* v) | |||||||
|  |  | ||||||
| 	// store consist weight in cache | 	// store consist weight in cache | ||||||
| 	v->u.rail.cached_weight = weight; | 	v->u.rail.cached_weight = weight; | ||||||
|  |  | ||||||
|  | 	/* Now update train power (tractive effort is dependent on weight) */ | ||||||
|  | 	TrainPowerChanged(v); | ||||||
| } | } | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Recalculates the cached total power of a train. Should be called when the consist is changed |  | ||||||
|  * @param v First vehicle of the consist. |  | ||||||
|  */ |  | ||||||
| void TrainPowerChanged(Vehicle* v) |  | ||||||
| { |  | ||||||
| 	Vehicle* u; |  | ||||||
| 	uint32 power = 0; |  | ||||||
|  |  | ||||||
| 	for (u = v; u != NULL; u = u->next) { |  | ||||||
| 		const RailVehicleInfo *rvi_u; |  | ||||||
| 		bool engine_has_power = true; |  | ||||||
| 		bool wagon_has_power = true; |  | ||||||
|  |  | ||||||
| 		/* Power is not added for articulated parts */ |  | ||||||
| 		if (IsArticulatedPart(u)) continue; |  | ||||||
|  |  | ||||||
| 		if (IsLevelCrossingTile(u->tile)) { |  | ||||||
| 			if (!HasPowerOnRail(u->u.rail.railtype, GetRailTypeCrossing(u->tile))) engine_has_power = false; |  | ||||||
| 			if (!HasPowerOnRail(v->u.rail.railtype, GetRailTypeCrossing(u->tile))) wagon_has_power = false; |  | ||||||
| 		} else { |  | ||||||
| 			if (!HasPowerOnRail(u->u.rail.railtype, GetRailType(u->tile))) engine_has_power = false; |  | ||||||
| 			if (!HasPowerOnRail(v->u.rail.railtype, GetRailType(u->tile))) wagon_has_power = false; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		rvi_u = RailVehInfo(u->engine_type); |  | ||||||
|  |  | ||||||
| 		if (engine_has_power) power += rvi_u->power; |  | ||||||
| 		if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON) && (wagon_has_power)) { |  | ||||||
| 			power += RailVehInfo(u->u.rail.first_engine)->pow_wag_power; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (v->u.rail.cached_power != power) { |  | ||||||
| 		v->u.rail.cached_power = power; |  | ||||||
| 		InvalidateWindow(WC_VEHICLE_DETAILS, v->index); |  | ||||||
| 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Recalculates the cached stuff of a train. Should be called each time a vehicle is added |  * Recalculates the cached stuff of a train. Should be called each time a vehicle is added | ||||||
| @@ -231,9 +243,7 @@ void TrainConsistChanged(Vehicle* v) | |||||||
| 	// store consist weight/max speed in cache | 	// store consist weight/max speed in cache | ||||||
| 	v->u.rail.cached_max_speed = max_speed; | 	v->u.rail.cached_max_speed = max_speed; | ||||||
|  |  | ||||||
| 	TrainPowerChanged(v); | 	// recalculate cached weights and power too (we do this *after* the rest, so it is known which wagons are powered and need extra weight added) | ||||||
|  |  | ||||||
| 	// recalculate cached weights too (we do this *after* the rest, so it is known which wagons are powered and need extra weight added) |  | ||||||
| 	TrainCargoChanged(v); | 	TrainCargoChanged(v); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -307,6 +317,7 @@ static int GetTrainAcceleration(Vehicle *v, bool mode) | |||||||
| 	int curvecount[2] = {0, 0}; | 	int curvecount[2] = {0, 0}; | ||||||
| 	int sum = 0; | 	int sum = 0; | ||||||
| 	int numcurve = 0; | 	int numcurve = 0; | ||||||
|  | 	int max_te = v->u.rail.cached_max_te; // [N] | ||||||
|  |  | ||||||
| 	speed *= 10; | 	speed *= 10; | ||||||
| 	speed /= 16; | 	speed /= 16; | ||||||
| @@ -407,6 +418,7 @@ static int GetTrainAcceleration(Vehicle *v, bool mode) | |||||||
| 				force = power / speed; //[N] | 				force = power / speed; //[N] | ||||||
| 				force *= 22; | 				force *= 22; | ||||||
| 				force /= 10; | 				force /= 10; | ||||||
|  | 				if (mode == AM_ACCEL && force > max_te) force = max_te; | ||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| 			case RAILTYPE_MAGLEV: | 			case RAILTYPE_MAGLEV: | ||||||
| @@ -415,7 +427,8 @@ static int GetTrainAcceleration(Vehicle *v, bool mode) | |||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		//"kickoff" acceleration | 		//"kickoff" acceleration | ||||||
| 		force = max(power, (mass * 8) + resistance); | 		force = (mode == AM_ACCEL && v->u.rail.railtype != RAILTYPE_MAGLEV) ? min(max_te, power) : power; | ||||||
|  | 		force = max(force, (mass * 8) + resistance); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (force <= 0) force = 10000; | 	if (force <= 0) force = 10000; | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								train_gui.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								train_gui.c
									
									
									
									
									
								
							| @@ -232,6 +232,13 @@ void DrawTrainEnginePurchaseInfo(int x, int y, uint w, EngineID engine_number) | |||||||
| 	DrawString(x,y, STR_PURCHASE_INFO_SPEED_POWER, 0); | 	DrawString(x,y, STR_PURCHASE_INFO_SPEED_POWER, 0); | ||||||
| 	y += 10; | 	y += 10; | ||||||
|  |  | ||||||
|  | 	/* Max tractive effort - not applicable if old acceleration or maglev */ | ||||||
|  | 	if (_patches.realistic_acceleration && e->railtype != RAILTYPE_MAGLEV) { | ||||||
|  | 		SetDParam(0, ((rvi->weight << multihead) * 10 * rvi->tractive_effort) / 256); | ||||||
|  | 		DrawString(x, y, STR_PURCHASE_INFO_MAX_TE, 0); | ||||||
|  | 		y += 10; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	/* Running cost */ | 	/* Running cost */ | ||||||
| 	SetDParam(0, (rvi->running_cost_base * _price.running_rail[rvi->running_cost_class] >> 8) << multihead); | 	SetDParam(0, (rvi->running_cost_base * _price.running_rail[rvi->running_cost_class] >> 8) << multihead); | ||||||
| 	DrawString(x,y, STR_PURCHASE_INFO_RUNNINGCOST, 0); | 	DrawString(x,y, STR_PURCHASE_INFO_RUNNINGCOST, 0); | ||||||
| @@ -939,7 +946,10 @@ static void DrawTrainDetailsWindow(Window *w) | |||||||
| 	SetDParam(2, v->u.rail.cached_max_speed); | 	SetDParam(2, v->u.rail.cached_max_speed); | ||||||
| 	SetDParam(1, v->u.rail.cached_power); | 	SetDParam(1, v->u.rail.cached_power); | ||||||
| 	SetDParam(0, v->u.rail.cached_weight); | 	SetDParam(0, v->u.rail.cached_weight); | ||||||
| 	DrawString(x, 25, STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED, 0); | 	SetDParam(3, v->u.rail.cached_max_te / 1000); | ||||||
|  | 	DrawString(x, 25, (_patches.realistic_acceleration && v->u.rail.railtype != RAILTYPE_MAGLEV) ? | ||||||
|  | 		STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE : | ||||||
|  | 		STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED, 0); | ||||||
|  |  | ||||||
| 	SetDParam(0, v->profit_this_year); | 	SetDParam(0, v->profit_this_year); | ||||||
| 	SetDParam(1, v->profit_last_year); | 	SetDParam(1, v->profit_last_year); | ||||||
|   | |||||||
| @@ -62,6 +62,7 @@ typedef struct VehicleRail { | |||||||
| 	// cached values, recalculated when the cargo on a train changes (in addition to the conditions above) | 	// cached values, recalculated when the cargo on a train changes (in addition to the conditions above) | ||||||
| 	uint32 cached_weight;     // total weight of the consist. | 	uint32 cached_weight;     // total weight of the consist. | ||||||
| 	uint32 cached_veh_weight; // weight of the vehicle. | 	uint32 cached_veh_weight; // weight of the vehicle. | ||||||
|  | 	uint32 cached_max_te;     // max tractive effort of consist | ||||||
| 	/** | 	/** | ||||||
| 	 * Position/type of visual effect. | 	 * Position/type of visual effect. | ||||||
| 	 * bit 0 - 3 = position of effect relative to vehicle. (0 = front, 8 = centre, 15 = rear) | 	 * bit 0 - 3 = position of effect relative to vehicle. (0 = front, 8 = centre, 15 = rear) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 peter1138
					peter1138