Fix #299: Add estimated max speed (full) to template windows
This commit is contained in:
		@@ -4950,6 +4950,7 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE                  :{BLACK}Weight:
 | 
			
		||||
STR_VEHICLE_INFO_TRAIN_LENGTH                                   :{BLACK}Train length {LTBLUE}{DECIMAL} tile{P "" s} {STRING4}
 | 
			
		||||
STR_VEHICLE_INFO_WEIGHT_RATIOS                                  :{BLACK}Power / weight: {LTBLUE}{POWER_WEIGHT_RATIO} {BLACK} Max. T.E / weight: {LTBLUE}{FORCE_WEIGHT_RATIO}
 | 
			
		||||
STR_VEHICLE_INFO_FULL_WEIGHT_WITH_RATIOS                        :{BLACK}Full weight: {LTBLUE}{WEIGHT_SHORT} {STRING2}
 | 
			
		||||
STR_VEHICLE_INFO_MAX_SPEED_LOADED                               :{BLACK}Max. speed (full): {LTBLUE}{VELOCITY}
 | 
			
		||||
 | 
			
		||||
STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR                     :{BLACK}Profit this year: {LTBLUE}{CURRENCY_LONG} (last year: {CURRENCY_LONG})
 | 
			
		||||
STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_LIFETIME            :{STRING2} (lifetime: {CURRENCY_LONG})
 | 
			
		||||
 
 | 
			
		||||
@@ -3959,7 +3959,7 @@ bool AfterLoadGame()
 | 
			
		||||
 | 
			
		||||
	AfterLoadTraceRestrict();
 | 
			
		||||
	AfterLoadTemplateVehiclesUpdate();
 | 
			
		||||
	if (SlXvIsFeaturePresent(XSLFI_TEMPLATE_REPLACEMENT, 1, 5)) {
 | 
			
		||||
	if (SlXvIsFeaturePresent(XSLFI_TEMPLATE_REPLACEMENT, 1, 7)) {
 | 
			
		||||
		AfterLoadTemplateVehiclesUpdateProperties();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -100,7 +100,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
 | 
			
		||||
	{ XSLFI_REVERSE_AT_WAYPOINT,    XSCF_NULL,                1,   1, "reverse_at_waypoint",       nullptr, nullptr, nullptr        },
 | 
			
		||||
	{ XSLFI_VEH_LIFETIME_PROFIT,    XSCF_NULL,                1,   1, "veh_lifetime_profit",       nullptr, nullptr, nullptr        },
 | 
			
		||||
	{ XSLFI_LINKGRAPH_DAY_SCALE,    XSCF_NULL,                1,   1, "linkgraph_day_scale",       nullptr, nullptr, nullptr        },
 | 
			
		||||
	{ XSLFI_TEMPLATE_REPLACEMENT,   XSCF_NULL,                7,   7, "template_replacement",      nullptr, nullptr, "TRPL,TMPL" },
 | 
			
		||||
	{ XSLFI_TEMPLATE_REPLACEMENT,   XSCF_NULL,                8,   8, "template_replacement",      nullptr, nullptr, "TRPL,TMPL" },
 | 
			
		||||
	{ XSLFI_MORE_RAIL_TYPES,        XSCF_NULL,                0,   1, "more_rail_types",           nullptr, nullptr, nullptr        },
 | 
			
		||||
	{ XSLFI_CARGO_TYPE_ORDERS,      XSCF_NULL,                3,   3, "cargo_type_orders",         nullptr, nullptr, "ORDX,VEOX" },
 | 
			
		||||
	{ XSLFI_EXTENDED_GAMELOG,       XSCF_NULL,                1,   1, "extended_gamelog",          nullptr, nullptr, nullptr        },
 | 
			
		||||
 
 | 
			
		||||
@@ -40,6 +40,7 @@ const SaveLoad* GTD() {
 | 
			
		||||
		SLE_VAR(TemplateVehicle, empty_weight, SLE_UINT32),
 | 
			
		||||
		SLE_CONDVAR_X(TemplateVehicle, full_weight, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TEMPLATE_REPLACEMENT, 6)),
 | 
			
		||||
		SLE_VAR(TemplateVehicle, max_te, SLE_UINT32),
 | 
			
		||||
		SLE_CONDVAR_X(TemplateVehicle, air_drag, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TEMPLATE_REPLACEMENT, 8)),
 | 
			
		||||
 | 
			
		||||
		SLE_CONDVAR_X(TemplateVehicle, ctrl_flags, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TEMPLATE_REPLACEMENT, 7)),
 | 
			
		||||
 | 
			
		||||
@@ -146,6 +147,7 @@ void AfterLoadTemplateVehiclesUpdateProperties()
 | 
			
		||||
				tv->empty_weight = gcache->cached_weight;
 | 
			
		||||
				tv->full_weight = gcache->cached_weight + full_cargo_weight;
 | 
			
		||||
				tv->max_te = gcache->cached_max_te;
 | 
			
		||||
				tv->air_drag = gcache->cached_air_drag;
 | 
			
		||||
				delete t;
 | 
			
		||||
			}
 | 
			
		||||
			cur_company.Restore();
 | 
			
		||||
 
 | 
			
		||||
@@ -340,6 +340,11 @@ public:
 | 
			
		||||
						}
 | 
			
		||||
						DrawString(8, r.right, y, STR_VEHICLE_INFO_FULL_WEIGHT_WITH_RATIOS);
 | 
			
		||||
					}
 | 
			
		||||
					if (_settings_game.vehicle.train_acceleration_model != AM_ORIGINAL) {
 | 
			
		||||
						y += FONT_HEIGHT_NORMAL;
 | 
			
		||||
						SetDParam(0, GetTrainEstimatedMaxAchievableSpeed(this->virtual_train, gcache->cached_weight + full_cargo_weight, this->virtual_train->GetDisplayMaxSpeed()));
 | 
			
		||||
						DrawString(8, r.right, y, STR_VEHICLE_INFO_MAX_SPEED_LOADED);
 | 
			
		||||
					}
 | 
			
		||||
					/* Draw cargo summary */
 | 
			
		||||
					CargoArray cargo_caps;
 | 
			
		||||
					for (const Train *tmp = this->virtual_train; tmp != nullptr; tmp = tmp->Next()) {
 | 
			
		||||
 
 | 
			
		||||
@@ -763,6 +763,11 @@ public:
 | 
			
		||||
			}
 | 
			
		||||
			DrawString(8, r.right, top, STR_VEHICLE_INFO_FULL_WEIGHT_WITH_RATIOS);
 | 
			
		||||
		}
 | 
			
		||||
		if (_settings_game.vehicle.train_acceleration_model != AM_ORIGINAL) {
 | 
			
		||||
			top += FONT_HEIGHT_NORMAL;
 | 
			
		||||
			SetDParam(0, GetTemplateVehicleEstimatedMaxAchievableSpeed(tmp, tmp->full_weight, tmp->max_speed));
 | 
			
		||||
			DrawString(8, r.right, top, STR_VEHICLE_INFO_MAX_SPEED_LOADED);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Draw cargo summary */
 | 
			
		||||
		top += ScaleGUITrad(26);
 | 
			
		||||
 
 | 
			
		||||
@@ -111,6 +111,7 @@ public:
 | 
			
		||||
	uint32 empty_weight;
 | 
			
		||||
	uint32 full_weight;
 | 
			
		||||
	uint32 max_te;
 | 
			
		||||
	uint32 air_drag;
 | 
			
		||||
 | 
			
		||||
	uint32 ctrl_flags;                  ///< See: TemplateVehicleControlFlags
 | 
			
		||||
 | 
			
		||||
@@ -218,4 +219,6 @@ short DeleteTemplateReplacementsByGroupID(GroupID);
 | 
			
		||||
 | 
			
		||||
void ReindexTemplateReplacements();
 | 
			
		||||
 | 
			
		||||
int GetTemplateVehicleEstimatedMaxAchievableSpeed(const TemplateVehicle *tv, const int mass, const int speed_cap);
 | 
			
		||||
 | 
			
		||||
#endif /* TEMPLATE_VEH_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -169,6 +169,7 @@ void SetupTemplateVehicleFromVirtual(TemplateVehicle *tmp, TemplateVehicle *prev
 | 
			
		||||
		tmp->empty_weight = std::max<uint32>(gcache->cached_weight - cargo_weight, 1);
 | 
			
		||||
		tmp->full_weight = std::max<uint32>(gcache->cached_weight + full_cargo_weight - cargo_weight, 1);
 | 
			
		||||
		tmp->max_te = gcache->cached_max_te;
 | 
			
		||||
		tmp->air_drag = gcache->cached_air_drag;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	virt->GetImage(DIR_W, EIT_IN_DEPOT, &tmp->sprite_seq);
 | 
			
		||||
@@ -490,3 +491,17 @@ void UpdateAllTemplateVehicleImages()
 | 
			
		||||
 | 
			
		||||
	_template_vehicle_images_valid = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int GetTemplateVehicleEstimatedMaxAchievableSpeed(const TemplateVehicle *tv, const int mass, const int speed_cap)
 | 
			
		||||
{
 | 
			
		||||
	int max_speed = 0;
 | 
			
		||||
	int acceleration;
 | 
			
		||||
 | 
			
		||||
	do
 | 
			
		||||
	{
 | 
			
		||||
		max_speed++;
 | 
			
		||||
		acceleration = GetTrainRealisticAccelerationAtSpeed(max_speed, mass, tv->power, tv->max_te, tv->air_drag, tv->railtype);
 | 
			
		||||
	} while (acceleration > 0 && max_speed < speed_cap);
 | 
			
		||||
 | 
			
		||||
	return max_speed;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -493,6 +493,7 @@ inline int GetTrainStopLocation(StationID station_id, TileIndex tile, Train *v,
 | 
			
		||||
	return GetTrainStopLocation(station_id, tile, v, update_train_state, station_ahead, station_length, v->x_pos, v->y_pos);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int GetTrainRealisticAccelerationAtSpeed(const int speed, const int mass, const uint32 cached_power, const uint32 max_te, const uint32 air_drag, const RailType railtype);
 | 
			
		||||
int GetTrainEstimatedMaxAchievableSpeed(const Train *train, const int mass, const int speed_cap);
 | 
			
		||||
 | 
			
		||||
#endif /* TRAIN_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -6920,12 +6920,12 @@ void TrainBrakesOverheatedBreakdown(Vehicle *v)
 | 
			
		||||
	t->breakdown_severity = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int GetTrainRealisticAccelerationAtSpeed(const Train *train, const int speed, const int mass)
 | 
			
		||||
int GetTrainRealisticAccelerationAtSpeed(const int speed, const int mass, const uint32 cached_power, const uint32 max_te, const uint32 air_drag, const RailType railtype)
 | 
			
		||||
{
 | 
			
		||||
	const int64 power = train->gcache.cached_power * 746ll;
 | 
			
		||||
	const int64 power = cached_power * 746ll;
 | 
			
		||||
	int64 resistance = 0;
 | 
			
		||||
 | 
			
		||||
	const bool maglev = (GetRailTypeInfo(train->railtype)->acceleration_type == 2);
 | 
			
		||||
	const bool maglev = (GetRailTypeInfo(railtype)->acceleration_type == 2);
 | 
			
		||||
 | 
			
		||||
	if (!maglev) {
 | 
			
		||||
		/* Static resistance plus rolling friction. */
 | 
			
		||||
@@ -6935,9 +6935,8 @@ static int GetTrainRealisticAccelerationAtSpeed(const Train *train, const int sp
 | 
			
		||||
 | 
			
		||||
	const int area = 14;
 | 
			
		||||
 | 
			
		||||
	resistance += (area * train->gcache.cached_air_drag * speed * speed) / 1000;
 | 
			
		||||
	resistance += (area * air_drag * speed * speed) / 1000;
 | 
			
		||||
 | 
			
		||||
	uint32 max_te = train->gcache.cached_max_te; // [N]
 | 
			
		||||
	int64 force;
 | 
			
		||||
 | 
			
		||||
	if (speed > 0) {
 | 
			
		||||
@@ -6973,7 +6972,7 @@ int GetTrainEstimatedMaxAchievableSpeed(const Train *train, const int mass, cons
 | 
			
		||||
	do
 | 
			
		||||
	{
 | 
			
		||||
		max_speed++;
 | 
			
		||||
		acceleration = GetTrainRealisticAccelerationAtSpeed(train, max_speed, mass);
 | 
			
		||||
		acceleration = GetTrainRealisticAccelerationAtSpeed(max_speed, mass, train->gcache.cached_power, train->gcache.cached_max_te, train->gcache.cached_air_drag, train->railtype);
 | 
			
		||||
	} while (acceleration > 0 && max_speed < speed_cap);
 | 
			
		||||
 | 
			
		||||
	return max_speed;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user