From 5a55c4a934256e3dc0d1cb66fbe0d427237895bd Mon Sep 17 00:00:00 2001 From: Koen Bussemaker Date: Fri, 28 Apr 2023 21:23:59 +0200 Subject: [PATCH] Feature: [NewGRF] Allow higher max speeds for ships --- src/engine.cpp | 2 ++ src/engine_type.h | 1 + src/newgrf.cpp | 10 ++++++++- src/saveload/afterload.cpp | 7 +++++++ src/saveload/saveload.h | 1 + src/ship_cmd.cpp | 6 ++++-- src/table/engines.h | 43 +++++++++++++++++++------------------- 7 files changed, 46 insertions(+), 24 deletions(-) diff --git a/src/engine.cpp b/src/engine.cpp index c00d05824a..c46f7bb843 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -87,6 +87,8 @@ Engine::Engine(VehicleType type, EngineID base) if (type == VEH_ROAD) this->u.road.tractive_effort = 0x4C; /* Aircraft must have INVALID_CARGO as default, as there is no property */ if (type == VEH_AIRCRAFT) this->info.cargo_type = INVALID_CARGO; + /* Ships must have a non-zero acceleration. */ + if (type == VEH_SHIP) this->u.ship.acceleration = 1; /* Set visual effect to the default value */ switch (type) { case VEH_TRAIN: this->u.rail.visual_effect = VE_DEFAULT; break; diff --git a/src/engine_type.h b/src/engine_type.h index 809cb408e6..7716fd92e7 100644 --- a/src/engine_type.h +++ b/src/engine_type.h @@ -67,6 +67,7 @@ struct RailVehicleInfo { struct ShipVehicleInfo { byte image_index; byte cost_factor; + uint8_t acceleration; ///< Acceleration (1 unit = 1/3.2 mph per tick = 0.5 km-ish/h per tick) uint16_t max_speed; ///< Maximum speed (1 unit = 1/3.2 mph = 0.5 km-ish/h) uint16_t capacity; byte running_cost; diff --git a/src/newgrf.cpp b/src/newgrf.cpp index c13c30d1ee..4f22d04f37 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -1586,7 +1586,7 @@ static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop svi->cost_factor = buf->ReadByte(); break; - case PROP_SHIP_SPEED: // 0x0B Speed (1 unit is 0.5 km-ish/h) + case PROP_SHIP_SPEED: // 0x0B Speed (1 unit is 0.5 km-ish/h). Use 0x23 to achieve higher speeds. svi->max_speed = buf->ReadByte(); break; @@ -1714,6 +1714,14 @@ static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop SB(ei->callback_mask, 8, 8, buf->ReadByte()); break; + case 0x23: // Speed (1 unit is 0.5 km-ish/h) + svi->max_speed = buf->ReadWord(); + break; + + case 0x24: // Acceleration (1 unit is 0.5 km-ish/h per tick) + svi->acceleration = std::max(1, buf->ReadByte()); + break; + default: ret = CommonVehicleChangeInfo(ei, prop, buf); break; diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 31052fcc52..25f3fe6451 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -3273,6 +3273,13 @@ bool AfterLoadGame() } } + if (IsSavegameVersionBefore(SLV_SHIP_ACCELERATION)) { + /* NewGRF acceleration information was added to ships. */ + for (Ship *s : Ship::Iterate()) { + if (s->acceleration == 0) s->acceleration = ShipVehInfo(s->engine_type)->acceleration; + } + } + for (Company *c : Company::Iterate()) { UpdateCompanyLiveries(c); } diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 4564b9d4f3..82c2d4b1f2 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -371,6 +371,7 @@ enum SaveLoadVersion : uint16_t { SLV_ECONOMY_DATE, ///< 326 PR#10700 Split calendar and economy timers and dates. SLV_ECONOMY_MODE_TIMEKEEPING_UNITS, ///< 327 PR#11341 Mode to display economy measurements in wallclock units. SLV_CALENDAR_SUB_DATE_FRACT, ///< 328 PR#11428 Add sub_date_fract to measure calendar days. + SLV_SHIP_ACCELERATION, ///< 329 PR#10734 Start using Vehicle's acceleration field for ships too. SL_MAX_VERSION, ///< Highest possible saveload version }; diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index 4637357196..34d96bf273 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -449,8 +449,7 @@ static bool CheckShipLeaveDepot(Ship *v) static uint ShipAccelerate(Vehicle *v) { uint speed; - - speed = std::min(v->cur_speed + 1, v->vcache.cached_max_speed); + speed = std::min(v->cur_speed + v->acceleration, v->vcache.cached_max_speed); speed = std::min(speed, v->current_order.GetMaxSpeed() * 2); /* updates statusbar only if speed have changed to save CPU time */ @@ -745,6 +744,8 @@ static void ShipController(Ship *v) const uint number_of_steps = ShipAccelerate(v); for (uint i = 0; i < number_of_steps; ++i) { + if (ShipMoveUpDownOnLock(v)) return; + GetNewVehiclePosResult gp = GetNewVehiclePos(v); if (v->state != TRACK_BIT_WORMHOLE) { /* Not on a bridge */ @@ -949,6 +950,7 @@ CommandCost CmdBuildShip(DoCommandFlag flags, TileIndex tile, const Engine *e, V v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY); v->random_bits = Random(); + v->acceleration = svi->acceleration; v->UpdateCache(); if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); diff --git a/src/table/engines.h b/src/table/engines.h index 9fc31efb02..ec02f6b908 100644 --- a/src/table/engines.h +++ b/src/table/engines.h @@ -557,29 +557,30 @@ static const RailVehicleInfo _orig_rail_vehicle_info[] = { * @see ShipVehicleInfo * @param a image_index * @param b cost_factor - * @param c max_speed (1 unit = 1/3.2 mph = 0.5 km-ish/h) - * @param d capacity (persons, bags, tons, pieces, items, cubic metres, ...) - * @param e running_cost - * @param f sound effect - * @param g refittable + * @param c acceleration (1 unit = 1/3.2 mph per tick = 0.5 km-ish/h per tick) + * @param d max_speed (1 unit = 1/3.2 mph = 0.5 km-ish/h) + * @param e capacity (persons, bags, tons, pieces, items, cubic metres, ...) + * @param f running_cost + * @param g sound effect + * @param h refittable */ -#define SVI(a, b, c, d, e, f, g) { a, b, c, d, e, f, g, VE_DEFAULT, 0, 0 } +#define SVI(a, b, c, d, e, f, g, h) { a, b, c, d, e, f, g, h, VE_DEFAULT, 0, 0 } static const ShipVehicleInfo _orig_ship_vehicle_info[] = { - /* image_index capacity refittable - * | cost_factor running_cost | - * | | max_speed | sfx | - * | | | | | | | */ - SVI( 1, 160, 48, 220, 140, SND_06_DEPARTURE_CARGO_SHIP, 0 ), // 0 MPS Oil Tanker - SVI( 1, 176, 80, 350, 125, SND_06_DEPARTURE_CARGO_SHIP, 0 ), // 1 CS-Inc. Oil Tanker - SVI( 2, 96, 64, 100, 90, SND_07_DEPARTURE_FERRY, 0 ), // 2 MPS Passenger Ferry - SVI( 2, 112, 128, 130, 80, SND_07_DEPARTURE_FERRY, 0 ), // 3 FFP Passenger Ferry - SVI( 3, 148, 224, 100, 190, SND_07_DEPARTURE_FERRY, 0 ), // 4 Bakewell 300 Hovercraft - SVI( 2, 96, 64, 100, 90, SND_07_DEPARTURE_FERRY, 0 ), // 5 Chugger-Chug Passenger Ferry - SVI( 2, 112, 128, 130, 80, SND_07_DEPARTURE_FERRY, 0 ), // 6 Shivershake Passenger Ferry - SVI( 0, 128, 48, 160, 150, SND_06_DEPARTURE_CARGO_SHIP, 1 ), // 7 Yate Cargo ship - SVI( 0, 144, 80, 190, 113, SND_06_DEPARTURE_CARGO_SHIP, 1 ), // 8 Bakewell Cargo ship - SVI( 0, 128, 48, 160, 150, SND_06_DEPARTURE_CARGO_SHIP, 1 ), // 9 Mightymover Cargo ship - SVI( 0, 144, 80, 190, 113, SND_06_DEPARTURE_CARGO_SHIP, 1 ), // 10 Powernaut Cargo ship + /* image_index max_speed sfx refittable + * | cost_factor capacity | | + * | | acceleration running_cost | + * | | | | | | | | */ + SVI( 1, 160, 1, 48, 220, 140, SND_06_DEPARTURE_CARGO_SHIP, 0 ), // 0 MPS Oil Tanker + SVI( 1, 176, 1, 80, 350, 125, SND_06_DEPARTURE_CARGO_SHIP, 0 ), // 1 CS-Inc. Oil Tanker + SVI( 2, 96, 1, 64, 100, 90, SND_07_DEPARTURE_FERRY, 0 ), // 2 MPS Passenger Ferry + SVI( 2, 112, 1, 128, 130, 80, SND_07_DEPARTURE_FERRY, 0 ), // 3 FFP Passenger Ferry + SVI( 3, 148, 1, 224, 100, 190, SND_07_DEPARTURE_FERRY, 0 ), // 4 Bakewell 300 Hovercraft + SVI( 2, 96, 1, 64, 100, 90, SND_07_DEPARTURE_FERRY, 0 ), // 5 Chugger-Chug Passenger Ferry + SVI( 2, 112, 1, 128, 130, 80, SND_07_DEPARTURE_FERRY, 0 ), // 6 Shivershake Passenger Ferry + SVI( 0, 128, 1, 48, 160, 150, SND_06_DEPARTURE_CARGO_SHIP, 1 ), // 7 Yate Cargo ship + SVI( 0, 144, 1, 80, 190, 113, SND_06_DEPARTURE_CARGO_SHIP, 1 ), // 8 Bakewell Cargo ship + SVI( 0, 128, 1, 48, 160, 150, SND_06_DEPARTURE_CARGO_SHIP, 1 ), // 9 Mightymover Cargo ship + SVI( 0, 144, 1, 80, 190, 113, SND_06_DEPARTURE_CARGO_SHIP, 1 ), // 10 Powernaut Cargo ship }; #undef SVI