src/vehicle.h
branchcustombridgeheads
changeset 5643 3778051e8095
parent 5588 1bcb6b4c01d8
child 5648 1608018c5ff2
equal deleted inserted replaced
5642:bfa6074e2833 5643:3778051e8095
       
     1 /* $Id$ */
       
     2 
       
     3 #ifndef VEHICLE_H
       
     4 #define VEHICLE_H
       
     5 
       
     6 #include "oldpool.h"
       
     7 #include "order.h"
       
     8 #include "rail.h"
       
     9 
       
    10 enum {
       
    11 	VEH_Invalid  = 0x00,
       
    12 	VEH_Train    = 0x10,
       
    13 	VEH_Road     = 0x11,
       
    14 	VEH_Ship     = 0x12,
       
    15 	VEH_Aircraft = 0x13,
       
    16 	VEH_Special  = 0x14,
       
    17 	VEH_Disaster = 0x15,
       
    18 } ;
       
    19 
       
    20 enum VehStatus {
       
    21 	VS_HIDDEN          = 0x01,
       
    22 	VS_STOPPED         = 0x02,
       
    23 	VS_UNCLICKABLE     = 0x04,
       
    24 	VS_DEFPAL          = 0x08,
       
    25 	VS_TRAIN_SLOWING   = 0x10,
       
    26 	VS_SHADOW          = 0x20,
       
    27 	VS_AIRCRAFT_BROKEN = 0x40,
       
    28 	VS_CRASHED         = 0x80,
       
    29 };
       
    30 
       
    31 enum LoadStatus {
       
    32 	LS_LOADING_FINISHED,
       
    33 	LS_CARGO_UNLOADING,
       
    34 	LS_CARGO_PAID_FOR,
       
    35 };
       
    36 
       
    37 /* Effect vehicle types */
       
    38 typedef enum EffectVehicle {
       
    39 	EV_CHIMNEY_SMOKE   = 0,
       
    40 	EV_STEAM_SMOKE     = 1,
       
    41 	EV_DIESEL_SMOKE    = 2,
       
    42 	EV_ELECTRIC_SPARK  = 3,
       
    43 	EV_SMOKE           = 4,
       
    44 	EV_EXPLOSION_LARGE = 5,
       
    45 	EV_BREAKDOWN_SMOKE = 6,
       
    46 	EV_EXPLOSION_SMALL = 7,
       
    47 	EV_BULLDOZER       = 8,
       
    48 	EV_BUBBLE          = 9
       
    49 } EffectVehicle;
       
    50 
       
    51 typedef struct VehicleRail {
       
    52 	uint16 last_speed; // NOSAVE: only used in UI
       
    53 	uint16 crash_anim_pos;
       
    54 	uint16 days_since_order_progr;
       
    55 
       
    56 	// cached values, recalculated on load and each time a vehicle is added to/removed from the consist.
       
    57 	uint16 cached_max_speed;  // max speed of the consist. (minimum of the max speed of all vehicles in the consist)
       
    58 	uint32 cached_power;      // total power of the consist.
       
    59 	uint8 cached_veh_length;  // length of this vehicle in units of 1/8 of normal length, cached because this can be set by a callback
       
    60 	uint16 cached_total_length; ///< Length of the whole train, valid only for first engine.
       
    61 
       
    62 	// cached values, recalculated when the cargo on a train changes (in addition to the conditions above)
       
    63 	uint32 cached_weight;     // total weight of the consist.
       
    64 	uint32 cached_veh_weight; // weight of the vehicle.
       
    65 	uint32 cached_max_te;     // max tractive effort of consist
       
    66 	/**
       
    67 	 * Position/type of visual effect.
       
    68 	 * bit 0 - 3 = position of effect relative to vehicle. (0 = front, 8 = centre, 15 = rear)
       
    69 	 * bit 4 - 5 = type of effect. (0 = default for engine class, 1 = steam, 2 = diesel, 3 = electric)
       
    70 	 * bit     6 = disable visual effect.
       
    71 	 * bit     7 = disable powered wagons.
       
    72 	 */
       
    73 	byte cached_vis_effect;
       
    74 
       
    75 	// NOSAVE: for wagon override - id of the first engine in train
       
    76 	// 0xffff == not in train
       
    77 	EngineID first_engine;
       
    78 
       
    79 	byte track;
       
    80 	byte force_proceed;
       
    81 	byte railtype;
       
    82 	RailTypeMask compatible_railtypes;
       
    83 
       
    84 	byte flags;
       
    85 
       
    86 	// Link between the two ends of a multiheaded engine
       
    87 	Vehicle *other_multiheaded_part;
       
    88 } VehicleRail;
       
    89 
       
    90 enum {
       
    91 	VRF_REVERSING         = 0,
       
    92 
       
    93 	// used to calculate if train is going up or down
       
    94 	VRF_GOINGUP           = 1,
       
    95 	VRF_GOINGDOWN         = 2,
       
    96 
       
    97 	// used to store if a wagon is powered or not
       
    98 	VRF_POWEREDWAGON      = 3,
       
    99 
       
   100 	// used to reverse the visible direction of the vehicle
       
   101 	VRF_REVERSE_DIRECTION = 4,
       
   102 
       
   103 	// used to mark train as lost because PF can't find the route
       
   104 	VRF_NO_PATH_TO_DESTINATION = 5,
       
   105 
       
   106 	// used to mark that electric train engine is allowed to run on normal rail
       
   107 	VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL = 6,
       
   108 };
       
   109 
       
   110 typedef struct VehicleAir {
       
   111 	uint16 crashed_counter;
       
   112 	byte pos;
       
   113 	byte previous_pos;
       
   114 	StationID targetairport;
       
   115 	byte state;
       
   116 } VehicleAir;
       
   117 
       
   118 typedef struct VehicleRoad {
       
   119 	byte state;
       
   120 	byte frame;
       
   121 	uint16 blocked_ctr;
       
   122 	byte overtaking;
       
   123 	byte overtaking_ctr;
       
   124 	uint16 crashed_ctr;
       
   125 	byte reverse_ctr;
       
   126 	struct RoadStop *slot;
       
   127 	byte slot_age;
       
   128 } VehicleRoad;
       
   129 
       
   130 typedef struct VehicleSpecial {
       
   131 	uint16 unk0;
       
   132 	byte unk2;
       
   133 } VehicleSpecial;
       
   134 
       
   135 typedef struct VehicleDisaster {
       
   136 	uint16 image_override;
       
   137 	uint16 unk2;
       
   138 } VehicleDisaster;
       
   139 
       
   140 typedef struct VehicleShip {
       
   141 	byte state;
       
   142 } VehicleShip;
       
   143 
       
   144 
       
   145 struct Vehicle {
       
   146 	byte type;               // type, ie roadven,train,ship,aircraft,special
       
   147 	byte subtype;            // subtype (Filled with values from EffectVehicles or TrainSubTypes)
       
   148 
       
   149 	VehicleID index;         // NOSAVE: Index in vehicle array
       
   150 
       
   151 	Vehicle *next;           // next
       
   152 	Vehicle *first;          // NOSAVE: pointer to the first vehicle in the chain
       
   153 	Vehicle *depot_list;     //NOSAVE: linked list to tell what vehicles entered a depot during the last tick. Used by autoreplace
       
   154 
       
   155 	StringID string_id;      // Displayed string
       
   156 
       
   157 	UnitID unitnumber;       // unit number, for display purposes only
       
   158 	PlayerID owner;          // which player owns the vehicle?
       
   159 
       
   160 	TileIndex tile;          // Current tile index
       
   161 	TileIndex dest_tile;     // Heading for this tile
       
   162 
       
   163 	int32 x_pos;             // coordinates
       
   164 	int32 y_pos;
       
   165 	byte z_pos;
       
   166 	byte direction;          // facing
       
   167 
       
   168 	byte spritenum;          // currently displayed sprite index
       
   169 	                         // 0xfd == custom sprite, 0xfe == custom second head sprite
       
   170 	                         // 0xff == reserved for another custom sprite
       
   171 	uint16 cur_image;        // sprite number for this vehicle
       
   172 	byte sprite_width;       // width of vehicle sprite
       
   173 	byte sprite_height;      // height of vehicle sprite
       
   174 	byte z_height;           // z-height of vehicle sprite
       
   175 	int8 x_offs;             // x offset for vehicle sprite
       
   176 	int8 y_offs;             // y offset for vehicle sprite
       
   177 	EngineID engine_type;
       
   178 
       
   179 	// for randomized variational spritegroups
       
   180 	// bitmask used to resolve them; parts of it get reseeded when triggers
       
   181 	// of corresponding spritegroups get matched
       
   182 	byte random_bits;
       
   183 	byte waiting_triggers;   // triggers to be yet matched
       
   184 
       
   185 	uint16 max_speed;        // maximum speed
       
   186 	uint16 cur_speed;        // current speed
       
   187 	byte subspeed;           // fractional speed
       
   188 	byte acceleration;       // used by train & aircraft
       
   189 	byte progress;
       
   190 	uint32 motion_counter;
       
   191 
       
   192 	byte vehstatus;          // Status
       
   193 	StationID last_station_visited;
       
   194 
       
   195 	CargoID cargo_type;      // type of cargo this vehicle is carrying
       
   196 	byte cargo_days;         // how many days have the pieces been in transit
       
   197 	StationID cargo_source;  // source of cargo
       
   198 	uint16 cargo_cap;        // total capacity
       
   199 	uint16 cargo_count;      // how many pieces are used
       
   200 	byte cargo_subtype;      ///< Used for livery refits (NewGRF variations)
       
   201 
       
   202 	byte day_counter;        // increased by one for each day
       
   203 	byte tick_counter;       // increased by one for each tick
       
   204 
       
   205 	/* Begin Order-stuff */
       
   206 	Order current_order;     ///< The current order (+ status, like: loading)
       
   207 	VehicleOrderID cur_order_index; ///< The index to the current order
       
   208 
       
   209 	Order *orders;           ///< Pointer to the first order for this vehicle
       
   210 	VehicleOrderID num_orders;      ///< How many orders there are in the list
       
   211 
       
   212 	Vehicle *next_shared;    ///< If not NULL, this points to the next vehicle that shared the order
       
   213 	Vehicle *prev_shared;    ///< If not NULL, this points to the prev vehicle that shared the order
       
   214 	/* End Order-stuff */
       
   215 
       
   216 	// Boundaries for the current position in the world and a next hash link.
       
   217 	// NOSAVE: All of those can be updated with VehiclePositionChanged()
       
   218 	int32 left_coord;
       
   219 	int32 top_coord;
       
   220 	int32 right_coord;
       
   221 	int32 bottom_coord;
       
   222 	VehicleID next_hash;
       
   223 
       
   224 	// Related to age and service time
       
   225 	Date age;     // Age in days
       
   226 	Date max_age; // Maximum age
       
   227 	Date date_of_last_service;
       
   228 	Date service_interval;
       
   229 	uint16 reliability;
       
   230 	uint16 reliability_spd_dec;
       
   231 	byte breakdown_ctr;
       
   232 	byte breakdown_delay;
       
   233 	byte breakdowns_since_last_service;
       
   234 	byte breakdown_chance;
       
   235 	Year build_year;
       
   236 
       
   237 	bool leave_depot_instantly; // NOSAVE: stores if the vehicle needs to leave the depot it just entered. Used by autoreplace
       
   238 
       
   239 	uint16 load_unload_time_rem;
       
   240 	byte load_status;
       
   241 
       
   242 	int32 profit_this_year;
       
   243 	int32 profit_last_year;
       
   244 	uint32 value;
       
   245 
       
   246 	union {
       
   247 		VehicleRail rail;
       
   248 		VehicleAir air;
       
   249 		VehicleRoad road;
       
   250 		VehicleSpecial special;
       
   251 		VehicleDisaster disaster;
       
   252 		VehicleShip ship;
       
   253 	} u;
       
   254 };
       
   255 
       
   256 #define is_custom_sprite(x) (x >= 0xFD)
       
   257 #define IS_CUSTOM_FIRSTHEAD_SPRITE(x) (x == 0xFD)
       
   258 #define IS_CUSTOM_SECONDHEAD_SPRITE(x) (x == 0xFE)
       
   259 
       
   260 typedef void *VehicleFromPosProc(Vehicle *v, void *data);
       
   261 
       
   262 void VehicleServiceInDepot(Vehicle *v);
       
   263 Vehicle *AllocateVehicle(void);
       
   264 bool AllocateVehicles(Vehicle **vl, int num);
       
   265 Vehicle *ForceAllocateVehicle(void);
       
   266 Vehicle *ForceAllocateSpecialVehicle(void);
       
   267 void VehiclePositionChanged(Vehicle *v);
       
   268 void AfterLoadVehicles(void);
       
   269 Vehicle *GetLastVehicleInChain(Vehicle *v);
       
   270 Vehicle *GetPrevVehicleInChain(const Vehicle *v);
       
   271 Vehicle *GetFirstVehicleInChain(const Vehicle *v);
       
   272 uint CountVehiclesInChain(const Vehicle* v);
       
   273 bool IsEngineCountable(const Vehicle *v);
       
   274 void DeleteVehicleChain(Vehicle *v);
       
   275 void *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc);
       
   276 void CallVehicleTicks(void);
       
   277 Vehicle *FindVehicleOnTileZ(TileIndex tile, byte z);
       
   278 
       
   279 void InitializeTrains(void);
       
   280 byte VehicleRandomBits(void);
       
   281 void ResetVehiclePosHash(void);
       
   282 
       
   283 bool CanFillVehicle(Vehicle *v);
       
   284 bool CanRefitTo(EngineID engine_type, CargoID cid_to);
       
   285 CargoID FindFirstRefittableCargo(EngineID engine_type);
       
   286 int32 GetRefitCost(EngineID engine_type);
       
   287 
       
   288 void ViewportAddVehicles(DrawPixelInfo *dpi);
       
   289 
       
   290 /* train_cmd.h */
       
   291 int GetTrainImage(const Vehicle* v, Direction direction);
       
   292 int GetAircraftImage(const Vehicle* v, Direction direction);
       
   293 int GetRoadVehImage(const Vehicle* v, Direction direction);
       
   294 int GetShipImage(const Vehicle* v, Direction direction);
       
   295 
       
   296 Vehicle *CreateEffectVehicle(int x, int y, int z, EffectVehicle type);
       
   297 Vehicle *CreateEffectVehicleAbove(int x, int y, int z, EffectVehicle type);
       
   298 Vehicle *CreateEffectVehicleRel(const Vehicle *v, int x, int y, int z, EffectVehicle type);
       
   299 
       
   300 uint32 VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y);
       
   301 
       
   302 StringID VehicleInTheWayErrMsg(const Vehicle* v);
       
   303 Vehicle *FindVehicleBetween(TileIndex from, TileIndex to, byte z);
       
   304 
       
   305 bool UpdateSignalsOnSegment(TileIndex tile, DiagDirection direction);
       
   306 void SetSignalsOnBothDir(TileIndex tile, byte track);
       
   307 
       
   308 Vehicle *CheckClickOnVehicle(const ViewPort *vp, int x, int y);
       
   309 
       
   310 void DecreaseVehicleValue(Vehicle *v);
       
   311 void CheckVehicleBreakdown(Vehicle *v);
       
   312 void AgeVehicle(Vehicle *v);
       
   313 void VehicleEnteredDepotThisTick(Vehicle *v);
       
   314 
       
   315 void BeginVehicleMove(Vehicle *v);
       
   316 void EndVehicleMove(Vehicle *v);
       
   317 
       
   318 void ShowAircraftViewWindow(const Vehicle* v);
       
   319 
       
   320 UnitID GetFreeUnitNumber(byte type);
       
   321 
       
   322 int LoadUnloadVehicle(Vehicle *v, bool just_arrived);
       
   323 
       
   324 void TrainConsistChanged(Vehicle *v);
       
   325 void TrainPowerChanged(Vehicle *v);
       
   326 int32 GetTrainRunningCost(const Vehicle *v);
       
   327 
       
   328 int CheckTrainStoppedInDepot(const Vehicle *v);
       
   329 
       
   330 bool VehicleNeedsService(const Vehicle *v);
       
   331 
       
   332 uint GenerateVehicleSortList(const Vehicle*** sort_list, uint16 *length_of_array, byte type, PlayerID owner, StationID station, OrderID order, uint16 depot_airport_index, uint16 window_type);
       
   333 void BuildDepotVehicleList(byte type, TileIndex tile, Vehicle ***engine_list, uint16 *engine_list_length, uint16 *engine_count, Vehicle ***wagon_list, uint16 *wagon_list_length, uint16 *wagon_count);
       
   334 int32 SendAllVehiclesToDepot(byte type, uint32 flags, bool service, PlayerID owner, uint16 vlw_flag, uint32 id);
       
   335 bool IsVehicleInDepot(const Vehicle *v);
       
   336 void VehicleEnterDepot(Vehicle *v);
       
   337 
       
   338 /* Flags to add to p2 for goto depot commands */
       
   339 /* Note: bits 8-10 are used for VLW flags */
       
   340 enum {
       
   341 	DEPOT_SERVICE       = (1 << 0),	// The vehicle will leave the depot right after arrival (serivce only)
       
   342 	DEPOT_MASS_SEND     = (1 << 1), // Tells that it's a mass send to depot command (type in VLW flag)
       
   343 	DEPOT_DONT_CANCEL   = (1 << 2), // Don't cancel current goto depot command if any
       
   344 	DEPOT_LOCATE_HANGAR = (1 << 3), // Find another airport if the target one lacks a hangar
       
   345 };
       
   346 
       
   347 typedef struct GetNewVehiclePosResult {
       
   348 	int x,y;
       
   349 	TileIndex old_tile;
       
   350 	TileIndex new_tile;
       
   351 } GetNewVehiclePosResult;
       
   352 
       
   353 /**
       
   354  * Returns the Trackdir on which the vehicle is currently located.
       
   355  * Works for trains and ships.
       
   356  * Currently works only sortof for road vehicles, since they have a fuzzy
       
   357  * concept of being "on" a trackdir. Dunno really what it returns for a road
       
   358  * vehicle that is halfway a tile, never really understood that part. For road
       
   359  * vehicles that are at the beginning or end of the tile, should just return
       
   360  * the diagonal trackdir on which they are driving. I _think_.
       
   361  * For other vehicles types, or vehicles with no clear trackdir (such as those
       
   362  * in depots), returns 0xFF.
       
   363  */
       
   364 Trackdir GetVehicleTrackdir(const Vehicle* v);
       
   365 
       
   366 /* returns true if staying in the same tile */
       
   367 bool GetNewVehiclePos(const Vehicle *v, GetNewVehiclePosResult *gp);
       
   368 Direction GetDirectionTowards(const Vehicle* v, int x, int y);
       
   369 
       
   370 #define BEGIN_ENUM_WAGONS(v) do {
       
   371 #define END_ENUM_WAGONS(v) } while ( (v=v->next) != NULL);
       
   372 
       
   373 DECLARE_OLD_POOL(Vehicle, Vehicle, 9, 125)
       
   374 
       
   375 static inline VehicleID GetMaxVehicleIndex(void)
       
   376 {
       
   377 	/* TODO - This isn't the real content of the function, but
       
   378 	 *  with the new pool-system this will be replaced with one that
       
   379 	 *  _really_ returns the highest index. Now it just returns
       
   380 	 *  the next safe value we are sure about everything is below.
       
   381 	 */
       
   382 	return GetVehiclePoolSize() - 1;
       
   383 }
       
   384 
       
   385 static inline uint GetNumVehicles(void)
       
   386 {
       
   387 	return GetVehiclePoolSize();
       
   388 }
       
   389 
       
   390 /**
       
   391  * Check if a Vehicle really exists.
       
   392  */
       
   393 static inline bool IsValidVehicle(const Vehicle *v)
       
   394 {
       
   395 	return v->type != 0;
       
   396 }
       
   397 
       
   398 void DestroyVehicle(Vehicle *v);
       
   399 
       
   400 static inline void DeleteVehicle(Vehicle *v)
       
   401 {
       
   402 	DestroyVehicle(v);
       
   403 	v->type = 0;
       
   404 }
       
   405 
       
   406 #define FOR_ALL_VEHICLES_FROM(v, start) for (v = GetVehicle(start); v != NULL; v = (v->index + 1U < GetVehiclePoolSize()) ? GetVehicle(v->index + 1) : NULL) if (IsValidVehicle(v))
       
   407 #define FOR_ALL_VEHICLES(v) FOR_ALL_VEHICLES_FROM(v, 0)
       
   408 
       
   409 /**
       
   410  * Check if an index is a vehicle-index (so between 0 and max-vehicles)
       
   411  *
       
   412  * @return Returns true if the vehicle-id is in range
       
   413  */
       
   414 static inline bool IsValidVehicleID(uint index)
       
   415 {
       
   416 	return index < GetVehiclePoolSize() && IsValidVehicle(GetVehicle(index));
       
   417 }
       
   418 
       
   419 /* Returns order 'index' of a vehicle or NULL when it doesn't exists */
       
   420 static inline Order *GetVehicleOrder(const Vehicle *v, int index)
       
   421 {
       
   422 	Order *order = v->orders;
       
   423 
       
   424 	if (index < 0) return NULL;
       
   425 
       
   426 	while (order != NULL && index-- > 0)
       
   427 		order = order->next;
       
   428 
       
   429 	return order;
       
   430 }
       
   431 
       
   432 /* Returns the last order of a vehicle, or NULL if it doesn't exists */
       
   433 static inline Order *GetLastVehicleOrder(const Vehicle *v)
       
   434 {
       
   435 	Order *order = v->orders;
       
   436 
       
   437 	if (order == NULL) return NULL;
       
   438 
       
   439 	while (order->next != NULL)
       
   440 		order = order->next;
       
   441 
       
   442 	return order;
       
   443 }
       
   444 
       
   445 /* Get the first vehicle of a shared-list, so we only have to walk forwards */
       
   446 static inline Vehicle *GetFirstVehicleFromSharedList(const Vehicle *v)
       
   447 {
       
   448 	Vehicle *u = (Vehicle *)v;
       
   449 	while (u->prev_shared != NULL) u = u->prev_shared;
       
   450 
       
   451 	return u;
       
   452 }
       
   453 
       
   454 // NOSAVE: Return values from various commands.
       
   455 VARDEF VehicleID _new_vehicle_id;
       
   456 VARDEF uint16 _returned_refit_capacity;
       
   457 
       
   458 enum {
       
   459 	INVALID_VEHICLE = 0xFFFF,
       
   460 };
       
   461 
       
   462 /**
       
   463  * Get the colour map for an engine. This used for unbuilt engines in the user interface.
       
   464  * @param engine_type ID of engine
       
   465  * @param player ID of player
       
   466  * @return A ready-to-use palette modifier
       
   467  */
       
   468 PalSpriteID GetEnginePalette(EngineID engine_type, PlayerID player);
       
   469 
       
   470 /**
       
   471  * Get the colour map for a vehicle.
       
   472  * @param v Vehicle to get colour map for
       
   473  * @return A ready-to-use palette modifier
       
   474  */
       
   475 PalSpriteID GetVehiclePalette(const Vehicle *v);
       
   476 
       
   477 /* A lot of code calls for the invalidation of the status bar, which is widget 5.
       
   478  * Best is to have a virtual value for it when it needs to change again */
       
   479 #define STATUS_BAR 5
       
   480 
       
   481 extern const uint32 _send_to_depot_proc_table[];
       
   482 #define CMD_SEND_TO_DEPOT(x) _send_to_depot_proc_table[ x - VEH_Train]
       
   483 
       
   484 #endif /* VEHICLE_H */