summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/saveload/saveload.cpp3
-rw-r--r--src/saveload/vehicle_sl.cpp13
-rw-r--r--src/ship.h5
-rw-r--r--src/ship_cmd.cpp40
4 files changed, 49 insertions, 12 deletions
diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp
index 7f5b10ac5..29adb40c9 100644
--- a/src/saveload/saveload.cpp
+++ b/src/saveload/saveload.cpp
@@ -273,8 +273,9 @@
* 201 #6885 Extend NewGRF persistant storages.
* 202 #6867 Increase industry cargo slots to 16 in, 16 out
* 203 #7072 Add path cache for ships
+ * 204 #7065 Add extra rotation stages for ships.
*/
-extern const uint16 SAVEGAME_VERSION = 203; ///< Current savegame version of OpenTTD.
+extern const uint16 SAVEGAME_VERSION = 204; ///< Current savegame version of OpenTTD.
SavegameType _savegame_type; ///< type of savegame we are loading
FileToSaveLoad _file_to_saveload; ///< File to save or load in the openttd loop.
diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp
index 1e01f3f67..76fd5af5a 100644
--- a/src/saveload/vehicle_sl.cpp
+++ b/src/saveload/vehicle_sl.cpp
@@ -368,6 +368,14 @@ void AfterLoadVehicles(bool part_of_load)
v->SetServiceIntervalIsPercent(c->settings.vehicle.servint_ispercent);
}
}
+
+ if (IsSavegameVersionBefore(204)) {
+ /* Ship rotation added */
+ Ship *s;
+ FOR_ALL_SHIPS(s) {
+ s->rotation = s->direction;
+ }
+ }
}
CheckValidVehicles();
@@ -753,8 +761,9 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
static const SaveLoad _ship_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_SHIP),
SLE_VEH_INCLUDE(),
- SLE_VAR(Ship, state, SLE_UINT8),
- SLE_CONDDEQUE(Ship, path, SLE_UINT8, 203, SL_MAX_VERSION),
+ SLE_VAR(Ship, state, SLE_UINT8),
+ SLE_CONDDEQUE(Ship, path, SLE_UINT8, 203, SL_MAX_VERSION),
+ SLE_CONDVAR(Ship, rotation, SLE_UINT8, 204, SL_MAX_VERSION),
SLE_CONDNULL(16, 2, 143), // old reserved space
diff --git a/src/ship.h b/src/ship.h
index 6e73332a5..adbc32228 100644
--- a/src/ship.h
+++ b/src/ship.h
@@ -26,8 +26,9 @@ typedef std::deque<TrackdirByte> ShipPathCache;
* All ships have this type.
*/
struct Ship FINAL : public SpecializedVehicle<Ship, VEH_SHIP> {
- TrackBitsByte state; ///< The "track" the ship is following.
- ShipPathCache path; ///< Cached path.
+ TrackBitsByte state; ///< The "track" the ship is following.
+ ShipPathCache path; ///< Cached path.
+ DirectionByte rotation; ///< Visible direction.
/** We don't want GCC to zero our struct! It already is zeroed and has an index! */
Ship() : SpecializedVehicleBase() {}
diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp
index e3886aa34..4603043d6 100644
--- a/src/ship_cmd.cpp
+++ b/src/ship_cmd.cpp
@@ -129,6 +129,8 @@ void Ship::GetImage(Direction direction, EngineImageType image_type, VehicleSpri
{
uint8 spritenum = this->spritenum;
+ if (image_type == EIT_ON_MAP) direction = this->rotation;
+
if (is_custom_sprite(spritenum)) {
GetCustomVehicleSprite(this, direction, image_type, result);
if (result->IsValid()) return;
@@ -311,7 +313,7 @@ void Ship::UpdateDeltaXY()
{32, 6, -16, -3}, // NW
};
- const int8 *bb = _delta_xy_table[this->direction];
+ const int8 *bb = _delta_xy_table[this->rotation];
this->x_offs = bb[3];
this->y_offs = bb[2];
this->x_extent = bb[1];
@@ -370,10 +372,10 @@ static bool CheckShipLeaveDepot(Ship *v)
if (north_tracks) {
/* Leave towards north */
- v->direction = DiagDirToDir(north_dir);
+ v->rotation = v->direction = DiagDirToDir(north_dir);
} else if (south_tracks) {
/* Leave towards south */
- v->direction = DiagDirToDir(south_dir);
+ v->rotation = v->direction = DiagDirToDir(south_dir);
} else {
/* Both ways blocked */
return false;
@@ -543,7 +545,6 @@ static void ShipController(Ship *v)
{
uint32 r;
const byte *b;
- Direction dir;
Track track;
TrackBits tracks;
@@ -563,6 +564,16 @@ static void ShipController(Ship *v)
v->ShowVisualEffect();
+ /* Rotating on spot */
+ if (v->direction != v->rotation) {
+ if ((v->tick_counter & 7) == 0) {
+ DirDiff diff = DirDifference(v->direction, v->rotation);
+ v->rotation = ChangeDir(v->rotation, diff > DIRDIFF_REVERSE ? DIRDIFF_45LEFT : DIRDIFF_45RIGHT);
+ v->UpdateViewport(true, true);
+ }
+ return;
+ }
+
if (!ShipAccelerate(v)) return;
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
@@ -653,7 +664,22 @@ static void ShipController(Ship *v)
if (old_wc != new_wc) v->UpdateCache();
}
- v->direction = (Direction)b[2];
+ Direction new_direction = (Direction)b[2];
+ DirDiff diff = DirDifference(new_direction, v->direction);
+ switch (diff) {
+ case DIRDIFF_SAME:
+ case DIRDIFF_45RIGHT:
+ case DIRDIFF_45LEFT:
+ /* Continue at speed */
+ v->rotation = v->direction = new_direction;
+ break;
+
+ default:
+ /* Stop for rotation */
+ v->cur_speed = 0;
+ v->direction = new_direction;
+ break;
+ }
}
} else {
/* On a bridge */
@@ -677,8 +703,8 @@ getout:
return;
reverse_direction:
- dir = ReverseDir(v->direction);
- v->direction = dir;
+ v->direction = ReverseDir(v->direction);
+ v->cur_speed = 0;
v->path.clear();
goto getout;
}