Merge branch 'improved_breakdowns' into jgrpp
Update German and Korean language strings # Conflicts: # src/saveload/extended_ver_sl.cpp
This commit is contained in:
@@ -4270,7 +4270,7 @@ STR_VEHICLE_DETAILS_AIRCRAFT_RENAME :{BLACK}Name air
|
|||||||
STR_VEHICLE_INFO_AGE_RUNNING_COST_YR :{BLACK}Age: {LTBLUE}{STRING2}{BLACK} Running Cost: {LTBLUE}{CURRENCY_LONG}/yr
|
STR_VEHICLE_INFO_AGE_RUNNING_COST_YR :{BLACK}Age: {LTBLUE}{STRING2}{BLACK} Running Cost: {LTBLUE}{CURRENCY_LONG}/yr
|
||||||
|
|
||||||
STR_RUNNING :{LTBLUE}Running
|
STR_RUNNING :{LTBLUE}Running
|
||||||
STR_NEED_REPAIR :{ORANGE}Train needs repair - max speed reduced to {VELOCITY}
|
STR_NEED_REPAIR :{ORANGE}Vehicle needs repair - max speed reduced to {VELOCITY}
|
||||||
STR_CURRENT_STATUS :{BLACK}Current status: {STRING3}
|
STR_CURRENT_STATUS :{BLACK}Current status: {STRING3}
|
||||||
|
|
||||||
# The next two need to stay in this order
|
# The next two need to stay in this order
|
||||||
|
@@ -4257,7 +4257,7 @@ STR_VEHICLE_DETAILS_AIRCRAFT_RENAME :{BLACK}Flugzeug
|
|||||||
STR_VEHICLE_INFO_AGE_RUNNING_COST_YR :{BLACK}Alter: {LTBLUE}{STRING}{BLACK} Betriebskosten: {LTBLUE}{CURRENCY_LONG}/Jahr
|
STR_VEHICLE_INFO_AGE_RUNNING_COST_YR :{BLACK}Alter: {LTBLUE}{STRING}{BLACK} Betriebskosten: {LTBLUE}{CURRENCY_LONG}/Jahr
|
||||||
|
|
||||||
STR_RUNNING :{LTBLUE}Funktionierend
|
STR_RUNNING :{LTBLUE}Funktionierend
|
||||||
STR_NEED_REPAIR :{ORANGE}Der Zug ist reparaturbedürftig - die Höchstgeschwindigkeit ist auf {VELOCITY} reduziert
|
STR_NEED_REPAIR :{ORANGE}Der Fahrzeuge ist reparaturbedürftig - die Höchstgeschwindigkeit ist auf {VELOCITY} reduziert
|
||||||
STR_CURRENT_STATUS :{BLACK}Momentaner Status: {STRING}
|
STR_CURRENT_STATUS :{BLACK}Momentaner Status: {STRING}
|
||||||
|
|
||||||
# The next two need to stay in this order
|
# The next two need to stay in this order
|
||||||
|
@@ -4256,7 +4256,7 @@ STR_VEHICLE_DETAILS_AIRCRAFT_RENAME :{BLACK}항공
|
|||||||
STR_VEHICLE_INFO_AGE_RUNNING_COST_YR :{BLACK}연령: {LTBLUE}{STRING}{BLACK} 유지비: {LTBLUE}{CURRENCY_LONG}/년
|
STR_VEHICLE_INFO_AGE_RUNNING_COST_YR :{BLACK}연령: {LTBLUE}{STRING}{BLACK} 유지비: {LTBLUE}{CURRENCY_LONG}/년
|
||||||
|
|
||||||
STR_RUNNING :{LTBLUE}운행 중
|
STR_RUNNING :{LTBLUE}운행 중
|
||||||
STR_NEED_REPAIR :{ORANGE}열차를 수리해야 합니다. 최고 속도가 {VELOCITY}로 감소하였습니다.
|
STR_NEED_REPAIR :{ORANGE}차량를 수리해야 합니다. 최고 속도가 {VELOCITY}로 감소하였습니다.
|
||||||
STR_CURRENT_STATUS :{BLACK}현재 상태: {STRING}
|
STR_CURRENT_STATUS :{BLACK}현재 상태: {STRING}
|
||||||
|
|
||||||
# The next two need to stay in this order
|
# The next two need to stay in this order
|
||||||
|
@@ -97,6 +97,8 @@ struct RoadVehicle FINAL : public GroundVehicle<RoadVehicle, VEH_ROAD> {
|
|||||||
RoadType roadtype;
|
RoadType roadtype;
|
||||||
RoadTypes compatible_roadtypes;
|
RoadTypes compatible_roadtypes;
|
||||||
|
|
||||||
|
byte critical_breakdown_count; ///< Counter for the number of critical breakdowns since last service
|
||||||
|
|
||||||
/** We don't want GCC to zero our struct! It already is zeroed and has an index! */
|
/** We don't want GCC to zero our struct! It already is zeroed and has an index! */
|
||||||
RoadVehicle() : GroundVehicleBase() {}
|
RoadVehicle() : GroundVehicleBase() {}
|
||||||
/** We want to 'destruct' the right class. */
|
/** We want to 'destruct' the right class. */
|
||||||
@@ -124,6 +126,8 @@ struct RoadVehicle FINAL : public GroundVehicle<RoadVehicle, VEH_ROAD> {
|
|||||||
bool IsBus() const;
|
bool IsBus() const;
|
||||||
|
|
||||||
int GetCurrentMaxSpeed() const;
|
int GetCurrentMaxSpeed() const;
|
||||||
|
int GetEffectiveMaxSpeed() const;
|
||||||
|
int GetDisplayEffectiveMaxSpeed() const { return this->GetEffectiveMaxSpeed() / 2; }
|
||||||
int UpdateSpeed();
|
int UpdateSpeed();
|
||||||
|
|
||||||
inline bool IsRoadVehicleOnLevelCrossing() const
|
inline bool IsRoadVehicleOnLevelCrossing() const
|
||||||
|
@@ -436,13 +436,29 @@ void RoadVehicle::UpdateDeltaXY(Direction direction)
|
|||||||
this->z_extent = 6;
|
this->z_extent = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the maximum speed of the vehicle, taking into account speed reductions following critical breakdowns
|
||||||
|
* @return Maximum speed of the vehicle.
|
||||||
|
*/
|
||||||
|
int RoadVehicle::GetEffectiveMaxSpeed() const
|
||||||
|
{
|
||||||
|
int max_speed = this->vcache.cached_max_speed;
|
||||||
|
|
||||||
|
for (uint i = 0; i < this->critical_breakdown_count; i++) {
|
||||||
|
max_speed = min(max_speed - (max_speed / 3) + 1, max_speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clamp speed to be no less than lower of 5mph and 1/8 of base speed */
|
||||||
|
return max<uint16>(max_speed, min<uint16>(10, (this->vcache.cached_max_speed + 7) >> 3));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the maximum speed of the vehicle under its current conditions.
|
* Calculates the maximum speed of the vehicle under its current conditions.
|
||||||
* @return Maximum speed of the vehicle.
|
* @return Maximum speed of the vehicle.
|
||||||
*/
|
*/
|
||||||
inline int RoadVehicle::GetCurrentMaxSpeed() const
|
inline int RoadVehicle::GetCurrentMaxSpeed() const
|
||||||
{
|
{
|
||||||
int max_speed = this->vcache.cached_max_speed;
|
int max_speed = this->GetEffectiveMaxSpeed();
|
||||||
|
|
||||||
/* Limit speed to 50% while reversing, 75% in curves. */
|
/* Limit speed to 50% while reversing, 75% in curves. */
|
||||||
for (const RoadVehicle *u = this; u != NULL; u = u->Next()) {
|
for (const RoadVehicle *u = this; u != NULL; u = u->Next()) {
|
||||||
|
@@ -117,6 +117,11 @@ void DrawRoadVehDetails(const Vehicle *v, int left, int right, int y)
|
|||||||
/* Draw Transfer credits text */
|
/* Draw Transfer credits text */
|
||||||
SetDParam(0, feeder_share);
|
SetDParam(0, feeder_share);
|
||||||
DrawString(left, right, y + 3 * FONT_HEIGHT_NORMAL + 3 + y_offset, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE);
|
DrawString(left, right, y + 3 * FONT_HEIGHT_NORMAL + 3 + y_offset, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE);
|
||||||
|
|
||||||
|
if (RoadVehicle::From(v)->critical_breakdown_count > 0) {
|
||||||
|
SetDParam(0, RoadVehicle::From(v)->GetDisplayEffectiveMaxSpeed());
|
||||||
|
DrawString(left, right, y + 4 * FONT_HEIGHT_NORMAL + 4 + y_offset, STR_NEED_REPAIR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -56,7 +56,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
|||||||
{ XSLFI_TIMETABLES_START_TICKS, XSCF_NULL, 2, 2, "timetable_start_ticks", NULL, NULL, NULL },
|
{ XSLFI_TIMETABLES_START_TICKS, XSCF_NULL, 2, 2, "timetable_start_ticks", NULL, NULL, NULL },
|
||||||
{ XSLFI_TOWN_CARGO_ADJ, XSCF_IGNORABLE_UNKNOWN, 2, 2, "town_cargo_adj", NULL, NULL, NULL },
|
{ XSLFI_TOWN_CARGO_ADJ, XSCF_IGNORABLE_UNKNOWN, 2, 2, "town_cargo_adj", NULL, NULL, NULL },
|
||||||
{ XSLFI_SIG_TUNNEL_BRIDGE, XSCF_NULL, 4, 4, "signal_tunnel_bridge", NULL, NULL, "XBSS" },
|
{ XSLFI_SIG_TUNNEL_BRIDGE, XSCF_NULL, 4, 4, "signal_tunnel_bridge", NULL, NULL, "XBSS" },
|
||||||
{ XSLFI_IMPROVED_BREAKDOWNS, XSCF_NULL, 5, 5, "improved_breakdowns", NULL, NULL, NULL },
|
{ XSLFI_IMPROVED_BREAKDOWNS, XSCF_NULL, 6, 6, "improved_breakdowns", NULL, NULL, NULL },
|
||||||
{ XSLFI_TT_WAIT_IN_DEPOT, XSCF_NULL, 1, 1, "tt_wait_in_depot", NULL, NULL, NULL },
|
{ XSLFI_TT_WAIT_IN_DEPOT, XSCF_NULL, 1, 1, "tt_wait_in_depot", NULL, NULL, NULL },
|
||||||
{ XSLFI_AUTO_TIMETABLE, XSCF_NULL, 4, 4, "auto_timetables", NULL, NULL, NULL },
|
{ XSLFI_AUTO_TIMETABLE, XSCF_NULL, 4, 4, "auto_timetables", NULL, NULL, NULL },
|
||||||
{ XSLFI_VEHICLE_REPAIR_COST, XSCF_NULL, 2, 2, "vehicle_repair_cost", NULL, NULL, NULL },
|
{ XSLFI_VEHICLE_REPAIR_COST, XSCF_NULL, 2, 2, "vehicle_repair_cost", NULL, NULL, NULL },
|
||||||
|
@@ -767,6 +767,7 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
|
|||||||
SLE_CONDNULL(4, 69, 130),
|
SLE_CONDNULL(4, 69, 130),
|
||||||
SLE_CONDNULL(2, 6, 130),
|
SLE_CONDNULL(2, 6, 130),
|
||||||
SLE_CONDNULL(16, 2, 143), // old reserved space
|
SLE_CONDNULL(16, 2, 143), // old reserved space
|
||||||
|
SLE_CONDVAR_X(RoadVehicle, critical_breakdown_count, SLE_UINT8, 0, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_IMPROVED_BREAKDOWNS, 6)),
|
||||||
|
|
||||||
SLE_END()
|
SLE_END()
|
||||||
};
|
};
|
||||||
|
@@ -159,12 +159,17 @@ void CheckBreakdownFlags(Train *v)
|
|||||||
|
|
||||||
uint16 GetTrainVehicleMaxSpeed(const Train *u, const RailVehicleInfo *rvi_u, const Train *front)
|
uint16 GetTrainVehicleMaxSpeed(const Train *u, const RailVehicleInfo *rvi_u, const Train *front)
|
||||||
{
|
{
|
||||||
uint16 speed = GetVehicleProperty(u, PROP_TRAIN_SPEED, rvi_u->max_speed);
|
const uint16 base_speed = GetVehicleProperty(u, PROP_TRAIN_SPEED, rvi_u->max_speed);
|
||||||
|
uint16 speed = base_speed;
|
||||||
if (HasBit(u->flags, VRF_NEED_REPAIR) && front->IsFrontEngine()) {
|
if (HasBit(u->flags, VRF_NEED_REPAIR) && front->IsFrontEngine()) {
|
||||||
for (uint i = 0; i < u->critical_breakdown_count; i++) {
|
for (uint i = 0; i < u->critical_breakdown_count; i++) {
|
||||||
speed = min(speed - (speed / (front->tcache.cached_num_engines + 2)) + 1, speed);
|
speed = min(speed - (speed / (front->tcache.cached_num_engines + 2)) + 1, speed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* clamp speed to be no less than lower of 5mph and 1/8 of base speed */
|
||||||
|
speed = max<uint16>(speed, min<uint16>(5, (base_speed + 7) >> 3));
|
||||||
|
|
||||||
if (HasBit(u->flags, VRF_HAS_HIT_RV) && front->IsFrontEngine()) {
|
if (HasBit(u->flags, VRF_HAS_HIT_RV) && front->IsFrontEngine()) {
|
||||||
speed = min(speed, 30);
|
speed = min(speed, 30);
|
||||||
}
|
}
|
||||||
|
@@ -163,6 +163,8 @@ void VehicleServiceInDepot(Vehicle *v)
|
|||||||
Train::From(v)->ConsistChanged(CCF_REFIT);
|
Train::From(v)->ConsistChanged(CCF_REFIT);
|
||||||
CLRBITS(Train::From(v)->flags, (1 << VRF_BREAKDOWN_BRAKING) | VRF_IS_BROKEN );
|
CLRBITS(Train::From(v)->flags, (1 << VRF_BREAKDOWN_BRAKING) | VRF_IS_BROKEN );
|
||||||
}
|
}
|
||||||
|
} else if (v->type == VEH_ROAD) {
|
||||||
|
RoadVehicle::From(v)->critical_breakdown_count = 0;
|
||||||
}
|
}
|
||||||
v->vehstatus &= ~VS_AIRCRAFT_BROKEN;
|
v->vehstatus &= ~VS_AIRCRAFT_BROKEN;
|
||||||
SetWindowDirty(WC_VEHICLE_DETAILS, v->index); // ensure that last service date and reliability are updated
|
SetWindowDirty(WC_VEHICLE_DETAILS, v->index); // ensure that last service date and reliability are updated
|
||||||
@@ -199,7 +201,8 @@ bool Vehicle::NeedsServicing() const
|
|||||||
if ((this->ServiceIntervalIsPercent() ?
|
if ((this->ServiceIntervalIsPercent() ?
|
||||||
(this->reliability >= this->GetEngine()->reliability * (100 - this->service_interval) / 100) :
|
(this->reliability >= this->GetEngine()->reliability * (100 - this->service_interval) / 100) :
|
||||||
(this->date_of_last_service + this->service_interval >= _date))
|
(this->date_of_last_service + this->service_interval >= _date))
|
||||||
&& !(this->type == VEH_TRAIN && HasBit(Train::From(this)->flags, VRF_NEED_REPAIR))) {
|
&& !(this->type == VEH_TRAIN && HasBit(Train::From(this)->flags, VRF_NEED_REPAIR))
|
||||||
|
&& !(this->type == VEH_ROAD && RoadVehicle::From(this)->critical_breakdown_count > 0)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1697,6 +1700,13 @@ bool Vehicle::HandleBreakdown()
|
|||||||
EffectVehicle *u = CreateEffectVehicleRel(this, 4, 4, 5, EV_BREAKDOWN_SMOKE);
|
EffectVehicle *u = CreateEffectVehicleRel(this, 4, 4, 5, EV_BREAKDOWN_SMOKE);
|
||||||
if (u != NULL) u->animation_state = this->breakdown_delay * 2;
|
if (u != NULL) u->animation_state = this->breakdown_delay * 2;
|
||||||
}
|
}
|
||||||
|
if (_settings_game.vehicle.improved_breakdowns) {
|
||||||
|
if (this->type == VEH_ROAD) {
|
||||||
|
if (RoadVehicle::From(this)->critical_breakdown_count != 255) {
|
||||||
|
RoadVehicle::From(this)->critical_breakdown_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/* FALL THROUGH */
|
/* FALL THROUGH */
|
||||||
case BREAKDOWN_EM_STOP:
|
case BREAKDOWN_EM_STOP:
|
||||||
this->cur_speed = 0;
|
this->cur_speed = 0;
|
||||||
|
@@ -2290,13 +2290,13 @@ struct VehicleDetailsWindow : Window {
|
|||||||
uint desired_height;
|
uint desired_height;
|
||||||
if (v->HasArticulatedPart()) {
|
if (v->HasArticulatedPart()) {
|
||||||
/* An articulated RV has its text drawn under the sprite instead of after it, hence 15 pixels extra. */
|
/* An articulated RV has its text drawn under the sprite instead of after it, hence 15 pixels extra. */
|
||||||
desired_height = WD_FRAMERECT_TOP + ScaleGUITrad(15) + 3 * FONT_HEIGHT_NORMAL + 2 + WD_FRAMERECT_BOTTOM;
|
desired_height = WD_FRAMERECT_TOP + ScaleGUITrad(15) + 4 * FONT_HEIGHT_NORMAL + 3 + WD_FRAMERECT_BOTTOM;
|
||||||
/* Add space for the cargo amount for each part. */
|
/* Add space for the cargo amount for each part. */
|
||||||
for (const Vehicle *u = v; u != NULL; u = u->Next()) {
|
for (const Vehicle *u = v; u != NULL; u = u->Next()) {
|
||||||
if (u->cargo_cap != 0) desired_height += FONT_HEIGHT_NORMAL + 1;
|
if (u->cargo_cap != 0) desired_height += FONT_HEIGHT_NORMAL + 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
desired_height = WD_FRAMERECT_TOP + 4 * FONT_HEIGHT_NORMAL + 3 + WD_FRAMERECT_BOTTOM;
|
desired_height = WD_FRAMERECT_TOP + 5 * FONT_HEIGHT_NORMAL + 4 + WD_FRAMERECT_BOTTOM;
|
||||||
}
|
}
|
||||||
return desired_height;
|
return desired_height;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user