summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2014-09-20 15:46:44 +0000
committerrubidium <rubidium@openttd.org>2014-09-20 15:46:44 +0000
commit9e0f4b3847469194856cc24e6ce666edf9d78fa2 (patch)
tree22273aedab16b095f6f6e8e81d6263e9df708f28 /src
parent6c2abf0930c23e7da82a892fb37c97786c245c00 (diff)
downloadopenttd-9e0f4b3847469194856cc24e6ce666edf9d78fa2.tar.xz
(svn r26864) -Codechange: bring a bit more OO into the disaster vehicles
Diffstat (limited to 'src')
-rw-r--r--src/aircraft.h1
-rw-r--r--src/aircraft_cmd.cpp2
-rw-r--r--src/disaster_vehicle.cpp (renamed from src/disaster_cmd.cpp)212
-rw-r--r--src/disaster_vehicle.h61
-rw-r--r--src/saveload/afterload.cpp1
-rw-r--r--src/saveload/oldloader_sl.cpp1
-rw-r--r--src/saveload/vehicle_sl.cpp1
-rw-r--r--src/vehicle_base.h22
8 files changed, 167 insertions, 134 deletions
diff --git a/src/aircraft.h b/src/aircraft.h
index d151f92a6..a093f3b7f 100644
--- a/src/aircraft.h
+++ b/src/aircraft.h
@@ -30,6 +30,7 @@ enum VehicleAirFlags {
VAF_DEST_TOO_FAR = 0, ///< Next destination is too far away.
};
+static const int ROTOR_Z_OFFSET = 5; ///< Z Offset between helicopter- and rotorsprite.
void HandleAircraftEnterHangar(Aircraft *v);
void GetAircraftSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type);
diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp
index 24a3127e0..74a5235c5 100644
--- a/src/aircraft_cmd.cpp
+++ b/src/aircraft_cmd.cpp
@@ -41,8 +41,6 @@
#include "safeguards.h"
-static const int ROTOR_Z_OFFSET = 5; ///< Z Offset between helicopter- and rotorsprite.
-
static const int PLANE_HOLDING_ALTITUDE = 150; ///< Altitude of planes in holding pattern (= lowest flight altitude).
static const int HELI_FLIGHT_ALTITUDE = 184; ///< Normal flight altitude of helicopters.
diff --git a/src/disaster_cmd.cpp b/src/disaster_vehicle.cpp
index 1ddfbd95c..703893d63 100644
--- a/src/disaster_cmd.cpp
+++ b/src/disaster_vehicle.cpp
@@ -8,7 +8,8 @@
*/
/**
- * @file disaster_cmd.cpp
+ * @file disaster_vehicle.cpp
+ *
* All disaster/easter egg vehicles are handled here.
* The general flow of control for the disaster vehicles is as follows:
* <ol>
@@ -26,6 +27,8 @@
#include "stdafx.h"
+#include "aircraft.h"
+#include "disaster_vehicle.h"
#include "industry.h"
#include "station_base.h"
#include "command_func.h"
@@ -52,24 +55,6 @@
/** Delay counter for considering the next disaster. */
uint16 _disaster_delay;
-enum DisasterSubType {
- ST_ZEPPELINER,
- ST_ZEPPELINER_SHADOW,
- ST_SMALL_UFO,
- ST_SMALL_UFO_SHADOW,
- ST_AIRPLANE,
- ST_AIRPLANE_SHADOW,
- ST_HELICOPTER,
- ST_HELICOPTER_SHADOW,
- ST_HELICOPTER_ROTORS,
- ST_BIG_UFO,
- ST_BIG_UFO_SHADOW,
- ST_BIG_UFO_DESTROYER,
- ST_BIG_UFO_DESTROYER_SHADOW,
- ST_SMALL_SUBMARINE,
- ST_BIG_SUBMARINE,
-};
-
static const uint INITIAL_DISASTER_VEHICLE_ZPOS = 135; ///< Initial Z position of flying disaster vehicles.
static void DisasterClearSquare(TileIndex tile)
@@ -125,46 +110,86 @@ static const SpriteID * const _disaster_images[] = {
_disaster_images_4, _disaster_images_5, ///< small and big submarine sprites
};
-static void DisasterVehicleUpdateImage(DisasterVehicle *v)
+void DisasterVehicle::UpdateImage()
{
- SpriteID img = v->image_override;
- if (img == 0) img = _disaster_images[v->subtype][v->direction];
- v->cur_image = img;
+ SpriteID img = this->image_override;
+ if (img == 0) img = _disaster_images[this->subtype][this->direction];
+ this->cur_image = img;
}
/**
- * Initialize a disaster vehicle. These vehicles are of type VEH_DISASTER, are unclickable
- * and owned by nobody
+ * Construct the disaster vehicle.
+ * @param x The X coordinate.
+ * @param y The Y coordinate.
+ * @param direction The direction the vehicle is facing.
+ * @param subtype The sub type of vehicle.
+ * @param big_ufo_destroyer_target The target for the UFO destroyer.
*/
-static void InitializeDisasterVehicle(DisasterVehicle *v, int x, int y, int z, Direction direction, byte subtype)
-{
- v->x_pos = x;
- v->y_pos = y;
- v->z_pos = z;
- v->tile = TileVirtXY(x, y);
- v->direction = direction;
- v->subtype = subtype;
- v->UpdateDeltaXY(INVALID_DIR);
- v->owner = OWNER_NONE;
- v->vehstatus = VS_UNCLICKABLE;
- v->image_override = 0;
- v->current_order.Free();
-
- DisasterVehicleUpdateImage(v);
- v->UpdatePositionAndViewport();
+DisasterVehicle::DisasterVehicle(int x, int y, Direction direction, DisasterSubType subtype, VehicleID big_ufo_destroyer_target) :
+ SpecializedVehicleBase(), big_ufo_destroyer_target(big_ufo_destroyer_target)
+{
+ this->x_pos = x;
+ this->y_pos = y;
+ switch (subtype) {
+ case ST_ZEPPELINER:
+ case ST_SMALL_UFO:
+ case ST_AIRPLANE:
+ case ST_HELICOPTER:
+ case ST_BIG_UFO:
+ case ST_BIG_UFO_DESTROYER:
+ this->z_pos = INITIAL_DISASTER_VEHICLE_ZPOS;
+ break;
+
+ case ST_HELICOPTER_ROTORS:
+ this->z_pos = INITIAL_DISASTER_VEHICLE_ZPOS + ROTOR_Z_OFFSET;
+ break;
+
+ case ST_SMALL_SUBMARINE:
+ case ST_BIG_SUBMARINE:
+ this->z_pos = 0;
+ break;
+
+ case ST_ZEPPELINER_SHADOW:
+ case ST_SMALL_UFO_SHADOW:
+ case ST_AIRPLANE_SHADOW:
+ case ST_HELICOPTER_SHADOW:
+ case ST_BIG_UFO_SHADOW:
+ case ST_BIG_UFO_DESTROYER_SHADOW:
+ this->z_pos = 0;
+ this->vehstatus |= VS_SHADOW;
+ break;
+ }
+
+ this->direction = direction;
+ this->tile = TileVirtXY(x, y);
+ this->subtype = subtype;
+ this->UpdateDeltaXY(INVALID_DIR);
+ this->owner = OWNER_NONE;
+ this->vehstatus = VS_UNCLICKABLE;
+ this->image_override = 0;
+ this->current_order.Free();
+
+ this->UpdateImage();
+ this->UpdatePositionAndViewport();
}
-static void SetDisasterVehiclePos(DisasterVehicle *v, int x, int y, int z)
+/**
+ * Update the position of the vehicle.
+ * @param x The new X-coordinate.
+ * @param y The new Y-coordinate.
+ * @param z The new Z-coordinate.
+ */
+void DisasterVehicle::UpdatePosition(int x, int y, int z)
{
- v->x_pos = x;
- v->y_pos = y;
- v->z_pos = z;
- v->tile = TileVirtXY(x, y);
+ this->x_pos = x;
+ this->y_pos = y;
+ this->z_pos = z;
+ this->tile = TileVirtXY(x, y);
- DisasterVehicleUpdateImage(v);
- v->UpdatePositionAndViewport();
+ this->UpdateImage();
+ this->UpdatePositionAndViewport();
- DisasterVehicle *u = v->Next();
+ DisasterVehicle *u = this->Next();
if (u != NULL) {
int safe_x = Clamp(x, 0, MapMaxX() * TILE_SIZE);
int safe_y = Clamp(y - 1, 0, MapMaxY() * TILE_SIZE);
@@ -173,15 +198,15 @@ static void SetDisasterVehiclePos(DisasterVehicle *v, int x, int y, int z)
u->y_pos = y - 1 - (max(z - GetSlopePixelZ(safe_x, safe_y), 0) >> 3);
safe_y = Clamp(u->y_pos, 0, MapMaxY() * TILE_SIZE);
u->z_pos = GetSlopePixelZ(safe_x, safe_y);
- u->direction = v->direction;
+ u->direction = this->direction;
- DisasterVehicleUpdateImage(u);
+ u->UpdateImage();
u->UpdatePositionAndViewport();
if ((u = u->Next()) != NULL) {
u->x_pos = x;
u->y_pos = y;
- u->z_pos = z + 5;
+ u->z_pos = z + ROTOR_Z_OFFSET;
u->UpdatePositionAndViewport();
}
}
@@ -204,7 +229,7 @@ static bool DisasterTick_Zeppeliner(DisasterVehicle *v)
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
- SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
+ v->UpdatePosition(gp.x, gp.y, v->z_pos);
if (v->current_order.GetDestination() == 1) {
if (++v->age == 38) {
@@ -242,7 +267,7 @@ static bool DisasterTick_Zeppeliner(DisasterVehicle *v)
AI::NewEvent(GetTileOwner(v->tile), new ScriptEventDisasterZeppelinerCleared(st->index));
}
- SetDisasterVehiclePos(v, v->x_pos, v->y_pos, v->z_pos);
+ v->UpdatePosition(v->x_pos, v->y_pos, v->z_pos);
delete v;
return false;
}
@@ -251,7 +276,7 @@ static bool DisasterTick_Zeppeliner(DisasterVehicle *v)
int y = v->y_pos;
int z = GetSlopePixelZ(x, y);
if (z < v->z_pos) z = v->z_pos - 1;
- SetDisasterVehiclePos(v, x, y, z);
+ v->UpdatePosition(x, y, z);
if (++v->age == 1) {
CreateEffectVehicleRel(v, 0, 7, 8, EV_EXPLOSION_LARGE);
@@ -298,7 +323,7 @@ static bool DisasterTick_Ufo(DisasterVehicle *v)
if (Delta(x, v->x_pos) + Delta(y, v->y_pos) >= (int)TILE_SIZE) {
v->direction = GetDirectionTowards(v, x, y);
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
- SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
+ v->UpdatePosition(gp.x, gp.y, v->z_pos);
return true;
}
if (++v->age < 6) {
@@ -346,7 +371,7 @@ static bool DisasterTick_Ufo(DisasterVehicle *v)
int z = v->z_pos;
if (dist <= TILE_SIZE && z > u->z_pos) z--;
- SetDisasterVehiclePos(v, gp.x, gp.y, z);
+ v->UpdatePosition(gp.x, gp.y, z);
if (z <= u->z_pos && (u->vehstatus & VS_HIDDEN) == 0) {
v->age++;
@@ -401,7 +426,7 @@ static bool DisasterTick_Aircraft(DisasterVehicle *v, uint16 image_override, boo
v->image_override = (v->current_order.GetDestination() == 1 && HasBit(v->tick_counter, 2)) ? image_override : 0;
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
- SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
+ v->UpdatePosition(gp.x, gp.y, v->z_pos);
if ((leave_at_top && gp.x < (-10 * (int)TILE_SIZE)) || (!leave_at_top && gp.x > (int)(MapSizeX() * TILE_SIZE + 9 * TILE_SIZE) - 1)) {
delete v;
@@ -498,7 +523,7 @@ static bool DisasterTick_Big_Ufo(DisasterVehicle *v)
v->direction = GetDirectionTowards(v, x, y);
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
- SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
+ v->UpdatePosition(gp.x, gp.y, v->z_pos);
return true;
}
@@ -510,7 +535,7 @@ static bool DisasterTick_Big_Ufo(DisasterVehicle *v)
int z = GetSlopePixelZ(v->x_pos, v->y_pos);
if (z < v->z_pos) {
- SetDisasterVehiclePos(v, v->x_pos, v->y_pos, v->z_pos - 1);
+ v->UpdatePosition(v->x_pos, v->y_pos, v->z_pos - 1);
return true;
}
@@ -534,23 +559,16 @@ static bool DisasterTick_Big_Ufo(DisasterVehicle *v)
delete v;
return false;
}
- DisasterVehicle *u = new DisasterVehicle();
-
- InitializeDisasterVehicle(u, -6 * (int)TILE_SIZE, v->y_pos, INITIAL_DISASTER_VEHICLE_ZPOS, DIR_SW, ST_BIG_UFO_DESTROYER);
- u->big_ufo_destroyer_target = v->index;
-
- DisasterVehicle *w = new DisasterVehicle();
-
+ DisasterVehicle *u = new DisasterVehicle(-6 * (int)TILE_SIZE, v->y_pos, DIR_SW, ST_BIG_UFO_DESTROYER, v->index);
+ DisasterVehicle *w = new DisasterVehicle(-6 * (int)TILE_SIZE, v->y_pos, DIR_SW, ST_BIG_UFO_DESTROYER_SHADOW);
u->SetNext(w);
- InitializeDisasterVehicle(w, -6 * (int)TILE_SIZE, v->y_pos, 0, DIR_SW, ST_BIG_UFO_DESTROYER_SHADOW);
- w->vehstatus |= VS_SHADOW;
} else if (v->current_order.GetDestination() == 0) {
int x = TileX(v->dest_tile) * TILE_SIZE;
int y = TileY(v->dest_tile) * TILE_SIZE;
if (Delta(x, v->x_pos) + Delta(y, v->y_pos) >= (int)TILE_SIZE) {
v->direction = GetDirectionTowards(v, x, y);
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
- SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
+ v->UpdatePosition(gp.x, gp.y, v->z_pos);
return true;
}
@@ -585,7 +603,7 @@ static bool DisasterTick_Big_Ufo_Destroyer(DisasterVehicle *v)
v->tick_counter++;
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
- SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
+ v->UpdatePosition(gp.x, gp.y, v->z_pos);
if (gp.x > (int)(MapSizeX() * TILE_SIZE + 9 * TILE_SIZE) - 1) {
delete v;
@@ -642,7 +660,7 @@ static bool DisasterTick_Submarine(DisasterVehicle *v)
TrackBits trackbits = TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0));
if (trackbits == TRACK_BIT_ALL && !Chance16(1, 90)) {
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
- SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
+ v->UpdatePosition(gp.x, gp.y, v->z_pos);
return true;
}
}
@@ -699,14 +717,10 @@ static void Disaster_Zeppeliner_Init()
}
}
- DisasterVehicle *v = new DisasterVehicle();
- InitializeDisasterVehicle(v, x, 0, INITIAL_DISASTER_VEHICLE_ZPOS, DIR_SE, ST_ZEPPELINER);
-
+ DisasterVehicle *v = new DisasterVehicle(x, 0, DIR_SE, ST_ZEPPELINER);
/* Allocate shadow */
- DisasterVehicle *u = new DisasterVehicle();
+ DisasterVehicle *u = new DisasterVehicle(x, 0, DIR_SE, ST_ZEPPELINER_SHADOW);
v->SetNext(u);
- InitializeDisasterVehicle(u, x, 0, 0, DIR_SE, ST_ZEPPELINER_SHADOW);
- u->vehstatus |= VS_SHADOW;
}
@@ -718,18 +732,13 @@ static void Disaster_Small_Ufo_Init()
{
if (!Vehicle::CanAllocateItem(2)) return;
- DisasterVehicle *v = new DisasterVehicle();
int x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2;
-
- InitializeDisasterVehicle(v, x, 0, INITIAL_DISASTER_VEHICLE_ZPOS, DIR_SE, ST_SMALL_UFO);
+ DisasterVehicle *v = new DisasterVehicle(x, 0, DIR_SE, ST_SMALL_UFO);
v->dest_tile = TileXY(MapSizeX() / 2, MapSizeY() / 2);
- v->age = 0;
/* Allocate shadow */
- DisasterVehicle *u = new DisasterVehicle();
+ DisasterVehicle *u = new DisasterVehicle(x, 0, DIR_SE, ST_SMALL_UFO_SHADOW);
v->SetNext(u);
- InitializeDisasterVehicle(u, x, 0, 0, DIR_SE, ST_SMALL_UFO_SHADOW);
- u->vehstatus |= VS_SHADOW;
}
@@ -749,18 +758,13 @@ static void Disaster_Airplane_Init()
if (found == NULL) return;
- DisasterVehicle *v = new DisasterVehicle();
-
/* Start from the bottom (south side) of the map */
int x = (MapSizeX() + 9) * TILE_SIZE - 1;
int y = TileY(found->location.tile) * TILE_SIZE + 37;
- InitializeDisasterVehicle(v, x, y, INITIAL_DISASTER_VEHICLE_ZPOS, DIR_NE, ST_AIRPLANE);
-
- DisasterVehicle *u = new DisasterVehicle();
+ DisasterVehicle *v = new DisasterVehicle(x, y, DIR_NE, ST_AIRPLANE);
+ DisasterVehicle *u = new DisasterVehicle(x, y, DIR_NE, ST_AIRPLANE_SHADOW);
v->SetNext(u);
- InitializeDisasterVehicle(u, x, y, 0, DIR_SE, ST_AIRPLANE_SHADOW);
- u->vehstatus |= VS_SHADOW;
}
@@ -780,21 +784,15 @@ static void Disaster_Helicopter_Init()
if (found == NULL) return;
- DisasterVehicle *v = new DisasterVehicle();
-
int x = -16 * (int)TILE_SIZE;
int y = TileY(found->location.tile) * TILE_SIZE + 37;
- InitializeDisasterVehicle(v, x, y, INITIAL_DISASTER_VEHICLE_ZPOS, DIR_SW, ST_HELICOPTER);
-
- DisasterVehicle *u = new DisasterVehicle();
+ DisasterVehicle *v = new DisasterVehicle(x, y, DIR_SW, ST_HELICOPTER);
+ DisasterVehicle *u = new DisasterVehicle(x, y, DIR_SW, ST_HELICOPTER_SHADOW);
v->SetNext(u);
- InitializeDisasterVehicle(u, x, y, 0, DIR_SW, ST_HELICOPTER_SHADOW);
- u->vehstatus |= VS_SHADOW;
- DisasterVehicle *w = new DisasterVehicle();
+ DisasterVehicle *w = new DisasterVehicle(x, y, DIR_SW, ST_HELICOPTER_ROTORS);
u->SetNext(w);
- InitializeDisasterVehicle(w, x, y, 140, DIR_SW, ST_HELICOPTER_ROTORS);
}
@@ -804,19 +802,15 @@ static void Disaster_Big_Ufo_Init()
{
if (!Vehicle::CanAllocateItem(2)) return;
- DisasterVehicle *v = new DisasterVehicle();
int x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2;
int y = MapMaxX() * TILE_SIZE - 1;
- InitializeDisasterVehicle(v, x, y, INITIAL_DISASTER_VEHICLE_ZPOS, DIR_NW, ST_BIG_UFO);
+ DisasterVehicle *v = new DisasterVehicle(x, y, DIR_NW, ST_BIG_UFO);
v->dest_tile = TileXY(MapSizeX() / 2, MapSizeY() / 2);
- v->age = 0;
/* Allocate shadow */
- DisasterVehicle *u = new DisasterVehicle();
+ DisasterVehicle *u = new DisasterVehicle(x, y, DIR_NW, ST_BIG_UFO_SHADOW);
v->SetNext(u);
- InitializeDisasterVehicle(u, x, y, 0, DIR_NW, ST_BIG_UFO_SHADOW);
- u->vehstatus |= VS_SHADOW;
}
@@ -839,9 +833,7 @@ static void Disaster_Submarine_Init(DisasterSubType subtype)
}
if (!IsWaterTile(TileVirtXY(x, y))) return;
- DisasterVehicle *v = new DisasterVehicle();
- InitializeDisasterVehicle(v, x, y, 0, dir, subtype);
- v->age = 0;
+ new DisasterVehicle(x, y, dir, subtype);
}
/* Curious submarine #1, just floats around */
diff --git a/src/disaster_vehicle.h b/src/disaster_vehicle.h
new file mode 100644
index 000000000..0b2005d92
--- /dev/null
+++ b/src/disaster_vehicle.h
@@ -0,0 +1,61 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file disaster_vehicle.h All disaster vehicles. */
+
+#ifndef DISASTER_VEHICLE_H
+#define DISASTER_VEHICLE_H
+
+#include "vehicle_base.h"
+
+/** Different sub types of disaster vehicles. */
+enum DisasterSubType {
+ ST_ZEPPELINER, ///< Zeppelin, crashes at airports.
+ ST_ZEPPELINER_SHADOW, ///< Shadow of the zeppelin.
+ ST_SMALL_UFO, ///< Small UFO, tries to find a road vehicle to destroy.
+ ST_SMALL_UFO_SHADOW, ///< Shadow of small UFO
+ ST_AIRPLANE, ///< Airplane destroying an oil refinery
+ ST_AIRPLANE_SHADOW, ///< Shadow of airplane
+ ST_HELICOPTER, ///< Helicopter destroying a factory.
+ ST_HELICOPTER_SHADOW, ///< Shadow of helicopter.
+ ST_HELICOPTER_ROTORS, ///< Rotors of helicopter.
+ ST_BIG_UFO, ///< Big UFO, finds a piece of railroad to "park" on
+ ST_BIG_UFO_SHADOW, ///< Shadow of the big UFO
+ ST_BIG_UFO_DESTROYER, ///< Aircraft the will bomb the big UFO
+ ST_BIG_UFO_DESTROYER_SHADOW, ///< Shadow of the aircraft.
+ ST_SMALL_SUBMARINE, ///< Small submarine, pops up in the oceans but doesn't do anything
+ ST_BIG_SUBMARINE, ///< Big submarine, pops up in the oceans but doesn't do anything
+};
+
+/**
+ * Disasters, like submarines, skyrangers and their shadows, belong to this class.
+ */
+struct DisasterVehicle FINAL : public SpecializedVehicle<DisasterVehicle, VEH_DISASTER> {
+ SpriteID image_override; ///< Override for the default disaster vehicle sprite.
+ VehicleID big_ufo_destroyer_target; ///< The big UFO that this destroyer is supposed to bomb.
+
+ /** For use by saveload. */
+ DisasterVehicle() : SpecializedVehicleBase() {}
+ DisasterVehicle(int x, int y, Direction direction, DisasterSubType subtype, VehicleID big_ufo_destroyer_target = VEH_INVALID);
+ /** We want to 'destruct' the right class. */
+ virtual ~DisasterVehicle() {}
+
+ void UpdatePosition(int x, int y, int z);
+ void UpdateDeltaXY(Direction direction);
+ void UpdateImage();
+ bool Tick();
+};
+
+/**
+ * Iterate over disaster vehicles.
+ * @param var The variable used to iterate over.
+ */
+#define FOR_ALL_DISASTERVEHICLES(var) FOR_ALL_VEHICLES_OF_TYPE(DisasterVehicle, var)
+
+#endif /* DISASTER_VEHICLE_H */
diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp
index ae6b6a774..e5a1ecfd2 100644
--- a/src/saveload/afterload.cpp
+++ b/src/saveload/afterload.cpp
@@ -53,6 +53,7 @@
#include "../news_func.h"
#include "../order_backup.h"
#include "../error.h"
+#include "../disaster_vehicle.h"
#include "saveload_internal.h"
diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp
index d3c63d951..61fa87a5b 100644
--- a/src/saveload/oldloader_sl.cpp
+++ b/src/saveload/oldloader_sl.cpp
@@ -27,6 +27,7 @@
#include "../effectvehicle_base.h"
#include "../engine_func.h"
#include "../company_base.h"
+#include "../disaster_vehicle.h"
#include "saveload_internal.h"
#include "oldloader.h"
diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp
index 40f73bdba..af14d2d67 100644
--- a/src/saveload/vehicle_sl.cpp
+++ b/src/saveload/vehicle_sl.cpp
@@ -19,6 +19,7 @@
#include "../effectvehicle_base.h"
#include "../company_base.h"
#include "../company_func.h"
+#include "../disaster_vehicle.h"
#include "saveload.h"
diff --git a/src/vehicle_base.h b/src/vehicle_base.h
index 26a76dc85..59584da78 100644
--- a/src/vehicle_base.h
+++ b/src/vehicle_base.h
@@ -1088,28 +1088,6 @@ struct SpecializedVehicle : public Vehicle {
*/
#define FOR_ALL_VEHICLES_OF_TYPE(name, var) FOR_ALL_ITEMS_FROM(name, vehicle_index, var, 0) if (var->type == name::EXPECTED_TYPE)
-/**
- * Disasters, like submarines, skyrangers and their shadows, belong to this class.
- */
-struct DisasterVehicle FINAL : public SpecializedVehicle<DisasterVehicle, VEH_DISASTER> {
- SpriteID image_override; ///< Override for the default disaster vehicle sprite.
- VehicleID big_ufo_destroyer_target; ///< The big UFO that this destroyer is supposed to bomb.
-
- /** We don't want GCC to zero our struct! It already is zeroed and has an index! */
- DisasterVehicle() : SpecializedVehicleBase() {}
- /** We want to 'destruct' the right class. */
- virtual ~DisasterVehicle() {}
-
- void UpdateDeltaXY(Direction direction);
- bool Tick();
-};
-
-/**
- * Iterate over disaster vehicles.
- * @param var The variable used to iterate over.
- */
-#define FOR_ALL_DISASTERVEHICLES(var) FOR_ALL_VEHICLES_OF_TYPE(DisasterVehicle, var)
-
/** Generates sequence of free UnitID numbers */
struct FreeUnitIDGenerator {
bool *cache; ///< array of occupied unit id numbers