0
|
1 |
#ifndef VEHICLE_H
|
|
2 |
#define VEHICLE_H
|
|
3 |
|
|
4 |
typedef struct VehicleRail {
|
|
5 |
uint16 last_speed; // NOSAVE: only used in UI
|
|
6 |
uint16 crash_anim_pos;
|
|
7 |
uint16 days_since_order_progr;
|
|
8 |
|
|
9 |
uint16 cached_weight; // cached power and weight for the vehicle.
|
|
10 |
uint32 cached_power; // no need to save those, they are recomputed on load.
|
|
11 |
|
|
12 |
// NOSAVE: for wagon override - id of the first engine in train
|
|
13 |
// 0xffff == not in train
|
|
14 |
uint16 first_engine;
|
|
15 |
|
|
16 |
byte track;
|
|
17 |
byte force_proceed;
|
|
18 |
byte railtype;
|
|
19 |
|
|
20 |
byte flags;
|
|
21 |
} VehicleRail;
|
|
22 |
|
|
23 |
enum {
|
|
24 |
VRF_REVERSING = 1,
|
|
25 |
|
|
26 |
// used to calculate if train is going up or down
|
|
27 |
VRF_GOINGUP = 2,
|
|
28 |
VRF_GOINGDOWN = 4,
|
|
29 |
};
|
|
30 |
|
|
31 |
typedef struct VehicleAir {
|
|
32 |
uint16 crashed_counter;
|
|
33 |
byte pos;
|
|
34 |
byte previous_pos;
|
|
35 |
byte targetairport;
|
|
36 |
byte state;
|
|
37 |
} VehicleAir;
|
|
38 |
|
|
39 |
typedef struct VehicleRoad {
|
|
40 |
byte state;
|
|
41 |
byte frame;
|
|
42 |
uint16 unk2;
|
|
43 |
byte overtaking;
|
|
44 |
byte overtaking_ctr;
|
|
45 |
uint16 crashed_ctr;
|
|
46 |
byte reverse_ctr;
|
|
47 |
} VehicleRoad;
|
|
48 |
|
|
49 |
typedef struct VehicleSpecial {
|
|
50 |
uint16 unk0;
|
|
51 |
byte unk2;
|
|
52 |
} VehicleSpecial;
|
|
53 |
|
|
54 |
typedef struct VehicleDisaster {
|
|
55 |
uint16 image_override;
|
|
56 |
uint16 unk2;
|
|
57 |
} VehicleDisaster;
|
|
58 |
|
|
59 |
typedef struct VehicleShip {
|
|
60 |
byte state;
|
|
61 |
} VehicleShip;
|
|
62 |
|
|
63 |
// not used ATM
|
|
64 |
struct WorldSprite {
|
|
65 |
struct WorldSprite *next; // next sprite in hash chain
|
|
66 |
uint16 image; // sprite number for this vehicle
|
|
67 |
|
|
68 |
// screen coordinates
|
|
69 |
int16 left, top, right, bottom;
|
|
70 |
|
|
71 |
// world coordinates
|
|
72 |
int16 x;
|
|
73 |
int16 y;
|
|
74 |
byte z;
|
|
75 |
|
|
76 |
int8 x_offs; // x offset for vehicle sprite
|
|
77 |
int8 y_offs; // y offset for vehicle sprite
|
|
78 |
|
|
79 |
byte width; // width of vehicle sprite
|
|
80 |
byte height; // height of vehicle sprite
|
|
81 |
byte depth; // depth of vehicle sprite
|
|
82 |
|
|
83 |
byte flags; // draw flags
|
|
84 |
};
|
|
85 |
|
|
86 |
struct Vehicle {
|
|
87 |
byte type; // type, ie roadven,train,ship,aircraft,special
|
|
88 |
byte subtype; // subtype
|
|
89 |
|
|
90 |
uint16 index; // NOSAVE: Index in vehicle array
|
|
91 |
uint16 next_in_chain_old; // Next vehicle index for chained vehicles
|
|
92 |
|
|
93 |
Vehicle *next; // next
|
|
94 |
|
|
95 |
StringID string_id; // Displayed string
|
|
96 |
|
|
97 |
byte unitnumber; // unit number, for display purposes only
|
|
98 |
byte owner; // which player owns the vehicle?
|
|
99 |
|
|
100 |
TileIndex tile; // Current tile index
|
|
101 |
TileIndex dest_tile; // Heading for this tile
|
|
102 |
|
|
103 |
int16 x_pos; // coordinates
|
|
104 |
int16 y_pos;
|
|
105 |
byte z_pos;
|
|
106 |
byte direction; // facing
|
|
107 |
|
|
108 |
uint16 cur_image; // sprite number for this vehicle
|
|
109 |
byte spritenum; // currently displayed sprite index
|
|
110 |
// 0xfd == custom sprite, 0xfe == custom second head sprite
|
|
111 |
// 0xff == reserved for another custom sprite
|
|
112 |
byte sprite_width;// width of vehicle sprite
|
|
113 |
byte sprite_height;// height of vehicle sprite
|
|
114 |
byte z_height; // z-height of vehicle sprite
|
|
115 |
int8 x_offs; // x offset for vehicle sprite
|
|
116 |
int8 y_offs; // y offset for vehicle sprite
|
|
117 |
uint16 engine_type;
|
|
118 |
|
|
119 |
uint16 max_speed; // maximum speed
|
|
120 |
uint16 cur_speed; // current speed
|
|
121 |
byte subspeed; // fractional speed
|
|
122 |
byte acceleration; // used by train & aircraft
|
|
123 |
byte progress;
|
|
124 |
|
|
125 |
byte vehstatus; // Status
|
|
126 |
byte last_station_visited;
|
|
127 |
|
|
128 |
byte cargo_type; // type of cargo this vehicle is carrying
|
|
129 |
byte cargo_days; // how many days have the pieces been in transit
|
|
130 |
byte cargo_source;// source of cargo
|
|
131 |
uint16 cargo_cap; // total capacity
|
|
132 |
uint16 cargo_count;// how many pieces are used
|
|
133 |
|
|
134 |
byte day_counter; // increased by one for each day
|
|
135 |
byte tick_counter;// increased by one for each tick
|
|
136 |
|
|
137 |
// related to the current order
|
|
138 |
byte cur_order_index;
|
|
139 |
byte num_orders;
|
|
140 |
byte next_order;
|
|
141 |
byte next_order_param;
|
|
142 |
uint16 *schedule_ptr;
|
|
143 |
|
|
144 |
// Boundaries for the current position in the world and a next hash link.
|
|
145 |
// NOSAVE: All of those can be updated with VehiclePositionChanged()
|
|
146 |
int16 left_coord, top_coord, right_coord, bottom_coord;
|
|
147 |
uint16 next_hash;
|
|
148 |
|
|
149 |
// Related to age and service time
|
|
150 |
uint16 age; // Age in days
|
|
151 |
uint16 max_age; // Maximum age
|
|
152 |
uint16 date_of_last_service;
|
|
153 |
uint16 service_interval;
|
|
154 |
uint16 reliability;
|
|
155 |
uint16 reliability_spd_dec;
|
|
156 |
byte breakdown_ctr;
|
|
157 |
byte breakdown_delay;
|
|
158 |
byte breakdowns_since_last_service;
|
|
159 |
byte breakdown_chance;
|
|
160 |
byte build_year;
|
|
161 |
|
|
162 |
uint16 load_unload_time_rem;
|
|
163 |
|
|
164 |
int32 profit_this_year;
|
|
165 |
int32 profit_last_year;
|
|
166 |
uint32 value;
|
|
167 |
|
|
168 |
union {
|
|
169 |
VehicleRail rail;
|
|
170 |
VehicleAir air;
|
|
171 |
VehicleRoad road;
|
|
172 |
VehicleSpecial special;
|
|
173 |
VehicleDisaster disaster;
|
|
174 |
VehicleShip ship;
|
|
175 |
} u;
|
|
176 |
};
|
|
177 |
|
|
178 |
#define is_custom_sprite(x) (x >= 0xfd)
|
|
179 |
#define is_custom_firsthead_sprite(x) (x == 0xfd)
|
|
180 |
#define is_custom_secondhead_sprite(x) (x == 0xfe)
|
|
181 |
|
|
182 |
struct Depot {
|
|
183 |
TileIndex xy;
|
|
184 |
uint16 town_index;
|
|
185 |
};
|
|
186 |
|
|
187 |
// train checkpoint
|
|
188 |
struct Checkpoint {
|
|
189 |
TileIndex xy;
|
|
190 |
uint16 town_or_string; // if this is 0xC000, it's a string id, otherwise a town.
|
|
191 |
ViewportSign sign;
|
|
192 |
uint16 build_date;
|
|
193 |
byte stat_id;
|
|
194 |
byte deleted; // this is a delete counter. when it reaches 0, the checkpoint struct is deleted.
|
|
195 |
};
|
|
196 |
|
|
197 |
enum {
|
|
198 |
VEH_Train = 0x10,
|
|
199 |
VEH_Road = 0x11,
|
|
200 |
VEH_Ship = 0x12,
|
|
201 |
VEH_Aircraft = 0x13,
|
|
202 |
VEH_Special = 0x14,
|
|
203 |
VEH_Disaster = 0x15,
|
|
204 |
};
|
|
205 |
|
|
206 |
/* Order types */
|
|
207 |
enum {
|
|
208 |
OT_NOTHING = 0,
|
|
209 |
OT_GOTO_STATION = 1,
|
|
210 |
OT_GOTO_DEPOT = 2,
|
|
211 |
OT_LOADING = 3,
|
|
212 |
OT_LEAVESTATION = 4,
|
|
213 |
OT_DUMMY = 5,
|
|
214 |
OT_GOTO_CHECKPOINT = 6,
|
|
215 |
|
|
216 |
OT_MASK = 0x1F,
|
|
217 |
};
|
|
218 |
|
|
219 |
/* Order flags */
|
|
220 |
enum {
|
|
221 |
OF_UNLOAD = 0x20,
|
|
222 |
OF_FULL_LOAD = 0x40, // Also used when to force an aircraft into a depot.
|
|
223 |
OF_NON_STOP = 0x80,
|
|
224 |
OF_MASK = 0xE0,
|
|
225 |
};
|
|
226 |
|
|
227 |
|
|
228 |
enum VehStatus {
|
|
229 |
VS_HIDDEN = 1,
|
|
230 |
VS_STOPPED = 2,
|
|
231 |
VS_UNCLICKABLE = 4,
|
|
232 |
VS_DEFPAL = 0x8,
|
|
233 |
VS_TRAIN_SLOWING = 0x10,
|
|
234 |
VS_DISASTER = 0x20,
|
|
235 |
VS_AIRCRAFT_BROKEN = 0x40,
|
|
236 |
VS_CRASHED = 0x80,
|
|
237 |
};
|
|
238 |
|
|
239 |
|
|
240 |
|
|
241 |
/* Effect vehicle types */
|
|
242 |
enum {
|
|
243 |
EV_INDUSTRYSMOKE = 0,
|
|
244 |
EV_STEAM_SMOKE = 1,
|
|
245 |
|
|
246 |
EV_SMOKE_1 = 2,
|
|
247 |
EV_SMOKE_2 = 3,
|
|
248 |
EV_SMOKE_3 = 4,
|
|
249 |
|
|
250 |
EV_CRASHED_SMOKE = 5,
|
|
251 |
EV_BREAKDOWN_SMOKE = 6,
|
|
252 |
|
|
253 |
EV_DEMOLISH = 7,
|
|
254 |
EV_ROADWORK = 8,
|
|
255 |
|
|
256 |
EV_INDUSTRY_SMOKE = 9,
|
|
257 |
|
|
258 |
};
|
|
259 |
|
|
260 |
typedef void VehicleTickProc(Vehicle *v);
|
|
261 |
typedef void *VehicleFromPosProc(Vehicle *v, void *data);
|
|
262 |
|
|
263 |
typedef struct {
|
|
264 |
byte orderindex;
|
|
265 |
uint16 order[41];
|
|
266 |
uint16 service_interval;
|
|
267 |
char name[32];
|
|
268 |
} BackuppedOrders;
|
|
269 |
|
|
270 |
void BackupVehicleOrders(Vehicle *v, BackuppedOrders *order);
|
|
271 |
void RestoreVehicleOrders(Vehicle *v, BackuppedOrders *order);
|
|
272 |
Vehicle *AllocateVehicle();
|
|
273 |
Vehicle *ForceAllocateVehicle();
|
|
274 |
Vehicle *ForceAllocateSpecialVehicle();
|
|
275 |
void UpdateVehiclePosHash(Vehicle *v, int x, int y);
|
|
276 |
void InitializeVehicles();
|
|
277 |
void VehiclePositionChanged(Vehicle *v);
|
|
278 |
void AfterLoadVehicles();
|
|
279 |
Vehicle *GetLastVehicleInChain(Vehicle *v);
|
|
280 |
Vehicle *GetPrevVehicleInChain(Vehicle *v);
|
|
281 |
Vehicle *GetFirstVehicleInChain(Vehicle *v);
|
|
282 |
int CountVehiclesInChain(Vehicle *v);
|
|
283 |
void DeleteVehicle(Vehicle *v);
|
|
284 |
void DeleteVehicleChain(Vehicle *v);
|
|
285 |
void *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc);
|
|
286 |
void CallVehicleTicks();
|
|
287 |
void DeleteVehicleSchedule(Vehicle *v);
|
|
288 |
Vehicle *IsScheduleShared(Vehicle *v);
|
|
289 |
|
|
290 |
Depot *AllocateDepot();
|
|
291 |
Checkpoint *AllocateCheckpoint();
|
|
292 |
void UpdateCheckpointSign(Checkpoint *cp);
|
|
293 |
void RedrawCheckpointSign(Checkpoint *cp);
|
|
294 |
|
|
295 |
void InitializeTrains();
|
|
296 |
bool IsTrainDepotTile(TileIndex tile);
|
|
297 |
bool IsRoadDepotTile(TileIndex tile);
|
|
298 |
|
|
299 |
bool CanFillVehicle(Vehicle *v);
|
|
300 |
|
|
301 |
void ViewportAddVehicles(DrawPixelInfo *dpi);
|
|
302 |
|
|
303 |
void TrainEnterDepot(Vehicle *v, uint tile);
|
|
304 |
|
|
305 |
/* train_cmd.h */
|
|
306 |
int GetTrainImage(Vehicle *v, byte direction);
|
|
307 |
int GetAircraftImage(Vehicle *v, byte direction);
|
|
308 |
int GetRoadVehImage(Vehicle *v, byte direction);
|
|
309 |
int GetShipImage(Vehicle *v, byte direction);
|
|
310 |
|
|
311 |
Vehicle *CreateEffectVehicle(int x, int y, int z, int type);
|
|
312 |
Vehicle *CreateEffectVehicleAbove(int x, int y, int z, int type);
|
|
313 |
Vehicle *CreateEffectVehicleRel(Vehicle *v, int x, int y, int z, int type);
|
|
314 |
|
|
315 |
uint32 VehicleEnterTile(Vehicle *v, uint tile, int x, int y);
|
|
316 |
|
|
317 |
void VehicleInTheWayErrMsg(Vehicle *v);
|
|
318 |
Vehicle *FindVehicleBetween(TileIndex from, TileIndex to, byte z);
|
|
319 |
uint GetVehicleOutOfTunnelTile(Vehicle *v);
|
|
320 |
|
|
321 |
bool UpdateSignalsOnSegment(uint tile, byte direction);
|
|
322 |
void SetSignalsOnBothDir(uint tile, byte track);
|
|
323 |
|
|
324 |
Vehicle *CheckClickOnVehicle(ViewPort *vp, int x, int y);
|
|
325 |
//uint GetVehicleWeight(Vehicle *v);
|
|
326 |
|
|
327 |
void DecreaseVehicleValue(Vehicle *v);
|
|
328 |
void CheckVehicleBreakdown(Vehicle *v);
|
|
329 |
void AgeVehicle(Vehicle *v);
|
|
330 |
void MaybeRenewVehicle(Vehicle *v, int32 build_cost);
|
|
331 |
|
|
332 |
void DeleteCommandFromVehicleSchedule(uint cmd);
|
|
333 |
|
|
334 |
void BeginVehicleMove(Vehicle *v);
|
|
335 |
void EndVehicleMove(Vehicle *v);
|
|
336 |
|
|
337 |
bool IsAircraftHangarTile(TileIndex tile);
|
|
338 |
void ShowAircraftViewWindow(Vehicle *v);
|
|
339 |
|
|
340 |
void InvalidateVehicleOrderWidget(Vehicle *v);
|
|
341 |
|
|
342 |
bool IsShipDepotTile(TileIndex tile);
|
|
343 |
uint GetFreeUnitNumber(byte type);
|
|
344 |
|
|
345 |
int LoadUnloadVehicle(Vehicle *v);
|
|
346 |
int GetDepotByTile(uint tile);
|
|
347 |
uint GetCheckpointByTile(uint tile);
|
|
348 |
|
|
349 |
void DoDeleteDepot(uint tile);
|
|
350 |
|
|
351 |
void UpdateTrainAcceleration(Vehicle *v);
|
|
352 |
int32 GetTrainRunningCost(Vehicle *v);
|
|
353 |
|
|
354 |
int CheckStoppedInDepot(Vehicle *v);
|
|
355 |
|
|
356 |
int ScheduleHasDepotOrders(uint16 *schedule);
|
|
357 |
|
|
358 |
typedef struct GetNewVehiclePosResult {
|
|
359 |
int x,y;
|
|
360 |
uint old_tile;
|
|
361 |
uint new_tile;
|
|
362 |
} GetNewVehiclePosResult;
|
|
363 |
|
|
364 |
/* returns true if staying in the same tile */
|
|
365 |
bool GetNewVehiclePos(Vehicle *v, GetNewVehiclePosResult *gp);
|
|
366 |
byte GetDirectionTowards(Vehicle *v, int x, int y);
|
|
367 |
|
|
368 |
#define BEGIN_ENUM_WAGONS(v) do {
|
|
369 |
#define END_ENUM_WAGONS(v) } while ( (v=v->next) != NULL);
|
|
370 |
|
|
371 |
#define FOR_ALL_VEHICLES(v) for(v=_vehicles; v != endof(_vehicles); v++)
|
|
372 |
|
|
373 |
/* vehicle.c */
|
|
374 |
enum {
|
|
375 |
NUM_NORMAL_VEHICLES = 2048,
|
|
376 |
NUM_SPECIAL_VEHICLES = 512,
|
|
377 |
NUM_VEHICLES = NUM_NORMAL_VEHICLES + NUM_SPECIAL_VEHICLES
|
|
378 |
};
|
|
379 |
|
|
380 |
VARDEF Vehicle _vehicles[NUM_VEHICLES];
|
|
381 |
|
|
382 |
VARDEF uint16 _order_array[5000];
|
|
383 |
VARDEF uint16 *_ptr_to_next_order;
|
|
384 |
|
|
385 |
VARDEF Depot _depots[255];
|
|
386 |
|
|
387 |
// 128 checkpoints
|
|
388 |
VARDEF Checkpoint _checkpoints[128];
|
|
389 |
|
|
390 |
// NOSAVE: Can be regenerated by inspecting the vehicles.
|
|
391 |
VARDEF VehicleID _vehicle_position_hash[0x1000];
|
|
392 |
|
|
393 |
// NOSAVE: Return values from various commands.
|
|
394 |
VARDEF VehicleID _new_train_id;
|
|
395 |
VARDEF VehicleID _new_wagon_id;
|
|
396 |
VARDEF VehicleID _new_aircraft_id;
|
|
397 |
VARDEF VehicleID _new_ship_id;
|
|
398 |
VARDEF VehicleID _new_roadveh_id;
|
|
399 |
VARDEF uint16 _aircraft_refit_capacity;
|
|
400 |
VARDEF byte _cmd_build_rail_veh_score;
|
|
401 |
VARDEF byte _cmd_build_rail_veh_var1;
|
|
402 |
|
|
403 |
// NOSAVE: Player specific info
|
|
404 |
VARDEF TileIndex _last_built_train_depot_tile;
|
|
405 |
VARDEF TileIndex _last_built_road_depot_tile;
|
|
406 |
VARDEF TileIndex _last_built_aircraft_depot_tile;
|
|
407 |
VARDEF TileIndex _last_built_ship_depot_tile;
|
|
408 |
VARDEF TileIndex _backup_orders_tile;
|
|
409 |
VARDEF BackuppedOrders _backup_orders_data[1];
|
|
410 |
|
|
411 |
// for each player, for each vehicle type, keep a list of the vehicles.
|
|
412 |
//VARDEF Vehicle *_vehicle_arr[8][4];
|
|
413 |
|
|
414 |
#define INVALID_VEHICLE 0xffff
|
|
415 |
|
|
416 |
#endif /* VEHICLE_H */
|