(svn r9760) -Codechange: remove the need for saving some vehicle variables.
authorrubidium
Tue, 01 May 2007 16:35:14 +0000
changeset 6558 c88e142f896e
parent 6557 36dcf7f8a84c
child 6559 354d355736ab
(svn r9760) -Codechange: remove the need for saving some vehicle variables.
src/aircraft.h
src/aircraft_cmd.cpp
src/disaster_cmd.cpp
src/players.cpp
src/roadveh.h
src/roadveh_cmd.cpp
src/ship.h
src/ship_cmd.cpp
src/train.h
src/train_cmd.cpp
src/vehicle.cpp
src/vehicle.h
--- a/src/aircraft.h	Tue May 01 15:25:00 2007 +0000
+++ b/src/aircraft.h	Tue May 01 16:35:14 2007 +0000
@@ -132,6 +132,7 @@
 
 	const char *GetTypeString() { return "aircraft"; }
 	void MarkDirty();
+	void UpdateDeltaXY(Direction direction);
 };
 
 #endif /* AIRCRAFT_H */
--- a/src/aircraft_cmd.cpp	Tue May 01 15:25:00 2007 +0000
+++ b/src/aircraft_cmd.cpp	Tue May 01 16:35:14 2007 +0000
@@ -33,6 +33,35 @@
 #include "spritecache.h"
 #include "cargotype.h"
 
+void Aircraft::UpdateDeltaXY(Direction direction)
+{
+	uint32 x;
+#define MKIT(a, b, c, d) ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | ((d & 0xFF) << 0)
+	switch (this->subtype) {
+		default: NOT_REACHED();
+		case AIR_AIRCRAFT:
+		case AIR_HELICOPTER:
+			switch (this->u.air.state) {
+				case ENDTAKEOFF:
+				case LANDING:
+				case HELILANDING:
+				case FLYING:     x = MKIT(24, 24, -1, -1); break;
+				default:         x = MKIT( 2,  2, -1, -1); break;
+			}
+			this->z_height = 5;
+			break;
+		case AIR_SHADOW:     this->z_height = 1; x = MKIT(2,  2,  0,  0); break;
+		case AIR_ROTOR:      this->z_height = 1; x = MKIT(2,  2, -1, -1); break;
+	}
+#undef MKIT
+
+	this->x_offs        = GB(x,  0, 8);
+	this->y_offs        = GB(x,  8, 8);
+	this->sprite_width  = GB(x, 16, 8);
+	this->sprite_height = GB(x, 24, 8);
+}
+
+
 /** this maps the terminal to its corresponding state and block flag
  *  currently set for 10 terms, 4 helipads */
 static const byte _airport_terminal_state[] = {2, 3, 4, 5, 6, 7, 19, 20, 0, 0, 8, 9, 21, 22};
@@ -287,15 +316,8 @@
 		u->z_pos = GetSlopeZ(x, y);
 		v->z_pos = u->z_pos + 1;
 
-		v->x_offs = v->y_offs = -1;
 //		u->delta_x = u->delta_y = 0;
 
-		v->sprite_width = v->sprite_height = 2;
-		v->z_height = 5;
-
-		u->sprite_width = u->sprite_height = 2;
-		u->z_height = 1;
-
 		v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
 		u->vehstatus = VS_HIDDEN | VS_UNCLICKABLE | VS_SHADOW;
 
@@ -323,9 +345,11 @@
 		v->engine_type = p1;
 
 		v->subtype = (avi->subtype & AIR_CTOL ? AIR_AIRCRAFT : AIR_HELICOPTER);
+		v->UpdateDeltaXY(INVALID_DIR);
 		v->value = value;
 
 		u->subtype = AIR_SHADOW;
+		u->UpdateDeltaXY(INVALID_DIR);
 
 		/* Danger, Will Robinson!
 		 * If the aircraft is refittable, but cannot be refitted to
@@ -411,9 +435,6 @@
 			w->x_pos = v->x_pos;
 			w->y_pos = v->y_pos;
 			w->z_pos = v->z_pos + 5;
-			w->x_offs = w->y_offs = -1;
-			w->sprite_width = w->sprite_height = 2;
-			w->z_height = 1;
 			w->vehstatus = VS_HIDDEN | VS_UNCLICKABLE;
 			w->spritenum = 0xFF;
 			w->subtype = AIR_ROTOR;
@@ -421,6 +442,7 @@
 			w->random_bits = VehicleRandomBits();
 			/* Use rotor's air.state to store the rotor animation frame */
 			w->u.air.state = HRS_ROTOR_STOPPED;
+			w->UpdateDeltaXY(INVALID_DIR);
 			VehiclePositionChanged(w);
 		}
 
@@ -1510,14 +1532,10 @@
 	v->BeginLoading();
 }
 
-static void AircraftLand(Vehicle *v)
-{
-	v->sprite_width = v->sprite_height = 2;
-}
-
 static void AircraftLandAirplane(Vehicle *v)
 {
-	AircraftLand(v);
+	v->UpdateDeltaXY(INVALID_DIR);
+
 	if (!PlayVehicleSound(v, VSE_TOUCHDOWN)) {
 		SndPlayVehicleFx(SND_17_SKID_PLANE, v);
 	}
@@ -1676,8 +1694,8 @@
 
 static void AircraftEventHandler_StartTakeOff(Vehicle *v, const AirportFTAClass *apc)
 {
-	v->sprite_width = v->sprite_height = 24; // ??? no idea what this is
 	v->u.air.state = ENDTAKEOFF;
+	v->UpdateDeltaXY(INVALID_DIR);
 }
 
 static void AircraftEventHandler_EndTakeOff(Vehicle *v, const AirportFTAClass *apc)
@@ -1690,8 +1708,9 @@
 static void AircraftEventHandler_HeliTakeOff(Vehicle *v, const AirportFTAClass *apc)
 {
 	const Player* p = GetPlayer(v->owner);
-	v->sprite_width = v->sprite_height = 24; // ??? no idea what this is
 	v->u.air.state = FLYING;
+	v->UpdateDeltaXY(INVALID_DIR);
+
 	/* get the next position to go to, differs per airport */
 	AircraftNextAirportPos_and_Order(v);
 
@@ -1749,8 +1768,9 @@
 
 static void AircraftEventHandler_Landing(Vehicle *v, const AirportFTAClass *apc)
 {
+	v->u.air.state = ENDLANDING;
 	AircraftLandAirplane(v);  // maybe crash airplane
-	v->u.air.state = ENDLANDING;
+
 	/* check if the aircraft needs to be replaced or renewed and send it to a hangar if needed */
 	if (v->current_order.type != OT_GOTO_DEPOT && v->owner == _local_player) {
 		/* only the vehicle owner needs to calculate the rest (locally) */
@@ -1767,8 +1787,8 @@
 
 static void AircraftEventHandler_HeliLanding(Vehicle *v, const AirportFTAClass *apc)
 {
-	AircraftLand(v); // helicopters don't crash
 	v->u.air.state = HELIENDLANDING;
+	v->UpdateDeltaXY(INVALID_DIR);
 }
 
 static void AircraftEventHandler_EndLanding(Vehicle *v, const AirportFTAClass *apc)
--- a/src/disaster_cmd.cpp	Tue May 01 15:25:00 2007 +0000
+++ b/src/disaster_cmd.cpp	Tue May 01 16:35:14 2007 +0000
@@ -116,7 +116,6 @@
 	v->cur_image = img;
 }
 
-
 /** Initialize a disaster vehicle. These vehicles are of type VEH_DISASTER, are unclickable
  * and owned by nobody */
 static void InitializeDisasterVehicle(Vehicle *v, int x, int y, byte z, Direction direction, byte subtype)
@@ -128,11 +127,7 @@
 	v->tile = TileVirtXY(x, y);
 	v->direction = direction;
 	v->subtype = subtype;
-	v->x_offs = -1;
-	v->y_offs = -1;
-	v->sprite_width = 2;
-	v->sprite_height = 2;
-	v->z_height = 5;
+	v->UpdateDeltaXY(INVALID_DIR);
 	v->owner = OWNER_NONE;
 	v->vehstatus = VS_UNCLICKABLE;
 	v->u.disaster.image_override = 0;
@@ -1065,3 +1060,12 @@
 {
 	ResetDisasterDelay();
 }
+
+void DisasterVehicle::UpdateDeltaXY(Direction direction)
+{
+	this->x_offs        = -1;
+	this->y_offs        = -1;
+	this->sprite_width  =  2;
+	this->sprite_height =  2;
+	this->z_height      =  5;
+}
--- a/src/players.cpp	Tue May 01 15:25:00 2007 +0000
+++ b/src/players.cpp	Tue May 01 16:35:14 2007 +0000
@@ -1109,7 +1109,7 @@
 
 	    SLE_VAR(Player, player_color,          SLE_UINT8),
 	    SLE_VAR(Player, player_money_fraction, SLE_UINT8),
-	    SLE_VAR(Player, avail_railtypes,       SLE_UINT8),
+	SLE_CONDVAR(Player, avail_railtypes,       SLE_UINT8,                   0, 57),
 	    SLE_VAR(Player, block_preview,         SLE_UINT8),
 
 	    SLE_VAR(Player, cargo_types,           SLE_UINT16),
--- a/src/roadveh.h	Tue May 01 15:25:00 2007 +0000
+++ b/src/roadveh.h	Tue May 01 16:35:14 2007 +0000
@@ -40,6 +40,7 @@
 
 	const char *GetTypeString() { return "road vehicle"; }
 	void MarkDirty();
+	void UpdateDeltaXY(Direction direction);
 };
 
 #endif /* ROADVEH_H */
--- a/src/roadveh_cmd.cpp	Tue May 01 15:25:00 2007 +0000
+++ b/src/roadveh_cmd.cpp	Tue May 01 16:35:14 2007 +0000
@@ -169,7 +169,6 @@
 		v->x_pos = x;
 		v->y_pos = y;
 		v->z_pos = GetSlopeZ(x, y);
-		v->z_height = 6;
 
 		v->u.road.state = RVSB_IN_DEPOT;
 		v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
@@ -492,9 +491,9 @@
 	MarkAllViewportsDirty(this->left_coord, this->top_coord, this->right_coord + 1, this->bottom_coord + 1);
 }
 
-static void UpdateRoadVehDeltaXY(Vehicle *v)
+void RoadVehicle::UpdateDeltaXY(Direction direction)
 {
-#define MKIT(a,b,c,d) ((a&0xFF)<<24) | ((b&0xFF)<<16) | ((c&0xFF)<<8) | ((d&0xFF)<<0)
+#define MKIT(a, b, c, d) ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | ((d & 0xFF) << 0)
 	static const uint32 _delta_xy_table[8] = {
 		MKIT(3, 3, -1, -1),
 		MKIT(3, 7, -1, -3),
@@ -506,11 +505,13 @@
 		MKIT(7, 3, -3, -1),
 	};
 #undef MKIT
-	uint32 x = _delta_xy_table[v->direction];
-	v->x_offs        = GB(x,  0, 8);
-	v->y_offs        = GB(x,  8, 8);
-	v->sprite_width  = GB(x, 16, 8);
-	v->sprite_height = GB(x, 24, 8);
+
+	uint32 x = _delta_xy_table[direction];
+	this->x_offs        = GB(x,  0, 8);
+	this->y_offs        = GB(x,  8, 8);
+	this->sprite_width  = GB(x, 16, 8);
+	this->sprite_height = GB(x, 24, 8);
+	this->z_height      = 6;
 }
 
 static void ClearCrashedStation(Vehicle *v)
@@ -566,7 +567,7 @@
 
 	v->direction = ChangeDir(v->direction, delta[r & 3]);
 	BeginVehicleMove(v);
-	UpdateRoadVehDeltaXY(v);
+	v->UpdateDeltaXY(v->direction);
 	v->cur_image = GetRoadVehImage(v, v->direction);
 	SetRoadVehPosition(v, v->x_pos, v->y_pos);
 }
@@ -1345,7 +1346,7 @@
 		v->u.road.frame = RVC_DEPOT_START_FRAME;
 
 		v->cur_image = GetRoadVehImage(v, v->direction);
-		UpdateRoadVehDeltaXY(v);
+		v->UpdateDeltaXY(v->direction);
 		SetRoadVehPosition(v,x,y);
 
 		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
@@ -1381,7 +1382,7 @@
 		if ((IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) && HASBIT(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) {
 			/* Vehicle has just entered a bridge or tunnel */
 			v->cur_image = GetRoadVehImage(v, v->direction);
-			UpdateRoadVehDeltaXY(v);
+			v->UpdateDeltaXY(v->direction);
 			SetRoadVehPosition(v,gp.x,gp.y);
 			return;
 		}
@@ -1469,7 +1470,7 @@
 		}
 
 		v->cur_image = GetRoadVehImage(v, newdir);
-		UpdateRoadVehDeltaXY(v);
+		v->UpdateDeltaXY(v->direction);
 		RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
 		return;
 	}
@@ -1509,7 +1510,7 @@
 		}
 
 		v->cur_image = GetRoadVehImage(v, newdir);
-		UpdateRoadVehDeltaXY(v);
+		v->UpdateDeltaXY(v->direction);
 		RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
 		return;
 	}
@@ -1539,7 +1540,7 @@
 		if (old_dir != v->u.road.state) {
 			/* The vehicle is in a road stop */
 			v->cur_image = GetRoadVehImage(v, new_dir);
-			UpdateRoadVehDeltaXY(v);
+			v->UpdateDeltaXY(v->direction);
 			SetRoadVehPosition(v, v->x_pos, v->y_pos);
 			/* Note, return here means that the frame counter is not incremented
 			 * for vehicles changing direction in a road stop. This causes frames to
@@ -1659,7 +1660,7 @@
 	if (!HASBIT(r, VETS_ENTERED_WORMHOLE)) v->u.road.frame++;
 
 	v->cur_image = GetRoadVehImage(v, v->direction);
-	UpdateRoadVehDeltaXY(v);
+	v->UpdateDeltaXY(v->direction);
 	RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
 }
 
--- a/src/ship.h	Tue May 01 15:25:00 2007 +0000
+++ b/src/ship.h	Tue May 01 16:35:14 2007 +0000
@@ -41,6 +41,7 @@
 
 	const char *GetTypeString() { return "ship"; }
 	void MarkDirty();
+	void UpdateDeltaXY(Direction direction);
 };
 
 #endif /* SHIP_H */
--- a/src/ship_cmd.cpp	Tue May 01 15:25:00 2007 +0000
+++ b/src/ship_cmd.cpp	Tue May 01 16:35:14 2007 +0000
@@ -334,30 +334,32 @@
 	InvalidateVehicleOrder(v);
 }
 
-static void UpdateShipDeltaXY(Vehicle *v, int dir)
+void Ship::UpdateDeltaXY(Direction direction)
 {
-#define MKIT(d,c,b,a) ((a&0xFF)<<24) | ((b&0xFF)<<16) | ((c&0xFF)<<8) | ((d&0xFF)<<0)
+#define MKIT(a, b, c, d) ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | ((d & 0xFF) << 0)
 	static const uint32 _delta_xy_table[8] = {
-		MKIT( -3,  -3,  6,  6),
-		MKIT(-16,  -3, 32,  6),
-		MKIT( -3,  -3,  6,  6),
-		MKIT( -3, -16,  6, 32),
-		MKIT( -3,  -3,  6,  6),
-		MKIT(-16,  -3, 32,  6),
-		MKIT( -3,  -3,  6,  6),
-		MKIT( -3, -16,  6, 32),
+		MKIT( 6,  6,  -3,  -3),
+		MKIT( 6, 32,  -3, -16),
+		MKIT( 6,  6,  -3,  -3),
+		MKIT(32,  6, -16,  -3),
+		MKIT( 6,  6,  -3,  -3),
+		MKIT( 6, 32,  -3, -16),
+		MKIT( 6,  6,  -3,  -3),
+		MKIT(32,  6, -16,  -3),
 	};
 #undef MKIT
-	uint32 x = _delta_xy_table[dir];
-	v->x_offs        = GB(x,  0, 8);
-	v->y_offs        = GB(x,  8, 8);
-	v->sprite_width  = GB(x, 16, 8);
-	v->sprite_height = GB(x, 24, 8);
+
+	uint32 x = _delta_xy_table[direction];
+	this->x_offs        = GB(x,  0, 8);
+	this->y_offs        = GB(x,  8, 8);
+	this->sprite_width  = GB(x, 16, 8);
+	this->sprite_height = GB(x, 24, 8);
+	this->z_height      = 6;
 }
 
 void RecalcShipStuff(Vehicle *v)
 {
-	UpdateShipDeltaXY(v, v->direction);
+	v->UpdateDeltaXY(v->direction);
 	v->cur_image = GetShipImage(v, v->direction);
 	v->MarkDirty();
 	InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
@@ -788,7 +790,7 @@
 	v->z_pos = GetSlopeZ(gp.x, gp.y);
 
 getout:
-	UpdateShipDeltaXY(v, dir);
+	v->UpdateDeltaXY(dir);
 	v->cur_image = GetShipImage(v, dir);
 	VehiclePositionChanged(v);
 	EndVehicleMove(v);
@@ -873,11 +875,7 @@
 		v->y_pos = y;
 		v->z_pos = GetSlopeZ(x, y);
 
-		v->z_height = 6;
-		v->sprite_width = 6;
-		v->sprite_height = 6;
-		v->x_offs = -3;
-		v->y_offs = -3;
+		v->UpdateDeltaXY(v->direction);
 		v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
 
 		v->spritenum = svi->image_index;
--- a/src/train.h	Tue May 01 15:25:00 2007 +0000
+++ b/src/train.h	Tue May 01 16:35:14 2007 +0000
@@ -245,6 +245,7 @@
 
 	const char *GetTypeString() { return "train"; }
 	void MarkDirty();
+	void UpdateDeltaXY(Direction direction);
 };
 
 #endif /* TRAIN_H */
--- a/src/train_cmd.cpp	Tue May 01 15:25:00 2007 +0000
+++ b/src/train_cmd.cpp	Tue May 01 16:35:14 2007 +0000
@@ -535,7 +535,6 @@
 		u->x_pos = v->x_pos;
 		u->y_pos = v->y_pos;
 		u->z_pos = v->z_pos;
-		u->z_height = v->z_height;
 		u->u.rail.track = v->u.rail.track;
 		u->u.rail.railtype = v->u.rail.railtype;
 		u->build_year = v->build_year;
@@ -608,7 +607,6 @@
 			v->y_pos = y;
 			v->z_pos = GetSlopeZ(x, y);
 			v->owner = _current_player;
-			v->z_height = 6;
 			v->u.rail.track = TRACK_BIT_DEPOT;
 			v->vehstatus = VS_HIDDEN | VS_DEFPAL;
 
@@ -681,7 +679,6 @@
 	u->x_pos = v->x_pos;
 	u->y_pos = v->y_pos;
 	u->z_pos = v->z_pos;
-	u->z_height = 6;
 	u->u.rail.track = TRACK_BIT_DEPOT;
 	u->vehstatus = v->vehstatus & ~VS_STOPPED;
 	u->subtype = 0;
@@ -763,7 +760,6 @@
 			v->x_pos = x;
 			v->y_pos = y;
 			v->z_pos = GetSlopeZ(x, y);
-			v->z_height = 6;
 			v->u.rail.track = TRACK_BIT_DEPOT;
 			v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
 			v->spritenum = rvi->image_index;
@@ -1463,9 +1459,9 @@
 	return cost;
 }
 
-static void UpdateTrainDeltaXY(Vehicle *v, Direction direction)
+void Train::UpdateDeltaXY(Direction direction)
 {
-#define MKIT(a,b,c,d) ((a&0xFF)<<24) | ((b&0xFF)<<16) | ((c&0xFF)<<8) | ((d&0xFF)<<0)
+#define MKIT(a, b, c, d) ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | ((d & 0xFF) << 0)
 	static const uint32 _delta_xy_table[8] = {
 		MKIT(3, 3, -1, -1),
 		MKIT(3, 7, -1, -3),
@@ -1479,16 +1475,16 @@
 #undef MKIT
 
 	uint32 x = _delta_xy_table[direction];
-
-	v->x_offs        = GB(x,  0, 8);
-	v->y_offs        = GB(x,  8, 8);
-	v->sprite_width  = GB(x, 16, 8);
-	v->sprite_height = GB(x, 24, 8);
+	this->x_offs        = GB(x,  0, 8);
+	this->y_offs        = GB(x,  8, 8);
+	this->sprite_width  = GB(x, 16, 8);
+	this->sprite_height = GB(x, 24, 8);
+	this->z_height      = 6;
 }
 
 static void UpdateVarsAfterSwap(Vehicle *v)
 {
-	UpdateTrainDeltaXY(v, v->direction);
+	v->UpdateDeltaXY(v->direction);
 	v->cur_image = GetTrainImage(v, v->direction);
 	BeginVehicleMove(v);
 	VehiclePositionChanged(v);
@@ -2149,7 +2145,7 @@
 	v->vehstatus &= ~VS_HIDDEN;
 	v->cur_speed = 0;
 
-	UpdateTrainDeltaXY(v, v->direction);
+	v->UpdateDeltaXY(v->direction);
 	v->cur_image = GetTrainImage(v, v->direction);
 	VehiclePositionChanged(v);
 	UpdateSignalsOnSegment(v->tile, DirToDiagDir(v->direction));
@@ -3061,7 +3057,7 @@
 
 		/* update image of train, as well as delta XY */
 		Direction newdir = GetNewVehicleDirection(v, gp.x, gp.y);
-		UpdateTrainDeltaXY(v, newdir);
+		v->UpdateDeltaXY(newdir);
 		if (update_image) v->cur_image = GetTrainImage(v, newdir);
 
 		v->x_pos = gp.x;
@@ -3157,7 +3153,7 @@
 		if (!(v->vehstatus & VS_HIDDEN)) {
 			v->direction = ChangeDir(v->direction, delta[GB(Random(), 0, 2)]);
 			BeginVehicleMove(v);
-			UpdateTrainDeltaXY(v, v->direction);
+			v->UpdateDeltaXY(v->direction);
 			v->cur_image = GetTrainImage(v, v->direction);
 			/* Refrain from updating the z position of the vehicle when on
 			   a bridge, because AfterSetTrainPos will put the vehicle under
--- a/src/vehicle.cpp	Tue May 01 15:25:00 2007 +0000
+++ b/src/vehicle.cpp	Tue May 01 16:35:14 2007 +0000
@@ -224,6 +224,8 @@
 	Vehicle *v;
 
 	FOR_ALL_VEHICLES(v) {
+		v->UpdateDeltaXY(v->direction);
+
 		v->first = NULL;
 		if (v->type == VEH_TRAIN) v->u.rail.first_engine = INVALID_ENGINE;
 	}
@@ -1443,9 +1445,8 @@
 		v->x_pos = x;
 		v->y_pos = y;
 		v->z_pos = z;
-		v->z_height = v->sprite_width = v->sprite_height = 1;
-		v->x_offs = v->y_offs = 0;
 		v->tile = 0;
+		v->UpdateDeltaXY(INVALID_DIR);
 		v->vehstatus = VS_UNCLICKABLE;
 
 		_effect_init_procs[type](v);
@@ -2644,13 +2645,13 @@
 	    SLE_VAR(Vehicle, z_pos,                SLE_UINT8),
 	    SLE_VAR(Vehicle, direction,            SLE_UINT8),
 
-	    SLE_VAR(Vehicle, cur_image,            SLE_UINT16),
+	SLE_CONDVAR(Vehicle, cur_image,            SLE_UINT16,                  0, 57),
 	    SLE_VAR(Vehicle, spritenum,            SLE_UINT8),
-	    SLE_VAR(Vehicle, sprite_width,         SLE_UINT8),
-	    SLE_VAR(Vehicle, sprite_height,        SLE_UINT8),
-	    SLE_VAR(Vehicle, z_height,             SLE_UINT8),
-	    SLE_VAR(Vehicle, x_offs,               SLE_INT8),
-	    SLE_VAR(Vehicle, y_offs,               SLE_INT8),
+	SLE_CONDVAR(Vehicle, sprite_width,         SLE_UINT8,                   0, 57),
+	SLE_CONDVAR(Vehicle, sprite_height,        SLE_UINT8,                   0, 57),
+	SLE_CONDVAR(Vehicle, z_height,             SLE_UINT8,                   0, 57),
+	SLE_CONDVAR(Vehicle, x_offs,               SLE_INT8,                    0, 57),
+	SLE_CONDVAR(Vehicle, y_offs,               SLE_INT8,                    0, 57),
 	    SLE_VAR(Vehicle, engine_type,          SLE_UINT16),
 
 	    SLE_VAR(Vehicle, max_speed,            SLE_UINT16),
@@ -2818,11 +2819,11 @@
 	    SLE_VAR(Vehicle, z_pos,         SLE_UINT8),
 
 	    SLE_VAR(Vehicle, cur_image,     SLE_UINT16),
-	    SLE_VAR(Vehicle, sprite_width,  SLE_UINT8),
-	    SLE_VAR(Vehicle, sprite_height, SLE_UINT8),
-	    SLE_VAR(Vehicle, z_height,      SLE_UINT8),
-	    SLE_VAR(Vehicle, x_offs,        SLE_INT8),
-	    SLE_VAR(Vehicle, y_offs,        SLE_INT8),
+	SLE_CONDVAR(Vehicle, sprite_width,  SLE_UINT8,                  0, 57),
+	SLE_CONDVAR(Vehicle, sprite_height, SLE_UINT8,                  0, 57),
+	SLE_CONDVAR(Vehicle, z_height,      SLE_UINT8,                  0, 57),
+	SLE_CONDVAR(Vehicle, x_offs,        SLE_INT8,                   0, 57),
+	SLE_CONDVAR(Vehicle, y_offs,        SLE_INT8,                   0, 57),
 	    SLE_VAR(Vehicle, progress,      SLE_UINT8),
 	    SLE_VAR(Vehicle, vehstatus,     SLE_UINT8),
 
@@ -2853,11 +2854,11 @@
 	    SLE_VAR(Vehicle, z_pos,         SLE_UINT8),
 	    SLE_VAR(Vehicle, direction,     SLE_UINT8),
 
-	    SLE_VAR(Vehicle, x_offs,        SLE_INT8),
-	    SLE_VAR(Vehicle, y_offs,        SLE_INT8),
-	    SLE_VAR(Vehicle, sprite_width,  SLE_UINT8),
-	    SLE_VAR(Vehicle, sprite_height, SLE_UINT8),
-	    SLE_VAR(Vehicle, z_height,      SLE_UINT8),
+	SLE_CONDVAR(Vehicle, x_offs,        SLE_INT8,                    0, 57),
+	SLE_CONDVAR(Vehicle, y_offs,        SLE_INT8,                    0, 57),
+	SLE_CONDVAR(Vehicle, sprite_width,  SLE_UINT8,                   0, 57),
+	SLE_CONDVAR(Vehicle, sprite_height, SLE_UINT8,                   0, 57),
+	SLE_CONDVAR(Vehicle, z_height,      SLE_UINT8,                   0, 57),
 	    SLE_VAR(Vehicle, owner,         SLE_UINT8),
 	    SLE_VAR(Vehicle, vehstatus,     SLE_UINT8),
 	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
@@ -3000,3 +3001,13 @@
 	current_order.flags = 0;
 	GetStation(this->last_station_visited)->loading_vehicles.remove(this);
 }
+
+
+void SpecialVehicle::UpdateDeltaXY(Direction direction)
+{
+	this->x_offs        = 0;
+	this->y_offs        = 0;
+	this->sprite_width  = 1;
+	this->sprite_height = 1;
+	this->z_height      = 1;
+}
--- a/src/vehicle.h	Tue May 01 15:25:00 2007 +0000
+++ b/src/vehicle.h	Tue May 01 16:35:14 2007 +0000
@@ -358,6 +358,13 @@
 	 * Marks the vehicles to be redrawn and updates cached variables
 	 */
 	virtual void MarkDirty() {}
+
+	/**
+	 * Updates the x and y offsets and the size of the sprite used
+	 * for this vehicle.
+	 * @param direction the direction the vehicle is facing
+	 */
+	virtual void UpdateDeltaXY(Direction direction) {}
 };
 
 /**
@@ -383,6 +390,7 @@
 	virtual ~SpecialVehicle() {}
 
 	const char *GetTypeString() { return "special vehicle"; }
+	void UpdateDeltaXY(Direction direction);
 };
 
 /**
@@ -401,6 +409,7 @@
 	virtual ~DisasterVehicle() {}
 
 	const char *GetTypeString() { return "disaster vehicle"; }
+	void UpdateDeltaXY(Direction direction);
 };
 
 /**
@@ -410,9 +419,6 @@
  *   v = new (v) Train();
  *
  * As side-effect the vehicle type is set correctly.
- *
- * An invalid vehicle must never be used; all (virtual) functions from
- * Vehicle should assert (NOT_REACHED).
  */
 struct InvalidVehicle : public Vehicle {
 	/** Initializes the Vehicle to a invalid vehicle */
@@ -422,7 +428,6 @@
 	virtual ~InvalidVehicle() {}
 
 	const char *GetTypeString() { return "invalid vehicle"; }
-	void MarkDirty() { NOT_REACHED(); }
 };
 
 #define is_custom_sprite(x) (x >= 0xFD)