Implement improved breakdown speed reductions for ships
This commit is contained in:
@@ -86,7 +86,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
|||||||
{ XSLFI_TIMETABLES_START_TICKS, XSCF_NULL, 2, 2, "timetable_start_ticks", nullptr, nullptr, nullptr },
|
{ XSLFI_TIMETABLES_START_TICKS, XSCF_NULL, 2, 2, "timetable_start_ticks", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_TOWN_CARGO_ADJ, XSCF_IGNORABLE_UNKNOWN, 2, 2, "town_cargo_adj", nullptr, nullptr, nullptr },
|
{ XSLFI_TOWN_CARGO_ADJ, XSCF_IGNORABLE_UNKNOWN, 2, 2, "town_cargo_adj", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_SIG_TUNNEL_BRIDGE, XSCF_NULL, 9, 9, "signal_tunnel_bridge", nullptr, nullptr, "XBSS" },
|
{ XSLFI_SIG_TUNNEL_BRIDGE, XSCF_NULL, 9, 9, "signal_tunnel_bridge", nullptr, nullptr, "XBSS" },
|
||||||
{ XSLFI_IMPROVED_BREAKDOWNS, XSCF_NULL, 7, 7, "improved_breakdowns", nullptr, nullptr, nullptr },
|
{ XSLFI_IMPROVED_BREAKDOWNS, XSCF_NULL, 8, 8, "improved_breakdowns", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_CONSIST_BREAKDOWN_FLAG, XSCF_NULL, 1, 1, "consist_breakdown_flag", nullptr, nullptr, nullptr },
|
{ XSLFI_CONSIST_BREAKDOWN_FLAG, XSCF_NULL, 1, 1, "consist_breakdown_flag", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_TT_WAIT_IN_DEPOT, XSCF_NULL, 1, 1, "tt_wait_in_depot", nullptr, nullptr, nullptr },
|
{ XSLFI_TT_WAIT_IN_DEPOT, XSCF_NULL, 1, 1, "tt_wait_in_depot", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_AUTO_TIMETABLE, XSCF_NULL, 5, 5, "auto_timetables", nullptr, nullptr, nullptr },
|
{ XSLFI_AUTO_TIMETABLE, XSCF_NULL, 5, 5, "auto_timetables", nullptr, nullptr, nullptr },
|
||||||
|
@@ -844,6 +844,7 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
|
|||||||
SLE_CONDDEQUE(Ship, path, SLE_UINT8, SLV_SHIP_PATH_CACHE, SL_MAX_VERSION),
|
SLE_CONDDEQUE(Ship, path, SLE_UINT8, SLV_SHIP_PATH_CACHE, SL_MAX_VERSION),
|
||||||
SLE_CONDVAR(Ship, rotation, SLE_UINT8, SLV_SHIP_ROTATION, SL_MAX_VERSION),
|
SLE_CONDVAR(Ship, rotation, SLE_UINT8, SLV_SHIP_ROTATION, SL_MAX_VERSION),
|
||||||
SLE_CONDVAR_X(Ship, lost_count, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SHIP_LOST_COUNTER)),
|
SLE_CONDVAR_X(Ship, lost_count, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SHIP_LOST_COUNTER)),
|
||||||
|
SLE_CONDVAR_X(Ship, critical_breakdown_count, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_IMPROVED_BREAKDOWNS, 8)),
|
||||||
|
|
||||||
SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space
|
SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space
|
||||||
|
|
||||||
|
@@ -32,6 +32,7 @@ struct Ship FINAL : public SpecializedVehicle<Ship, VEH_SHIP> {
|
|||||||
int16 rotation_x_pos; ///< NOSAVE: X Position before rotation.
|
int16 rotation_x_pos; ///< NOSAVE: X Position before rotation.
|
||||||
int16 rotation_y_pos; ///< NOSAVE: Y Position before rotation.
|
int16 rotation_y_pos; ///< NOSAVE: Y Position before rotation.
|
||||||
uint8 lost_count; ///< Count of number of failed pathfinder attempts
|
uint8 lost_count; ///< Count of number of failed pathfinder attempts
|
||||||
|
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! */
|
||||||
Ship() : SpecializedVehicleBase() {}
|
Ship() : SpecializedVehicleBase() {}
|
||||||
@@ -47,7 +48,9 @@ struct Ship FINAL : public SpecializedVehicle<Ship, VEH_SHIP> {
|
|||||||
Direction GetMapImageDirection() const { return this->rotation; }
|
Direction GetMapImageDirection() const { return this->rotation; }
|
||||||
int GetDisplaySpeed() const { return this->cur_speed / 2; }
|
int GetDisplaySpeed() const { return this->cur_speed / 2; }
|
||||||
int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed / 2; }
|
int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed / 2; }
|
||||||
int GetCurrentMaxSpeed() const { return std::min<int>(this->vcache.cached_max_speed, this->current_order.GetMaxSpeed() * 2); }
|
int GetEffectiveMaxSpeed() const;
|
||||||
|
int GetDisplayEffectiveMaxSpeed() const { return this->GetEffectiveMaxSpeed() / 2; }
|
||||||
|
int GetCurrentMaxSpeed() const { return std::min<int>(this->GetEffectiveMaxSpeed(), this->current_order.GetMaxSpeed() * 2); }
|
||||||
Money GetRunningCost() const;
|
Money GetRunningCost() const;
|
||||||
bool IsInDepot() const { return this->state == TRACK_BIT_DEPOT; }
|
bool IsInDepot() const { return this->state == TRACK_BIT_DEPOT; }
|
||||||
bool Tick();
|
bool Tick();
|
||||||
|
@@ -339,6 +339,20 @@ void Ship::UpdateDeltaXY()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Ship::GetEffectiveMaxSpeed() const
|
||||||
|
{
|
||||||
|
int max_speed = this->vcache.cached_max_speed;
|
||||||
|
|
||||||
|
if (this->critical_breakdown_count == 0) return max_speed;
|
||||||
|
|
||||||
|
for (uint i = 0; i < this->critical_breakdown_count; i++) {
|
||||||
|
max_speed = std::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 std::max<uint16>(max_speed, std::min<uint16>(10, (this->vcache.cached_max_speed + 7) >> 3));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test-procedure for HasVehicleOnPos to check for any ships which are visible and not stopped by the player.
|
* Test-procedure for HasVehicleOnPos to check for any ships which are visible and not stopped by the player.
|
||||||
*/
|
*/
|
||||||
@@ -439,7 +453,7 @@ static bool ShipAccelerate(Vehicle *v)
|
|||||||
uint spd;
|
uint spd;
|
||||||
byte t;
|
byte t;
|
||||||
|
|
||||||
spd = std::min<uint>(v->cur_speed + 1, v->vcache.cached_max_speed);
|
spd = std::min<uint>(v->cur_speed + 1, Ship::From(v)->GetEffectiveMaxSpeed());
|
||||||
spd = std::min<uint>(spd, v->current_order.GetMaxSpeed() * 2);
|
spd = std::min<uint>(spd, v->current_order.GetMaxSpeed() * 2);
|
||||||
|
|
||||||
if (v->breakdown_ctr == 1 && v->breakdown_type == BREAKDOWN_LOW_POWER && v->cur_speed > (v->breakdown_severity * ShipVehInfo(v->engine_type)->max_speed) >> 8) {
|
if (v->breakdown_ctr == 1 && v->breakdown_type == BREAKDOWN_LOW_POWER && v->cur_speed > (v->breakdown_severity * ShipVehInfo(v->engine_type)->max_speed) >> 8) {
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
#include "vehicle_func.h"
|
#include "vehicle_func.h"
|
||||||
#include "spritecache.h"
|
#include "spritecache.h"
|
||||||
#include "zoom_func.h"
|
#include "zoom_func.h"
|
||||||
|
#include "ship.h"
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
|
|
||||||
@@ -84,4 +85,9 @@ void DrawShipDetails(const Vehicle *v, int left, int right, int y)
|
|||||||
/* Draw Transfer credits text */
|
/* Draw Transfer credits text */
|
||||||
SetDParam(0, v->cargo.FeederShare());
|
SetDParam(0, v->cargo.FeederShare());
|
||||||
DrawString(left, right, y + 3 * FONT_HEIGHT_NORMAL + 3, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE);
|
DrawString(left, right, y + 3 * FONT_HEIGHT_NORMAL + 3, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE);
|
||||||
|
|
||||||
|
if (Ship::From(v)->critical_breakdown_count > 0) {
|
||||||
|
SetDParam(0, Ship::From(v)->GetDisplayEffectiveMaxSpeed());
|
||||||
|
DrawString(left, right, y + 4 * FONT_HEIGHT_NORMAL + 4, STR_NEED_REPAIR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -194,6 +194,8 @@ void VehicleServiceInDepot(Vehicle *v)
|
|||||||
}
|
}
|
||||||
} else if (v->type == VEH_ROAD) {
|
} else if (v->type == VEH_ROAD) {
|
||||||
RoadVehicle::From(v)->critical_breakdown_count = 0;
|
RoadVehicle::From(v)->critical_breakdown_count = 0;
|
||||||
|
} else if (v->type == VEH_SHIP) {
|
||||||
|
Ship::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
|
||||||
@@ -231,7 +233,8 @@ bool Vehicle::NeedsServicing() const
|
|||||||
(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)) {
|
&& !(this->type == VEH_ROAD && RoadVehicle::From(this)->critical_breakdown_count > 0)
|
||||||
|
&& !(this->type == VEH_SHIP && Ship::From(this)->critical_breakdown_count > 0)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2205,6 +2208,10 @@ bool Vehicle::HandleBreakdown()
|
|||||||
if (RoadVehicle::From(this)->critical_breakdown_count != 255) {
|
if (RoadVehicle::From(this)->critical_breakdown_count != 255) {
|
||||||
RoadVehicle::From(this)->critical_breakdown_count++;
|
RoadVehicle::From(this)->critical_breakdown_count++;
|
||||||
}
|
}
|
||||||
|
} else if (this->type == VEH_SHIP) {
|
||||||
|
if (Ship::From(this)->critical_breakdown_count != 255) {
|
||||||
|
Ship::From(this)->critical_breakdown_count++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* FALL THROUGH */
|
/* FALL THROUGH */
|
||||||
|
@@ -2823,7 +2823,7 @@ struct VehicleDetailsWindow : Window {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case VEH_SHIP:
|
case VEH_SHIP:
|
||||||
size->height = WD_FRAMERECT_TOP + 4 * FONT_HEIGHT_NORMAL + 3 + WD_FRAMERECT_BOTTOM;
|
size->height = WD_FRAMERECT_TOP + 5 * FONT_HEIGHT_NORMAL + 4 + WD_FRAMERECT_BOTTOM;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VEH_AIRCRAFT:
|
case VEH_AIRCRAFT:
|
||||||
|
Reference in New Issue
Block a user