Implement improved breakdown speed reductions for ships

pull/306/head
Jonathan G Rennison 3 years ago
parent 282f5f22e3
commit 0748d540e8

@ -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_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_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_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 },

@ -844,6 +844,7 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
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_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

@ -32,6 +32,7 @@ struct Ship FINAL : public SpecializedVehicle<Ship, VEH_SHIP> {
int16 rotation_x_pos; ///< NOSAVE: X Position before rotation.
int16 rotation_y_pos; ///< NOSAVE: Y Position before rotation.
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! */
Ship() : SpecializedVehicleBase() {}
@ -47,7 +48,9 @@ struct Ship FINAL : public SpecializedVehicle<Ship, VEH_SHIP> {
Direction GetMapImageDirection() const { return this->rotation; }
int GetDisplaySpeed() const { return this->cur_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;
bool IsInDepot() const { return this->state == TRACK_BIT_DEPOT; }
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.
*/
@ -439,7 +453,7 @@ static bool ShipAccelerate(Vehicle *v)
uint spd;
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);
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 "spritecache.h"
#include "zoom_func.h"
#include "ship.h"
#include "table/strings.h"
@ -84,4 +85,9 @@ void DrawShipDetails(const Vehicle *v, int left, int right, int y)
/* Draw Transfer credits text */
SetDParam(0, v->cargo.FeederShare());
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) {
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;
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->date_of_last_service + this->service_interval >= _date))
&& !(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;
}
@ -2205,6 +2208,10 @@ bool Vehicle::HandleBreakdown()
if (RoadVehicle::From(this)->critical_breakdown_count != 255) {
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 */

@ -2823,7 +2823,7 @@ struct VehicleDetailsWindow : Window {
break;
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;
case VEH_AIRCRAFT:

Loading…
Cancel
Save