|
1 /* $Id$ */ |
|
2 |
|
3 #ifndef ENGINE_H |
|
4 #define ENGINE_H |
|
5 |
|
6 /** @file engine.h */ |
|
7 |
|
8 #include "oldpool.h" |
|
9 |
|
10 typedef struct RailVehicleInfo { |
|
11 byte image_index; |
|
12 byte flags; /* 1=multihead engine, 2=wagon */ |
|
13 byte base_cost; |
|
14 uint16 max_speed; |
|
15 uint16 power; |
|
16 uint16 weight; |
|
17 byte running_cost_base; |
|
18 byte running_cost_class; |
|
19 byte engclass; // 0: steam, 1: diesel, 2: electric |
|
20 byte capacity; |
|
21 CargoID cargo_type; |
|
22 byte ai_rank; |
|
23 uint16 pow_wag_power; |
|
24 byte pow_wag_weight; |
|
25 byte visual_effect; // NOTE: this is not 100% implemented yet, at the moment it is only used as a 'fallback' value |
|
26 // for when the 'powered wagon' callback fails. But it should really also determine what |
|
27 // kind of visual effect to generate for a vehicle (default, steam, diesel, electric). |
|
28 // Same goes for the callback result, which atm is only used to check if a wagon is powered. |
|
29 byte shorten_factor; // length on main map for this type is 8 - shorten_factor |
|
30 byte tractive_effort; ///< Tractive effort coefficient |
|
31 byte user_def_data; ///! Property 0x25: "User-defined bit mask" Used only for (very few) NewGRF vehicles |
|
32 } RailVehicleInfo; |
|
33 |
|
34 typedef struct ShipVehicleInfo { |
|
35 byte image_index; |
|
36 byte base_cost; |
|
37 uint16 max_speed; |
|
38 CargoID cargo_type; |
|
39 uint16 capacity; |
|
40 byte running_cost; |
|
41 byte sfx; |
|
42 byte refittable; |
|
43 } ShipVehicleInfo; |
|
44 |
|
45 // Aircraft subtypes |
|
46 enum { |
|
47 AIR_CTOL = 1, // Conventional Take Off and Landing, i.e. planes |
|
48 AIR_FAST = 2 |
|
49 }; |
|
50 |
|
51 typedef struct AircraftVehicleInfo { |
|
52 byte image_index; |
|
53 byte base_cost; |
|
54 byte running_cost; |
|
55 byte subtype; |
|
56 byte sfx; |
|
57 byte acceleration; |
|
58 byte max_speed; |
|
59 byte mail_capacity; |
|
60 uint16 passenger_capacity; |
|
61 } AircraftVehicleInfo; |
|
62 |
|
63 typedef struct RoadVehicleInfo { |
|
64 byte image_index; |
|
65 byte base_cost; |
|
66 byte running_cost; |
|
67 byte sfx; |
|
68 byte max_speed; |
|
69 byte capacity; |
|
70 CargoID cargo_type; |
|
71 } RoadVehicleInfo; |
|
72 |
|
73 /** Information about a vehicle |
|
74 * @see table/engines.h |
|
75 */ |
|
76 typedef struct EngineInfo { |
|
77 Date base_intro; |
|
78 byte unk2; ///< Carriages have the highest bit set in this one |
|
79 Year lifelength; |
|
80 Year base_life; |
|
81 byte load_amount; |
|
82 byte railtype:4; |
|
83 byte climates:4; |
|
84 uint32 refit_mask; |
|
85 byte refit_cost; |
|
86 byte misc_flags; |
|
87 byte callbackmask; |
|
88 } EngineInfo; |
|
89 |
|
90 typedef struct Engine { |
|
91 Date intro_date; |
|
92 Date age; |
|
93 uint16 reliability; |
|
94 uint16 reliability_spd_dec; |
|
95 uint16 reliability_start, reliability_max, reliability_final; |
|
96 uint16 duration_phase_1, duration_phase_2, duration_phase_3; |
|
97 byte lifelength; |
|
98 byte flags; |
|
99 byte preview_player; |
|
100 byte preview_wait; |
|
101 byte railtype; |
|
102 byte player_avail; |
|
103 byte type; // type, ie VEH_Road, VEH_Train, etc. Same as in vehicle.h |
|
104 } Engine; |
|
105 |
|
106 /** |
|
107 * EngineInfo.misc_flags is a bitmask, with the following values |
|
108 */ |
|
109 enum { |
|
110 EF_RAIL_TILTS = 0, ///< Rail vehicle tilts in curves (unsupported) |
|
111 EF_ROAD_TRAM = 0, ///< Road vehicle is a tram/light rail vehicle (unsup) |
|
112 EF_USES_2CC = 1, ///< Vehicle uses two company colours |
|
113 EF_RAIL_IS_MU = 2, ///< Rail vehicle is a multiple-unit (DMU/EMU) |
|
114 }; |
|
115 |
|
116 enum { |
|
117 RVI_MULTIHEAD = 1, |
|
118 RVI_WAGON = 2, |
|
119 }; |
|
120 |
|
121 enum { |
|
122 NUM_VEHICLE_TYPES = 6 |
|
123 }; |
|
124 |
|
125 enum { |
|
126 INVALID_ENGINE = 0xFFFF, |
|
127 }; |
|
128 |
|
129 void AddTypeToEngines(void); |
|
130 void StartupEngines(void); |
|
131 |
|
132 |
|
133 void DrawTrainEngine(int x, int y, EngineID engine, uint32 image_ormod); |
|
134 void DrawRoadVehEngine(int x, int y, EngineID engine, uint32 image_ormod); |
|
135 void DrawShipEngine(int x, int y, EngineID engine, uint32 image_ormod); |
|
136 void DrawAircraftEngine(int x, int y, EngineID engine, uint32 image_ormod); |
|
137 |
|
138 void LoadCustomEngineNames(void); |
|
139 void DeleteCustomEngineNames(void); |
|
140 |
|
141 bool IsEngineBuildable(EngineID engine, byte type, PlayerID player); |
|
142 |
|
143 enum { |
|
144 NUM_NORMAL_RAIL_ENGINES = 54, |
|
145 NUM_MONORAIL_ENGINES = 30, |
|
146 NUM_MAGLEV_ENGINES = 32, |
|
147 NUM_TRAIN_ENGINES = NUM_NORMAL_RAIL_ENGINES + NUM_MONORAIL_ENGINES + NUM_MAGLEV_ENGINES, |
|
148 NUM_ROAD_ENGINES = 88, |
|
149 NUM_SHIP_ENGINES = 11, |
|
150 NUM_AIRCRAFT_ENGINES = 41, |
|
151 TOTAL_NUM_ENGINES = NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES + NUM_SHIP_ENGINES + NUM_AIRCRAFT_ENGINES, |
|
152 AIRCRAFT_ENGINES_INDEX = NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES + NUM_SHIP_ENGINES, |
|
153 SHIP_ENGINES_INDEX = NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES, |
|
154 ROAD_ENGINES_INDEX = NUM_TRAIN_ENGINES, |
|
155 }; |
|
156 VARDEF Engine _engines[TOTAL_NUM_ENGINES]; |
|
157 #define FOR_ALL_ENGINES(e) for (e = _engines; e != endof(_engines); e++) |
|
158 |
|
159 static inline Engine* GetEngine(EngineID i) |
|
160 { |
|
161 assert(i < lengthof(_engines)); |
|
162 return &_engines[i]; |
|
163 } |
|
164 |
|
165 VARDEF StringID _engine_name_strings[TOTAL_NUM_ENGINES]; |
|
166 |
|
167 static inline bool IsEngineIndex(uint index) |
|
168 { |
|
169 return index < TOTAL_NUM_ENGINES; |
|
170 } |
|
171 |
|
172 /* Access Vehicle Data */ |
|
173 //#include "table/engines.h" |
|
174 extern const EngineInfo orig_engine_info[TOTAL_NUM_ENGINES]; |
|
175 extern const RailVehicleInfo orig_rail_vehicle_info[NUM_TRAIN_ENGINES]; |
|
176 extern const ShipVehicleInfo orig_ship_vehicle_info[NUM_SHIP_ENGINES]; |
|
177 extern const AircraftVehicleInfo orig_aircraft_vehicle_info[NUM_AIRCRAFT_ENGINES]; |
|
178 extern const RoadVehicleInfo orig_road_vehicle_info[NUM_ROAD_ENGINES]; |
|
179 |
|
180 extern EngineInfo _engine_info[TOTAL_NUM_ENGINES]; |
|
181 extern RailVehicleInfo _rail_vehicle_info[NUM_TRAIN_ENGINES]; |
|
182 extern ShipVehicleInfo _ship_vehicle_info[NUM_SHIP_ENGINES]; |
|
183 extern AircraftVehicleInfo _aircraft_vehicle_info[NUM_AIRCRAFT_ENGINES]; |
|
184 extern RoadVehicleInfo _road_vehicle_info[NUM_ROAD_ENGINES]; |
|
185 |
|
186 static inline const EngineInfo *EngInfo(EngineID e) |
|
187 { |
|
188 assert(e < lengthof(_engine_info)); |
|
189 return &_engine_info[e]; |
|
190 } |
|
191 |
|
192 static inline const RailVehicleInfo* RailVehInfo(EngineID e) |
|
193 { |
|
194 assert(e < lengthof(_rail_vehicle_info)); |
|
195 return &_rail_vehicle_info[e]; |
|
196 } |
|
197 |
|
198 static inline const ShipVehicleInfo* ShipVehInfo(EngineID e) |
|
199 { |
|
200 assert(e >= SHIP_ENGINES_INDEX && e < SHIP_ENGINES_INDEX + lengthof(_ship_vehicle_info)); |
|
201 return &_ship_vehicle_info[e - SHIP_ENGINES_INDEX]; |
|
202 } |
|
203 |
|
204 static inline const AircraftVehicleInfo* AircraftVehInfo(EngineID e) |
|
205 { |
|
206 assert(e >= AIRCRAFT_ENGINES_INDEX && e < AIRCRAFT_ENGINES_INDEX + lengthof(_aircraft_vehicle_info)); |
|
207 return &_aircraft_vehicle_info[e - AIRCRAFT_ENGINES_INDEX]; |
|
208 } |
|
209 |
|
210 static inline const RoadVehicleInfo* RoadVehInfo(EngineID e) |
|
211 { |
|
212 assert(e >= ROAD_ENGINES_INDEX && e < ROAD_ENGINES_INDEX + lengthof(_road_vehicle_info)); |
|
213 return &_road_vehicle_info[e - ROAD_ENGINES_INDEX]; |
|
214 } |
|
215 |
|
216 /************************************************************************ |
|
217 * Engine Replacement stuff |
|
218 ************************************************************************/ |
|
219 |
|
220 /** |
|
221 * Struct to store engine replacements. DO NOT USE outside of engine.c. Is |
|
222 * placed here so the only exception to this rule, the saveload code, can use |
|
223 * it. |
|
224 */ |
|
225 struct EngineRenew { |
|
226 EngineRenewID index; |
|
227 EngineID from; |
|
228 EngineID to; |
|
229 struct EngineRenew *next; |
|
230 }; |
|
231 |
|
232 typedef struct EngineRenew EngineRenew; |
|
233 |
|
234 /** |
|
235 * Memory pool for engine renew elements. DO NOT USE outside of engine.c. Is |
|
236 * placed here so the only exception to this rule, the saveload code, can use |
|
237 * it. |
|
238 */ |
|
239 DECLARE_OLD_POOL(EngineRenew, EngineRenew, 3, 8000) |
|
240 |
|
241 /** |
|
242 * Check if a EngineRenew really exists. |
|
243 */ |
|
244 static inline bool IsValidEngineRenew(const EngineRenew *er) |
|
245 { |
|
246 return er->from != INVALID_ENGINE; |
|
247 } |
|
248 |
|
249 static inline void DeleteEngineRenew(EngineRenew *er) |
|
250 { |
|
251 er->from = INVALID_ENGINE; |
|
252 } |
|
253 |
|
254 #define FOR_ALL_ENGINE_RENEWS_FROM(er, start) for (er = GetEngineRenew(start); er != NULL; er = (er->index + 1U < GetEngineRenewPoolSize()) ? GetEngineRenew(er->index + 1U) : NULL) if (er->from != INVALID_ENGINE) if (IsValidEngineRenew(er)) |
|
255 #define FOR_ALL_ENGINE_RENEWS(er) FOR_ALL_ENGINE_RENEWS_FROM(er, 0) |
|
256 |
|
257 |
|
258 /** |
|
259 * A list to group EngineRenew directives together (such as per-player). |
|
260 */ |
|
261 typedef EngineRenew* EngineRenewList; |
|
262 |
|
263 /** |
|
264 * Remove all engine replacement settings for the player. |
|
265 * @param er The renewlist for a given player. |
|
266 * @return The new renewlist for the player. |
|
267 */ |
|
268 void RemoveAllEngineReplacement(EngineRenewList* erl); |
|
269 |
|
270 /** |
|
271 * Retrieve the engine replacement in a given renewlist for an original engine type. |
|
272 * @param erl The renewlist to search in. |
|
273 * @param engine Engine type to be replaced. |
|
274 * @return The engine type to replace with, or INVALID_ENGINE if no |
|
275 * replacement is in the list. |
|
276 */ |
|
277 EngineID EngineReplacement(EngineRenewList erl, EngineID engine); |
|
278 |
|
279 /** |
|
280 * Add an engine replacement to the given renewlist. |
|
281 * @param erl The renewlist to add to. |
|
282 * @param old_engine The original engine type. |
|
283 * @param new_engine The replacement engine type. |
|
284 * @param flags The calling command flags. |
|
285 * @return 0 on success, CMD_ERROR on failure. |
|
286 */ |
|
287 int32 AddEngineReplacement(EngineRenewList* erl, EngineID old_engine, EngineID new_engine, uint32 flags); |
|
288 |
|
289 /** |
|
290 * Remove an engine replacement from a given renewlist. |
|
291 * @param erl The renewlist from which to remove the replacement |
|
292 * @param engine The original engine type. |
|
293 * @param flags The calling command flags. |
|
294 * @return 0 on success, CMD_ERROR on failure. |
|
295 */ |
|
296 int32 RemoveEngineReplacement(EngineRenewList* erl, EngineID engine, uint32 flags); |
|
297 |
|
298 /* Engine list manipulators - current implementation is only C wrapper of CBlobT<EngineID> class (helpers.cpp) */ |
|
299 void EngList_Create(EngineList *el); ///< Creates engine list |
|
300 void EngList_Destroy(EngineList *el); ///< Deallocate and destroy engine list |
|
301 uint EngList_Count(const EngineList *el); ///< Returns number of items in the engine list |
|
302 void EngList_Add(EngineList *el, EngineID eid); ///< Append one item at the end of engine list |
|
303 EngineID* EngList_Items(EngineList *el); ///< Returns engine list items as C array |
|
304 void EngList_RemoveAll(EngineList *el); ///< Removes all items from engine list |
|
305 typedef int CDECL EngList_SortTypeFunction(const void*, const void*); ///< argument type for EngList_Sort() |
|
306 void EngList_Sort(EngineList *el, EngList_SortTypeFunction compare); ///< qsort of the engine list |
|
307 void EngList_SortPartial(EngineList *el, EngList_SortTypeFunction compare, uint begin, uint num_items); ///< qsort of specified portion of the engine list |
|
308 |
|
309 #endif /* ENGINE_H */ |