author | dominik |
Thu, 09 Dec 2004 23:16:52 +0000 | |
changeset 579 | e977d17c89b1 |
parent 578 | 1e66514eb621 |
child 584 | e36fcfe33aea |
permissions | -rw-r--r-- |
0 | 1 |
#include "stdafx.h" |
2 |
#include "ttd.h" |
|
507
04b5403aaf6b
(svn r815) Include strings.h only in the files which need it.
tron
parents:
445
diff
changeset
|
3 |
#include "table/strings.h" |
0 | 4 |
#include "vehicle.h" |
5 |
#include "gfx.h" |
|
6 |
//#include "station.h" |
|
7 |
#include "viewport.h" |
|
8 |
#include "news.h" |
|
9 |
#include "command.h" |
|
10 |
#include "saveload.h" |
|
11 |
#include "player.h" |
|
12 |
#include "engine.h" |
|
337
cbe0c766c947
(svn r513) Merge revisions 402, 416, 417, 478, 479, 511, 512 from map to trunk
tron
parents:
260
diff
changeset
|
13 |
#include "sound.h" |
0 | 14 |
|
15 |
#define INVALID_COORD (-0x8000) |
|
16 |
#define GEN_HASH(x,y) (((x & 0x1F80)>>7) + ((y & 0xFC0))) |
|
17 |
||
578
1e66514eb621
(svn r998) now vehicles are serviced both when entering and when leaving depots to prevent that vehicles might need service when leaving after a long stay (ln--)
bjarni
parents:
577
diff
changeset
|
18 |
void VehicleServiceInDepot(Vehicle *v) |
1e66514eb621
(svn r998) now vehicles are serviced both when entering and when leaving depots to prevent that vehicles might need service when leaving after a long stay (ln--)
bjarni
parents:
577
diff
changeset
|
19 |
{ |
1e66514eb621
(svn r998) now vehicles are serviced both when entering and when leaving depots to prevent that vehicles might need service when leaving after a long stay (ln--)
bjarni
parents:
577
diff
changeset
|
20 |
v->date_of_last_service = _date; |
1e66514eb621
(svn r998) now vehicles are serviced both when entering and when leaving depots to prevent that vehicles might need service when leaving after a long stay (ln--)
bjarni
parents:
577
diff
changeset
|
21 |
v->breakdowns_since_last_service = 0; |
1e66514eb621
(svn r998) now vehicles are serviced both when entering and when leaving depots to prevent that vehicles might need service when leaving after a long stay (ln--)
bjarni
parents:
577
diff
changeset
|
22 |
v->reliability = _engines[v->engine_type].reliability; |
1e66514eb621
(svn r998) now vehicles are serviced both when entering and when leaving depots to prevent that vehicles might need service when leaving after a long stay (ln--)
bjarni
parents:
577
diff
changeset
|
23 |
} |
0 | 24 |
|
577 | 25 |
Order UnpackOldOrder(uint16 packed) |
26 |
{ |
|
27 |
Order order; |
|
28 |
order.type = (packed & 0x000f); |
|
29 |
order.flags = (packed & 0x00f0) >> 4, |
|
30 |
order.station = (packed & 0xff00) >> 8; |
|
31 |
||
32 |
// Sanity check |
|
33 |
// TTD stores invalid orders as OT_NOTHING with non-zero flags/station |
|
34 |
if (order.type == OT_NOTHING && (order.flags != 0 || order.station != 0)) { |
|
35 |
order.type = OT_DUMMY; |
|
36 |
order.flags = 0; |
|
37 |
} |
|
38 |
||
39 |
return order; |
|
40 |
} |
|
41 |
||
42 |
||
0 | 43 |
void VehicleInTheWayErrMsg(Vehicle *v) |
44 |
{ |
|
45 |
StringID id; |
|
46 |
||
47 |
(id = STR_8803_TRAIN_IN_THE_WAY,v->type == VEH_Train) || |
|
48 |
(id = STR_9000_ROAD_VEHICLE_IN_THE_WAY,v->type == VEH_Road) || |
|
49 |
(id = STR_A015_AIRCRAFT_IN_THE_WAY,v->type == VEH_Aircraft) || |
|
50 |
(id = STR_980E_SHIP_IN_THE_WAY, true); |
|
51 |
||
52 |
_error_message = id; |
|
53 |
} |
|
54 |
||
55 |
static void *EnsureNoVehicleProc(Vehicle *v, void *data) |
|
56 |
{ |
|
537
901bd4c077f0
(svn r909) Small cleanup in vehicle.c, this should fix some warnings on 64bit machines
tron
parents:
534
diff
changeset
|
57 |
if (v->tile != *(const TileIndex*)data || v->type == VEH_Disaster) |
0 | 58 |
return NULL; |
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
59 |
|
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
60 |
VehicleInTheWayErrMsg(v); |
537
901bd4c077f0
(svn r909) Small cleanup in vehicle.c, this should fix some warnings on 64bit machines
tron
parents:
534
diff
changeset
|
61 |
return v; |
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
62 |
} |
0 | 63 |
|
64 |
bool EnsureNoVehicle(TileIndex tile) |
|
65 |
{ |
|
537
901bd4c077f0
(svn r909) Small cleanup in vehicle.c, this should fix some warnings on 64bit machines
tron
parents:
534
diff
changeset
|
66 |
return VehicleFromPos(tile, &tile, EnsureNoVehicleProc) == NULL; |
0 | 67 |
} |
68 |
||
69 |
static void *EnsureNoVehicleProcZ(Vehicle *v, void *data) |
|
70 |
{ |
|
537
901bd4c077f0
(svn r909) Small cleanup in vehicle.c, this should fix some warnings on 64bit machines
tron
parents:
534
diff
changeset
|
71 |
const TileInfo *ti = data; |
901bd4c077f0
(svn r909) Small cleanup in vehicle.c, this should fix some warnings on 64bit machines
tron
parents:
534
diff
changeset
|
72 |
|
901bd4c077f0
(svn r909) Small cleanup in vehicle.c, this should fix some warnings on 64bit machines
tron
parents:
534
diff
changeset
|
73 |
if (v->tile != ti->tile || v->z_pos != ti->z || v->type == VEH_Disaster) |
0 | 74 |
return NULL; |
75 |
||
76 |
VehicleInTheWayErrMsg(v); |
|
537
901bd4c077f0
(svn r909) Small cleanup in vehicle.c, this should fix some warnings on 64bit machines
tron
parents:
534
diff
changeset
|
77 |
return v; |
0 | 78 |
} |
79 |
||
80 |
bool EnsureNoVehicleZ(TileIndex tile, byte z) |
|
81 |
{ |
|
82 |
TileInfo ti; |
|
537
901bd4c077f0
(svn r909) Small cleanup in vehicle.c, this should fix some warnings on 64bit machines
tron
parents:
534
diff
changeset
|
83 |
|
0 | 84 |
FindLandscapeHeightByTile(&ti, tile); |
85 |
// needs z correction for slope-type graphics that have the NORTHERN tile lowered |
|
86 |
// 1, 2, 3, 4, 5, 6 and 7 |
|
87 |
if (CORRECT_Z(ti.tileh)) |
|
88 |
z += 8; |
|
89 |
||
537
901bd4c077f0
(svn r909) Small cleanup in vehicle.c, this should fix some warnings on 64bit machines
tron
parents:
534
diff
changeset
|
90 |
ti.z = z; |
901bd4c077f0
(svn r909) Small cleanup in vehicle.c, this should fix some warnings on 64bit machines
tron
parents:
534
diff
changeset
|
91 |
|
901bd4c077f0
(svn r909) Small cleanup in vehicle.c, this should fix some warnings on 64bit machines
tron
parents:
534
diff
changeset
|
92 |
return VehicleFromPos(tile, &ti, EnsureNoVehicleProcZ) == NULL; |
0 | 93 |
} |
94 |
||
95 |
Vehicle *FindVehicleBetween(TileIndex from, TileIndex to, byte z) |
|
96 |
{ |
|
97 |
int x1 = GET_TILE_X(from); |
|
98 |
int y1 = GET_TILE_Y(from); |
|
99 |
int x2 = GET_TILE_X(to); |
|
100 |
int y2 = GET_TILE_Y(to); |
|
101 |
Vehicle *veh; |
|
102 |
uint count; |
|
103 |
||
104 |
/* Make sure x1 < x2 or y1 < y2 */ |
|
105 |
if (x1 > x2 || y1 > y2) { |
|
106 |
intswap(x1,x2); |
|
107 |
intswap(y1,y2); |
|
108 |
} |
|
109 |
for(veh = _vehicles, count=lengthof(_vehicles); count != 0; count--, veh++) { |
|
110 |
if ((veh->type == VEH_Train || veh->type == VEH_Road) && (z==0xFF || veh->z_pos == z)) { |
|
111 |
if ((veh->x_pos>>4) >= x1 && (veh->x_pos>>4) <= x2 && |
|
112 |
(veh->y_pos>>4) >= y1 && (veh->y_pos>>4) <= y2) { |
|
113 |
return veh; |
|
114 |
} |
|
115 |
} |
|
116 |
} |
|
117 |
return NULL; |
|
118 |
} |
|
119 |
||
120 |
void VehiclePositionChanged(Vehicle *v) |
|
121 |
{ |
|
122 |
int img = v->cur_image; |
|
123 |
const SpriteDimension *sd; |
|
124 |
Point pt = RemapCoords(v->x_pos + v->x_offs, v->y_pos + v->y_offs, v->z_pos); |
|
125 |
||
126 |
sd = GetSpriteDimension(img); |
|
127 |
||
128 |
pt.x += sd->xoffs; |
|
129 |
pt.y += sd->yoffs; |
|
130 |
||
131 |
UpdateVehiclePosHash(v, pt.x, pt.y); |
|
132 |
||
133 |
v->left_coord = pt.x; |
|
134 |
v->top_coord = pt.y; |
|
135 |
v->right_coord = pt.x + sd->xsize + 2; |
|
136 |
v->bottom_coord = pt.y + sd->ysize + 2; |
|
137 |
} |
|
138 |
||
395
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
139 |
void UpdateWaypointSign(Waypoint *cp) |
0 | 140 |
{ |
141 |
Point pt = RemapCoords2(GET_TILE_X(cp->xy)*16, GET_TILE_Y(cp->xy)*16); |
|
534
306bc86eb23e
(svn r901) Small step in the process to clean up the DPARAM mess:
tron
parents:
507
diff
changeset
|
142 |
SetDParam(0, cp - _waypoints); |
395
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
143 |
UpdateViewportSignPos(&cp->sign, pt.x, pt.y - 0x20, STR_WAYPOINT_VIEWPORT); |
0 | 144 |
} |
145 |
||
395
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
146 |
void RedrawWaypointSign(Waypoint *cp) |
0 | 147 |
{ |
148 |
MarkAllViewportsDirty( |
|
149 |
cp->sign.left - 6, |
|
150 |
cp->sign.top, |
|
151 |
cp->sign.left + (cp->sign.width_1 << 2) + 12, |
|
152 |
cp->sign.top + 48); |
|
153 |
} |
|
154 |
||
155 |
// Called after load to update coordinates |
|
156 |
void AfterLoadVehicles() |
|
157 |
{ |
|
158 |
Vehicle *v; |
|
395
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
159 |
Waypoint *cp; |
0 | 160 |
|
161 |
FOR_ALL_VEHICLES(v) { |
|
162 |
if (v->type != 0) { |
|
163 |
v->left_coord = INVALID_COORD; |
|
164 |
VehiclePositionChanged(v); |
|
165 |
||
166 |
if (v->type == VEH_Train) { |
|
167 |
if (v->subtype == 0) |
|
168 |
UpdateTrainAcceleration(v); |
|
169 |
} |
|
170 |
||
171 |
#if defined(_DEBUG) |
|
172 |
if (!(v->schedule_ptr == NULL || (v->schedule_ptr >= _order_array && v->schedule_ptr < _ptr_to_next_order))) |
|
173 |
v->schedule_ptr = NULL; |
|
174 |
#endif |
|
175 |
} |
|
176 |
} |
|
177 |
||
395
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
178 |
// update waypoint signs |
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
179 |
for(cp=_waypoints; cp != endof(_waypoints); cp++) if (cp->xy) UpdateWaypointSign(cp); |
0 | 180 |
} |
181 |
||
182 |
||
183 |
static Vehicle *InitializeVehicle(Vehicle *v) |
|
184 |
{ |
|
185 |
VehicleID index = v->index; |
|
186 |
memset(v, 0, sizeof(Vehicle)); |
|
187 |
v->index = index; |
|
188 |
||
189 |
assert(v->schedule_ptr == NULL); |
|
190 |
||
191 |
v->left_coord = INVALID_COORD; |
|
192 |
v->next = NULL; |
|
193 |
v->next_hash = 0xffff; |
|
194 |
v->string_id = 0; |
|
548
440429cbe70d
(svn r948) -Codechange: clearified my last commit a bit more with some comment in the code
truelight
parents:
547
diff
changeset
|
195 |
/* random_bits is used to pick out a random sprite for vehicles |
440429cbe70d
(svn r948) -Codechange: clearified my last commit a bit more with some comment in the code
truelight
parents:
547
diff
changeset
|
196 |
which are technical the same (newgrf stuff). |
440429cbe70d
(svn r948) -Codechange: clearified my last commit a bit more with some comment in the code
truelight
parents:
547
diff
changeset
|
197 |
Because RandomRange() results in desyncs, and because it does |
440429cbe70d
(svn r948) -Codechange: clearified my last commit a bit more with some comment in the code
truelight
parents:
547
diff
changeset
|
198 |
not really matter that one client has other visual vehicles then |
440429cbe70d
(svn r948) -Codechange: clearified my last commit a bit more with some comment in the code
truelight
parents:
547
diff
changeset
|
199 |
the other, it can be InteractiveRandomRange() without any problem |
440429cbe70d
(svn r948) -Codechange: clearified my last commit a bit more with some comment in the code
truelight
parents:
547
diff
changeset
|
200 |
*/ |
547 | 201 |
v->random_bits = InteractiveRandomRange(256); |
0 | 202 |
return v; |
203 |
} |
|
204 |
||
205 |
Vehicle *ForceAllocateSpecialVehicle() |
|
206 |
{ |
|
207 |
Vehicle *v; |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
208 |
for(v=_vehicles + NUM_NORMAL_VEHICLES; |
0 | 209 |
v!=&_vehicles[NUM_NORMAL_VEHICLES+NUM_SPECIAL_VEHICLES]; v++) { |
210 |
if (v->type == 0) |
|
211 |
return InitializeVehicle(v); |
|
212 |
} |
|
213 |
return NULL; |
|
214 |
||
215 |
} |
|
216 |
||
217 |
Vehicle *ForceAllocateVehicle() |
|
218 |
{ |
|
219 |
Vehicle *v; |
|
220 |
for(v=_vehicles; v!=&_vehicles[NUM_NORMAL_VEHICLES]; v++) { |
|
221 |
if (v->type == 0) |
|
222 |
return InitializeVehicle(v); |
|
223 |
} |
|
224 |
return NULL; |
|
225 |
} |
|
226 |
||
227 |
Vehicle *AllocateVehicle() |
|
228 |
{ |
|
229 |
Vehicle *v; |
|
230 |
int num; |
|
231 |
||
232 |
if (IS_HUMAN_PLAYER(_current_player)) { |
|
233 |
num = 0; |
|
234 |
||
235 |
for(v=_vehicles; v!=&_vehicles[NUM_NORMAL_VEHICLES]; v++) { |
|
236 |
if (v->type == 0) |
|
237 |
num++; |
|
238 |
} |
|
239 |
||
240 |
if (num <= 90) |
|
241 |
return NULL; |
|
242 |
} |
|
243 |
||
244 |
return ForceAllocateVehicle(); |
|
245 |
} |
|
246 |
||
247 |
void *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc) |
|
248 |
{ |
|
249 |
int x,y,x2,y2; |
|
250 |
VehicleID veh; |
|
251 |
Point pt = RemapCoords(GET_TILE_X(tile) * 16, GET_TILE_Y(tile) * 16, 0); |
|
252 |
||
253 |
x2 = ((pt.x + 104) & 0x1F80) >> 7; |
|
254 |
x = ((pt.x - 174) & 0x1F80) >> 7; |
|
255 |
||
256 |
y2 = ((pt.y + 56) & 0xFC0); |
|
257 |
y = ((pt.y - 294) & 0xFC0); |
|
258 |
||
259 |
for(;;) { |
|
260 |
int xb = x; |
|
261 |
for(;;) { |
|
262 |
veh = _vehicle_position_hash[ (x+y)&0xFFFF ]; |
|
263 |
while (veh != INVALID_VEHICLE) { |
|
264 |
Vehicle *v = &_vehicles[veh]; |
|
265 |
void *a; |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
266 |
|
0 | 267 |
if ((a = proc(v, data)) != NULL) |
268 |
return a; |
|
269 |
veh = v->next_hash; |
|
270 |
} |
|
271 |
||
272 |
if (x == x2) |
|
273 |
break; |
|
274 |
||
275 |
x = (x + 1) & 0x3F; |
|
276 |
} |
|
277 |
x = xb; |
|
278 |
||
279 |
if (y == y2) |
|
280 |
break; |
|
281 |
||
282 |
y = (y + 0x40) & ((0x3F) << 6); |
|
283 |
} |
|
284 |
return NULL; |
|
285 |
} |
|
286 |
||
287 |
||
288 |
||
289 |
void UpdateVehiclePosHash(Vehicle *v, int x, int y) |
|
290 |
{ |
|
291 |
VehicleID *old_hash, *new_hash; |
|
292 |
int old_x = v->left_coord; |
|
293 |
int old_y = v->top_coord; |
|
294 |
Vehicle *u; |
|
295 |
||
296 |
new_hash = (x == INVALID_COORD) ? NULL : &_vehicle_position_hash[GEN_HASH(x,y)]; |
|
297 |
old_hash = (old_x == INVALID_COORD) ? NULL : &_vehicle_position_hash[GEN_HASH(old_x, old_y)]; |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
298 |
|
0 | 299 |
if (old_hash == new_hash) |
300 |
return; |
|
301 |
||
302 |
/* remove from hash table? */ |
|
303 |
if (old_hash != NULL) { |
|
304 |
Vehicle *last = NULL; |
|
305 |
int idx = *old_hash; |
|
306 |
while((u = &_vehicles[idx]) != v) { |
|
307 |
idx = u->next_hash; |
|
308 |
assert(idx != INVALID_VEHICLE); |
|
309 |
last = u; |
|
310 |
} |
|
311 |
||
312 |
if (last == NULL) |
|
313 |
*old_hash = v->next_hash; |
|
314 |
else |
|
315 |
last->next_hash = v->next_hash; |
|
316 |
} |
|
317 |
||
318 |
/* insert into hash table? */ |
|
319 |
if (new_hash != NULL) { |
|
320 |
v->next_hash = *new_hash; |
|
321 |
*new_hash = v->index; |
|
322 |
} |
|
323 |
} |
|
324 |
||
325 |
void InitializeVehicles() |
|
326 |
{ |
|
327 |
Vehicle *v; |
|
328 |
int i; |
|
329 |
||
330 |
// clear it... |
|
331 |
memset(&_vehicles, 0, sizeof(_vehicles)); |
|
395
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
332 |
memset(&_waypoints, 0, sizeof(_waypoints)); |
0 | 333 |
memset(&_depots, 0, sizeof(_depots)); |
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
334 |
|
0 | 335 |
// setup indexes.. |
336 |
i = 0; |
|
337 |
FOR_ALL_VEHICLES(v) |
|
338 |
v->index = i++; |
|
339 |
||
340 |
memset(_vehicle_position_hash, -1, sizeof(_vehicle_position_hash)); |
|
341 |
||
342 |
_ptr_to_next_order = _order_array; |
|
343 |
} |
|
344 |
||
345 |
Vehicle *GetLastVehicleInChain(Vehicle *v) |
|
346 |
{ |
|
347 |
while (v->next != NULL) v = v->next; |
|
348 |
return v; |
|
349 |
} |
|
350 |
||
351 |
Vehicle *GetPrevVehicleInChain(Vehicle *v) |
|
352 |
{ |
|
353 |
Vehicle *org = v; |
|
354 |
||
355 |
v = _vehicles; |
|
356 |
while (v->type != VEH_Train || org != v->next) { |
|
357 |
if (++v == endof(_vehicles)) |
|
358 |
return NULL; |
|
359 |
} |
|
360 |
||
361 |
return v; |
|
362 |
} |
|
363 |
||
364 |
Vehicle *GetFirstVehicleInChain(Vehicle *v) |
|
365 |
{ |
|
366 |
for(;;) { |
|
367 |
Vehicle *u = v; |
|
368 |
v = _vehicles; |
|
369 |
while (v->type != VEH_Train || u != v->next) { |
|
370 |
if (++v == endof(_vehicles)) |
|
371 |
return u; |
|
372 |
} |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
373 |
} |
0 | 374 |
} |
375 |
||
376 |
int CountVehiclesInChain(Vehicle *v) |
|
377 |
{ |
|
378 |
int count = 0; |
|
379 |
do count++; while ( (v=v->next) != NULL); |
|
380 |
return count; |
|
381 |
} |
|
382 |
||
383 |
||
384 |
Depot *AllocateDepot() |
|
385 |
{ |
|
386 |
Depot *dep, *free_dep = NULL; |
|
387 |
int num_free = 0; |
|
388 |
||
389 |
for(dep = _depots; dep != endof(_depots); dep++) { |
|
390 |
if (dep->xy == 0) { |
|
391 |
num_free++; |
|
392 |
if (free_dep==NULL) |
|
393 |
free_dep = dep; |
|
394 |
} |
|
395 |
} |
|
396 |
||
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
397 |
if (free_dep == NULL || |
0 | 398 |
(num_free < 30 && IS_HUMAN_PLAYER(_current_player))) { |
399 |
_error_message = STR_1009_TOO_MANY_DEPOTS; |
|
400 |
return NULL; |
|
401 |
} |
|
402 |
||
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
403 |
return free_dep; |
0 | 404 |
} |
405 |
||
395
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
406 |
Waypoint *AllocateWaypoint() |
0 | 407 |
{ |
395
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
408 |
Waypoint *cp; |
0 | 409 |
|
395
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
410 |
for(cp = _waypoints; cp != endof(_waypoints); cp++) { |
0 | 411 |
if (cp->xy == 0) |
412 |
return cp; |
|
413 |
} |
|
414 |
||
415 |
return NULL; |
|
416 |
} |
|
417 |
||
395
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
418 |
uint GetWaypointByTile(uint tile) |
0 | 419 |
{ |
395
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
420 |
Waypoint *cp; |
0 | 421 |
int i=0; |
395
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
422 |
for(cp=_waypoints; cp->xy != (TileIndex)tile; cp++) { i++; } |
0 | 423 |
return i; |
424 |
} |
|
425 |
||
426 |
||
427 |
Vehicle *IsScheduleShared(Vehicle *u) |
|
428 |
{ |
|
555
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
429 |
const Order *sched = u->schedule_ptr; |
0 | 430 |
Vehicle *v; |
431 |
||
432 |
FOR_ALL_VEHICLES(v) { |
|
433 |
if (v->schedule_ptr == sched && u != v && v->type != 0) |
|
434 |
return v; |
|
435 |
} |
|
436 |
return NULL; |
|
437 |
} |
|
438 |
||
439 |
void DeleteVehicleSchedule(Vehicle *v) |
|
440 |
{ |
|
555
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
441 |
Order *sched; |
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
442 |
Order *cur; |
0 | 443 |
int num; |
444 |
Vehicle *u; |
|
445 |
||
446 |
// if the schedule is shared, don't delete it. |
|
447 |
if ((u = IsScheduleShared(v)) != NULL) { |
|
448 |
v->schedule_ptr = NULL; |
|
449 |
InvalidateWindow(WC_VEHICLE_ORDERS, u->index); |
|
450 |
return; |
|
451 |
} |
|
452 |
||
453 |
sched = v->schedule_ptr; |
|
454 |
v->schedule_ptr = NULL; |
|
455 |
||
456 |
num = v->num_orders + 1; |
|
457 |
||
458 |
_ptr_to_next_order -= num; |
|
459 |
||
460 |
cur = sched; |
|
461 |
while (cur != _ptr_to_next_order) { |
|
462 |
assert(cur < _ptr_to_next_order); |
|
463 |
cur[0] = cur[num]; |
|
464 |
cur++; |
|
465 |
} |
|
466 |
||
467 |
FOR_ALL_VEHICLES(v) { |
|
468 |
if (v->schedule_ptr != NULL && sched < v->schedule_ptr) { |
|
469 |
v->schedule_ptr -= num; |
|
470 |
} |
|
471 |
} |
|
472 |
} |
|
473 |
||
555
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
474 |
void DeleteCommandFromVehicleSchedule(Order cmd) |
0 | 475 |
{ |
476 |
Vehicle *v; |
|
477 |
bool need_invalidate; |
|
478 |
||
479 |
FOR_ALL_VEHICLES(v) { |
|
480 |
if (v->type != 0 && v->schedule_ptr != NULL) { |
|
555
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
481 |
Order *sched; |
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
482 |
|
0 | 483 |
// clear last station visited |
555
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
484 |
if (v->last_station_visited == cmd.station && cmd.type == OT_GOTO_STATION) |
0 | 485 |
v->last_station_visited = 0xFF; |
486 |
||
487 |
// check the next order |
|
555
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
488 |
if (v->current_order.type == cmd.type && |
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
489 |
v->current_order.station == cmd.station) { |
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
490 |
v->current_order.type = OT_DUMMY; |
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
491 |
v->current_order.flags = 0; |
0 | 492 |
InvalidateWindow(WC_VEHICLE_VIEW, v->index); |
493 |
} |
|
494 |
||
495 |
// clear the order list |
|
496 |
need_invalidate = false; |
|
555
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
497 |
for (sched = v->schedule_ptr; sched->type != OT_NOTHING; ++sched) { |
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
498 |
if (sched->type == cmd.type && sched->station == cmd.station) { |
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
499 |
sched->type = OT_DUMMY; |
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
500 |
sched->flags = 0; |
0 | 501 |
need_invalidate = true; |
502 |
} |
|
503 |
} |
|
504 |
||
505 |
if (need_invalidate) |
|
506 |
InvalidateWindow(WC_VEHICLE_ORDERS, v->index); |
|
507 |
} |
|
508 |
} |
|
509 |
} |
|
510 |
||
511 |
void DoDeleteDepot(uint tile) |
|
512 |
{ |
|
555
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
513 |
Order order; |
0 | 514 |
byte dep_index; |
515 |
Depot *d; |
|
516 |
||
517 |
// Clear it |
|
518 |
DoClearSquare(tile); |
|
519 |
||
520 |
// Nullify the depot struct |
|
521 |
for(d=_depots,dep_index=0; d->xy != (TileIndex)tile; d++) {dep_index++;} |
|
522 |
d->xy = 0; |
|
523 |
||
555
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
524 |
order.type = OT_GOTO_DEPOT; |
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
525 |
order.flags = 0; |
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
526 |
order.station = dep_index; |
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
527 |
DeleteCommandFromVehicleSchedule(order); |
0 | 528 |
|
529 |
// Delete the depot |
|
530 |
DeleteWindowById(WC_VEHICLE_DEPOT, tile); |
|
531 |
} |
|
532 |
||
533 |
void DeleteVehicle(Vehicle *v) |
|
534 |
{ |
|
535 |
DeleteName(v->string_id); |
|
536 |
v->type = 0; |
|
537 |
UpdateVehiclePosHash(v, INVALID_COORD, 0); |
|
538 |
v->next_hash = 0xffff; |
|
539 |
||
540 |
if (v->schedule_ptr != NULL) |
|
541 |
DeleteVehicleSchedule(v); |
|
542 |
} |
|
543 |
||
544 |
void DeleteVehicleChain(Vehicle *v) |
|
545 |
{ |
|
546 |
do { |
|
547 |
Vehicle *u = v; |
|
548 |
v = v->next; |
|
549 |
DeleteVehicle(u); |
|
550 |
} while (v); |
|
551 |
} |
|
552 |
||
553 |
||
554 |
void Aircraft_Tick(Vehicle *v); |
|
555 |
void RoadVeh_Tick(Vehicle *v); |
|
556 |
void Ship_Tick(Vehicle *v); |
|
557 |
void Train_Tick(Vehicle *v); |
|
410 | 558 |
static void EffectVehicle_Tick(Vehicle *v); |
0 | 559 |
void DisasterVehicle_Tick(Vehicle *v); |
560 |
||
561 |
VehicleTickProc *_vehicle_tick_procs[] = { |
|
562 |
Train_Tick, |
|
563 |
RoadVeh_Tick, |
|
564 |
Ship_Tick, |
|
565 |
Aircraft_Tick, |
|
566 |
EffectVehicle_Tick, |
|
567 |
DisasterVehicle_Tick, |
|
568 |
}; |
|
569 |
||
570 |
void CallVehicleTicks() |
|
571 |
{ |
|
572 |
Vehicle *v; |
|
573 |
||
574 |
FOR_ALL_VEHICLES(v) { |
|
575 |
if (v->type != 0) |
|
576 |
_vehicle_tick_procs[v->type - 0x10](v); |
|
577 |
} |
|
578 |
} |
|
579 |
||
580 |
static bool CanFillVehicle_FullLoadAny(Vehicle *v) |
|
581 |
{ |
|
582 |
uint32 full = 0, not_full = 0; |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
583 |
|
0 | 584 |
// patch should return "true" to continue loading, i.e. when there is no cargo type that is fully loaded. |
585 |
do { |
|
586 |
//Should never happen, but just in case future additions change this |
|
587 |
assert(v->cargo_type<32); |
|
588 |
||
589 |
if (v->cargo_cap != 0) { |
|
590 |
uint32 mask = 1 << v->cargo_type; |
|
591 |
if (v->cargo_cap == v->cargo_count) full |= mask; else not_full |= mask; |
|
592 |
} |
|
593 |
} while ( (v=v->next) != NULL); |
|
594 |
||
595 |
// continue loading if there is a non full cargo type and no cargo type that is full |
|
596 |
return not_full && (full & ~not_full) == 0; |
|
597 |
} |
|
598 |
||
599 |
bool CanFillVehicle(Vehicle *v) |
|
600 |
{ |
|
601 |
byte *t = &_map_type_and_height[v->tile]; |
|
602 |
||
603 |
if (t[0] >> 4 == MP_STATION || |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
604 |
(v->type == VEH_Ship && |
0 | 605 |
(t[TILE_XY(1,0)] >> 4 == MP_STATION || |
606 |
t[TILE_XY(-1,0)] >> 4 == MP_STATION || |
|
607 |
t[TILE_XY(0,1)] >> 4 == MP_STATION || |
|
608 |
t[TILE_XY(0,-1)] >> 4 == MP_STATION || |
|
609 |
t[TILE_XY(-2,0)] >> 4 == MP_STATION))) { |
|
610 |
||
611 |
// If patch is active, use alternative CanFillVehicle-function |
|
612 |
if (_patches.full_load_any) |
|
613 |
return CanFillVehicle_FullLoadAny(v); |
|
614 |
||
615 |
do { |
|
616 |
if (v->cargo_count != v->cargo_cap) |
|
617 |
return true; |
|
618 |
} while ( (v=v->next) != NULL); |
|
619 |
} |
|
620 |
return false; |
|
621 |
} |
|
622 |
||
623 |
static void DoDrawVehicle(Vehicle *v) |
|
624 |
{ |
|
625 |
uint32 image = v->cur_image; |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
626 |
|
0 | 627 |
if (v->vehstatus & VS_DISASTER) { |
628 |
image |= 0x3224000; |
|
629 |
} else if (v->vehstatus & VS_DEFPAL) { |
|
630 |
image |= (v->vehstatus & VS_CRASHED) ? 0x3248000 : SPRITE_PALETTE(PLAYER_SPRITE_COLOR(v->owner)); |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
631 |
} |
0 | 632 |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
633 |
AddSortableSpriteToDraw(image, v->x_pos + v->x_offs, v->y_pos + v->y_offs, |
0 | 634 |
v->sprite_width, v->sprite_height, v->z_height, v->z_pos); |
635 |
} |
|
636 |
||
637 |
void ViewportAddVehicles(DrawPixelInfo *dpi) |
|
638 |
{ |
|
639 |
int x,xb, y, x2, y2; |
|
640 |
VehicleID veh; |
|
641 |
Vehicle *v; |
|
642 |
||
643 |
x = ((dpi->left - 70) & 0x1F80) >> 7; |
|
644 |
x2 = ((dpi->left + dpi->width) & 0x1F80) >> 7; |
|
645 |
||
646 |
y = ((dpi->top - 70) & 0xFC0); |
|
647 |
y2 = ((dpi->top + dpi->height) & 0xFC0); |
|
648 |
||
649 |
for(;;) { |
|
650 |
xb = x; |
|
651 |
for(;;) { |
|
652 |
veh = _vehicle_position_hash[ (x+y)&0xFFFF ]; |
|
653 |
while (veh != INVALID_VEHICLE) { |
|
654 |
v = &_vehicles[veh]; |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
655 |
|
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
656 |
if (!(v->vehstatus & VS_HIDDEN) && |
0 | 657 |
dpi->left <= v->right_coord && |
658 |
dpi->top <= v->bottom_coord && |
|
659 |
dpi->left + dpi->width >= v->left_coord && |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
660 |
dpi->top + dpi->height >= v->top_coord) { |
0 | 661 |
DoDrawVehicle(v); |
662 |
} |
|
663 |
veh = v->next_hash; |
|
664 |
} |
|
665 |
||
666 |
if (x == x2) |
|
667 |
break; |
|
668 |
x = (x + 1) & 0x3F; |
|
669 |
} |
|
670 |
x = xb; |
|
671 |
||
672 |
if (y == y2) |
|
673 |
break; |
|
674 |
y = (y + 0x40) & ((0x3F) << 6); |
|
675 |
} |
|
676 |
} |
|
677 |
||
678 |
static void EffectInit_0(Vehicle *v) |
|
679 |
{ |
|
680 |
uint32 r = Random(); |
|
681 |
v->cur_image = (uint16)((r & 7) + 3701); |
|
682 |
v->progress = (byte)((r >> 16)&7); |
|
683 |
} |
|
684 |
||
685 |
static void EffectTick_0(Vehicle *v) |
|
686 |
{ |
|
687 |
uint tile; |
|
688 |
uint img; |
|
689 |
||
690 |
if (--v->progress & 0x80) { |
|
691 |
BeginVehicleMove(v); |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
692 |
|
0 | 693 |
tile = TILE_FROM_XY(v->x_pos, v->y_pos); |
694 |
if (!IS_TILETYPE(tile, MP_INDUSTRY)) { |
|
695 |
EndVehicleMove(v); |
|
696 |
DeleteVehicle(v); |
|
697 |
return; |
|
698 |
} |
|
699 |
||
700 |
img = v->cur_image + 1; |
|
701 |
if (img > 3708) img = 3701; |
|
702 |
v->cur_image = img; |
|
703 |
v->progress = 7; |
|
704 |
VehiclePositionChanged(v); |
|
705 |
EndVehicleMove(v); |
|
706 |
} |
|
707 |
} |
|
708 |
||
709 |
static void EffectInit_1(Vehicle *v) |
|
710 |
{ |
|
711 |
v->cur_image = 3079; |
|
712 |
v->progress = 12; |
|
713 |
} |
|
714 |
||
715 |
static void EffectTick_1(Vehicle *v) |
|
716 |
{ |
|
717 |
bool moved; |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
718 |
|
0 | 719 |
BeginVehicleMove(v); |
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
720 |
|
0 | 721 |
moved = false; |
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
722 |
|
0 | 723 |
if ((++v->progress & 7) == 0) { |
724 |
v->z_pos++; |
|
725 |
moved = true; |
|
726 |
} |
|
727 |
||
728 |
if ((v->progress & 0xF)==4) { |
|
729 |
if (++v->cur_image > 3083) { |
|
730 |
EndVehicleMove(v); |
|
731 |
DeleteVehicle(v); |
|
732 |
return; |
|
733 |
} |
|
734 |
moved = true; |
|
735 |
} |
|
736 |
||
737 |
if (moved) { |
|
738 |
VehiclePositionChanged(v); |
|
739 |
EndVehicleMove(v); |
|
740 |
} |
|
741 |
} |
|
742 |
||
743 |
static void EffectInit_2(Vehicle *v) |
|
744 |
{ |
|
745 |
v->cur_image = 3073; |
|
746 |
v->progress = 0; |
|
747 |
} |
|
748 |
||
749 |
static void EffectTick_2(Vehicle *v) |
|
750 |
{ |
|
751 |
if ((++v->progress & 3) == 0) { |
|
752 |
BeginVehicleMove(v); |
|
753 |
v->z_pos++; |
|
754 |
VehiclePositionChanged(v); |
|
755 |
EndVehicleMove(v); |
|
756 |
} else if ((v->progress & 7) == 1) { |
|
757 |
BeginVehicleMove(v); |
|
758 |
if (++v->cur_image > 3078) { |
|
759 |
EndVehicleMove(v); |
|
760 |
DeleteVehicle(v); |
|
761 |
} else { |
|
762 |
VehiclePositionChanged(v); |
|
763 |
EndVehicleMove(v); |
|
764 |
} |
|
765 |
} |
|
766 |
} |
|
767 |
||
768 |
static void EffectInit_3(Vehicle *v) |
|
769 |
{ |
|
770 |
v->cur_image = 3084; |
|
771 |
v->progress = 1; |
|
772 |
} |
|
773 |
||
774 |
static void EffectTick_3(Vehicle *v) |
|
775 |
{ |
|
776 |
if (++v->progress > 2) { |
|
777 |
v->progress = 0; |
|
778 |
BeginVehicleMove(v); |
|
779 |
if (++v->cur_image > 3089) { |
|
780 |
EndVehicleMove(v); |
|
781 |
DeleteVehicle(v); |
|
782 |
} else { |
|
783 |
VehiclePositionChanged(v); |
|
784 |
EndVehicleMove(v); |
|
785 |
} |
|
786 |
} |
|
787 |
} |
|
788 |
||
789 |
static void EffectInit_4(Vehicle *v) |
|
790 |
{ |
|
791 |
v->cur_image = 2040; |
|
792 |
v->progress = 12; |
|
793 |
} |
|
794 |
||
795 |
static void EffectTick_4(Vehicle *v) |
|
796 |
{ |
|
797 |
bool moved; |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
798 |
|
0 | 799 |
BeginVehicleMove(v); |
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
800 |
|
0 | 801 |
moved = false; |
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
802 |
|
0 | 803 |
if ((++v->progress & 3) == 0) { |
804 |
v->z_pos++; |
|
805 |
moved = true; |
|
806 |
} |
|
807 |
||
808 |
if ((v->progress & 0xF)==4) { |
|
809 |
if (++v->cur_image > 2044) { |
|
810 |
EndVehicleMove(v); |
|
811 |
DeleteVehicle(v); |
|
812 |
return; |
|
813 |
} |
|
814 |
moved = true; |
|
815 |
} |
|
816 |
||
817 |
if (moved) { |
|
818 |
VehiclePositionChanged(v); |
|
819 |
EndVehicleMove(v); |
|
820 |
} |
|
821 |
} |
|
822 |
||
823 |
static void EffectInit_5(Vehicle *v) |
|
824 |
{ |
|
825 |
v->cur_image = 3709; |
|
826 |
v->progress = 0; |
|
827 |
} |
|
828 |
||
829 |
static void EffectTick_5(Vehicle *v) |
|
830 |
{ |
|
831 |
if (!(++v->progress & 3)) { |
|
832 |
BeginVehicleMove(v); |
|
833 |
if (++v->cur_image > 3724) { |
|
834 |
EndVehicleMove(v); |
|
835 |
DeleteVehicle(v); |
|
836 |
} else { |
|
837 |
VehiclePositionChanged(v); |
|
838 |
EndVehicleMove(v); |
|
839 |
} |
|
840 |
} |
|
841 |
} |
|
842 |
||
843 |
static void EffectInit_6(Vehicle *v) |
|
844 |
{ |
|
845 |
v->cur_image = 3737; |
|
846 |
v->progress = 0; |
|
847 |
} |
|
848 |
||
849 |
static void EffectTick_6(Vehicle *v) |
|
850 |
{ |
|
851 |
if (!(++v->progress & 7)) { |
|
852 |
BeginVehicleMove(v); |
|
853 |
if (++v->cur_image > 3740) v->cur_image = 3737; |
|
854 |
VehiclePositionChanged(v); |
|
855 |
EndVehicleMove(v); |
|
856 |
} |
|
857 |
||
858 |
if (!--v->u.special.unk0) { |
|
859 |
BeginVehicleMove(v); |
|
860 |
EndVehicleMove(v); |
|
861 |
DeleteVehicle(v); |
|
862 |
} |
|
863 |
} |
|
864 |
||
865 |
static void EffectInit_7(Vehicle *v) |
|
866 |
{ |
|
867 |
v->cur_image = 3725; |
|
868 |
v->progress = 0; |
|
869 |
} |
|
870 |
||
871 |
static void EffectTick_7(Vehicle *v) |
|
872 |
{ |
|
873 |
if (!(++v->progress & 3)) { |
|
874 |
BeginVehicleMove(v); |
|
875 |
if (++v->cur_image > 3736) { |
|
876 |
EndVehicleMove(v); |
|
877 |
DeleteVehicle(v); |
|
878 |
} else { |
|
879 |
VehiclePositionChanged(v); |
|
880 |
EndVehicleMove(v); |
|
881 |
} |
|
882 |
} |
|
883 |
} |
|
884 |
||
885 |
static void EffectInit_8(Vehicle *v) |
|
886 |
{ |
|
887 |
v->cur_image = 1416; |
|
888 |
v->progress = 0; |
|
889 |
v->u.special.unk0 = 0; |
|
890 |
v->u.special.unk2 = 0; |
|
891 |
} |
|
892 |
||
893 |
#define MK(imag,dir,dur) (imag<<6)+(dir<<4)+dur |
|
894 |
static const byte _effecttick8_data[] = { |
|
895 |
MK(0,0,4), |
|
896 |
MK(3,3,4), |
|
897 |
MK(2,2,7), |
|
898 |
MK(0,2,7), |
|
899 |
MK(1,1,3), |
|
900 |
MK(2,2,7), |
|
901 |
MK(0,2,7), |
|
902 |
MK(1,1,3), |
|
903 |
MK(2,2,7), |
|
904 |
MK(0,2,7), |
|
905 |
MK(3,3,6), |
|
906 |
MK(2,2,6), |
|
907 |
MK(1,1,7), |
|
908 |
MK(3,1,7), |
|
909 |
MK(0,0,3), |
|
910 |
MK(1,1,7), |
|
911 |
MK(3,1,7), |
|
912 |
MK(0,0,3), |
|
913 |
MK(1,1,7), |
|
914 |
MK(3,1,7), |
|
915 |
255 |
|
916 |
}; |
|
917 |
#undef MK |
|
918 |
||
919 |
static const int8 _xy_inc_by_dir[5] = { |
|
920 |
-1, 0, 1, 0, -1, |
|
921 |
}; |
|
922 |
||
923 |
#define GET_X_INC_BY_DIR(d) _xy_inc_by_dir[d] |
|
924 |
#define GET_Y_INC_BY_DIR(d) _xy_inc_by_dir[(d)+1] |
|
925 |
||
926 |
static void EffectTick_8(Vehicle *v) |
|
927 |
{ |
|
928 |
byte b; |
|
929 |
||
930 |
if (!(++v->progress & 7)) { |
|
931 |
v->u.special.unk2++; |
|
932 |
BeginVehicleMove(v); |
|
933 |
||
934 |
b = _effecttick8_data[v->u.special.unk0]; |
|
935 |
||
936 |
v->cur_image = 0x588 + (b>>6); |
|
937 |
||
938 |
v->x_pos += GET_X_INC_BY_DIR((b>>4)&3); |
|
939 |
v->y_pos += GET_X_INC_BY_DIR((b>>4)&3); |
|
940 |
||
941 |
if (v->u.special.unk2 < (b & 7)) { |
|
942 |
v->u.special.unk2 = 0; |
|
943 |
v->u.special.unk0++; |
|
944 |
if (_effecttick8_data[v->u.special.unk0] == 0xFF) { |
|
945 |
EndVehicleMove(v); |
|
946 |
DeleteVehicle(v); |
|
947 |
return; |
|
948 |
} |
|
949 |
} |
|
950 |
VehiclePositionChanged(v); |
|
951 |
EndVehicleMove(v); |
|
952 |
} |
|
953 |
} |
|
954 |
||
955 |
static void EffectInit_9(Vehicle *v) |
|
956 |
{ |
|
957 |
v->cur_image = 4751; |
|
958 |
v->spritenum = 0; |
|
959 |
v->progress = 0; |
|
960 |
} |
|
961 |
||
962 |
#define MK(x,y,z,i) (x+4)+(y+4)*16,(z+4)+i*16 |
|
963 |
||
964 |
/* -1,0,1,2 = 2*/ |
|
965 |
/* -1,0,1 = 2*/ |
|
966 |
/* */ |
|
967 |
static const byte _effecttick9_data1[] = { |
|
968 |
MK(0,0,1,0), |
|
969 |
MK(1,0,1,1), |
|
970 |
MK(0,0,1,0), |
|
971 |
MK(1,0,1,2), |
|
972 |
0x81, |
|
973 |
}; |
|
974 |
||
975 |
||
976 |
static const byte _effecttick9_data2[] = { |
|
977 |
MK(0,0,1,0), |
|
978 |
MK(-1,0,1,1), |
|
979 |
MK(0,0,1,0), |
|
980 |
MK(-1,0,1,2), |
|
981 |
0x81, |
|
982 |
}; |
|
983 |
||
984 |
static const byte _effecttick9_data3[] = { |
|
985 |
MK(0,0,1,0), |
|
986 |
MK(0,1,1,1), |
|
987 |
MK(0,0,1,0), |
|
988 |
MK(0,1,1,2), |
|
989 |
0x81, |
|
990 |
}; |
|
991 |
||
992 |
static const byte _effecttick9_data4[] = { |
|
993 |
MK(0,0,1,0), |
|
994 |
MK(0,-1,1,1), |
|
995 |
MK(0,0,1,0), |
|
996 |
MK(0,-1,1,2), |
|
997 |
0x81, |
|
998 |
}; |
|
999 |
||
1000 |
static const byte _effecttick9_data5[] = { |
|
1001 |
MK(0,0,1,2), |
|
1002 |
MK(0,0,1,7), |
|
1003 |
MK(0,0,1,8), |
|
1004 |
MK(0,0,1,9), |
|
1005 |
0x80, |
|
1006 |
}; |
|
1007 |
||
1008 |
static const byte _effecttick9_data6[] = { |
|
1009 |
MK(0,0,1,0), |
|
1010 |
MK(0,0,1,1), |
|
1011 |
MK(0,0,1,0), |
|
1012 |
MK(0,0,1,2), |
|
1013 |
MK(0,0,1,0), |
|
1014 |
MK(0,0,1,1), |
|
1015 |
MK(0,0,1,0), |
|
1016 |
MK(0,0,1,2), |
|
1017 |
MK(0,0,1,0), |
|
1018 |
MK(0,0,1,1), |
|
1019 |
MK(0,0,1,0), |
|
1020 |
MK(0,0,1,2), |
|
1021 |
MK(0,0,1,0), |
|
1022 |
MK(0,0,1,1), |
|
1023 |
MK(0,0,1,0), |
|
1024 |
MK(0,0,1,2), |
|
1025 |
MK(0,0,1,0), |
|
1026 |
MK(0,0,1,1), |
|
1027 |
MK(0,0,1,0), |
|
1028 |
MK(0,0,1,2), |
|
1029 |
MK(0,0,1,0), |
|
1030 |
MK(0,0,1,1), |
|
1031 |
MK(0,0,1,0), |
|
1032 |
MK(0,0,1,2), |
|
1033 |
MK(0,0,1,0), |
|
1034 |
MK(0,0,1,1), |
|
1035 |
MK(0,0,1,0), |
|
1036 |
MK(0,0,1,2), |
|
1037 |
MK(0,0,1,0), |
|
1038 |
MK(0,0,1,1), |
|
1039 |
MK(0,0,1,0), |
|
1040 |
MK(0,0,1,2), |
|
1041 |
MK(0,0,1,0), |
|
1042 |
MK(0,0,1,1), |
|
1043 |
MK(0,0,1,0), |
|
1044 |
MK(0,0,1,2), |
|
1045 |
MK(0,0,1,0), |
|
1046 |
MK(0,0,1,1), |
|
1047 |
MK(0,0,1,0), |
|
1048 |
MK(0,0,1,2), |
|
1049 |
MK(0,0,1,0), |
|
1050 |
MK(0,0,1,1), |
|
1051 |
MK(0,0,1,0), |
|
1052 |
MK(0,0,1,2), |
|
1053 |
MK(0,0,1,0), |
|
1054 |
MK(0,0,1,1), |
|
1055 |
MK(0,0,1,0), |
|
1056 |
MK(0,0,1,2), |
|
1057 |
MK(0,0,1,0), |
|
1058 |
MK(0,0,1,1), |
|
1059 |
MK(0,0,1,0), |
|
1060 |
MK(0,0,1,2), |
|
1061 |
MK(0,0,1,0), |
|
1062 |
MK(0,0,1,1), |
|
1063 |
MK(0,0,1,0), |
|
1064 |
MK(0,0,1,2), |
|
1065 |
MK(0,0,1,0), |
|
1066 |
MK(0,0,1,1), |
|
1067 |
MK(0,0,1,0), |
|
1068 |
MK(0,0,1,2), |
|
1069 |
MK(0,0,1,0), |
|
1070 |
MK(0,0,1,1), |
|
1071 |
MK(2,1,3,0), |
|
1072 |
MK(1,1,3,1), |
|
1073 |
MK(2,1,3,0), |
|
1074 |
MK(1,1,3,2), |
|
1075 |
MK(2,1,3,0), |
|
1076 |
MK(1,1,3,1), |
|
1077 |
MK(2,1,3,0), |
|
1078 |
MK(1,0,1,2), |
|
1079 |
MK(0,0,1,0), |
|
1080 |
MK(1,0,1,1), |
|
1081 |
MK(0,0,1,0), |
|
1082 |
MK(1,0,1,2), |
|
1083 |
MK(0,0,1,0), |
|
1084 |
MK(1,0,1,1), |
|
1085 |
MK(0,0,1,0), |
|
1086 |
MK(1,0,1,2), |
|
1087 |
0x82,0, |
|
1088 |
MK(0,0,0,0xA), |
|
1089 |
MK(0,0,0,0xB), |
|
1090 |
MK(0,0,0,0xC), |
|
1091 |
MK(0,0,0,0xD), |
|
1092 |
MK(0,0,0,0xE), |
|
1093 |
0x80 |
|
1094 |
}; |
|
1095 |
#undef MK |
|
1096 |
||
1097 |
static const byte * const _effecttick9_data[6] = { |
|
1098 |
_effecttick9_data1, |
|
1099 |
_effecttick9_data2, |
|
1100 |
_effecttick9_data3, |
|
1101 |
_effecttick9_data4, |
|
1102 |
_effecttick9_data5, |
|
1103 |
_effecttick9_data6, |
|
1104 |
}; |
|
1105 |
||
1106 |
static void EffectTick_9(Vehicle *v) |
|
1107 |
{ |
|
543
946badd71033
(svn r942) -Merged branch/network back into the trunk
truelight
parents:
541
diff
changeset
|
1108 |
/* |
946badd71033
(svn r942) -Merged branch/network back into the trunk
truelight
parents:
541
diff
changeset
|
1109 |
* Warning: those effects can NOT use Random(), and have to use |
946badd71033
(svn r942) -Merged branch/network back into the trunk
truelight
parents:
541
diff
changeset
|
1110 |
* InteractiveRandom(), because somehow someone forgot to save |
946badd71033
(svn r942) -Merged branch/network back into the trunk
truelight
parents:
541
diff
changeset
|
1111 |
* spritenum to the savegame, and so it will cause desyncs in |
946badd71033
(svn r942) -Merged branch/network back into the trunk
truelight
parents:
541
diff
changeset
|
1112 |
* multiplayer!! (that is: in ToyLand) |
946badd71033
(svn r942) -Merged branch/network back into the trunk
truelight
parents:
541
diff
changeset
|
1113 |
*/ |
0 | 1114 |
int et; |
1115 |
const byte *b; |
|
1116 |
||
1117 |
if (((++v->progress)&3) != 0) |
|
1118 |
return; |
|
1119 |
||
1120 |
BeginVehicleMove(v); |
|
1121 |
||
1122 |
et = v->engine_type + 1; |
|
1123 |
||
1124 |
if (v->spritenum == 0) { |
|
1125 |
if (++v->cur_image < 4754) { |
|
1126 |
VehiclePositionChanged(v); |
|
1127 |
EndVehicleMove(v); |
|
1128 |
return; |
|
1129 |
} |
|
1130 |
if (v->u.special.unk2 != 0) { |
|
543
946badd71033
(svn r942) -Merged branch/network back into the trunk
truelight
parents:
541
diff
changeset
|
1131 |
v->spritenum = (byte)((InteractiveRandom()&3)+1); |
0 | 1132 |
} else { |
1133 |
v->spritenum = 6; |
|
1134 |
} |
|
1135 |
et = 0; |
|
1136 |
} |
|
1137 |
||
1138 |
again: |
|
1139 |
v->engine_type = et; |
|
1140 |
b = &_effecttick9_data[v->spritenum - 1][et*2]; |
|
1141 |
||
1142 |
if (*b == 0x80) { |
|
1143 |
EndVehicleMove(v); |
|
1144 |
DeleteVehicle(v); |
|
1145 |
return; |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
1146 |
} |
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
1147 |
|
0 | 1148 |
if (*b == 0x81) { |
543
946badd71033
(svn r942) -Merged branch/network back into the trunk
truelight
parents:
541
diff
changeset
|
1149 |
if (v->z_pos > 180 || CHANCE16I(1,96, InteractiveRandom())) { |
0 | 1150 |
v->spritenum = 5; |
541 | 1151 |
SndPlayVehicleFx(SND_2F_POP, v); |
0 | 1152 |
} |
1153 |
et = 0; |
|
1154 |
goto again; |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
1155 |
} |
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
1156 |
|
0 | 1157 |
if (*b == 0x82) { |
1158 |
uint tile; |
|
1159 |
||
1160 |
et++; |
|
541 | 1161 |
SndPlayVehicleFx(SND_31_EXTRACT, v); |
0 | 1162 |
|
1163 |
tile = TILE_FROM_XY(v->x_pos, v->y_pos); |
|
1164 |
if (IS_TILETYPE(tile, MP_INDUSTRY) && |
|
1165 |
_map5[tile]==0xA2) { |
|
1166 |
AddAnimatedTile(tile); |
|
1167 |
} |
|
1168 |
goto again; |
|
1169 |
} |
|
1170 |
||
1171 |
v->x_pos += (b[0]&0xF) - 4; |
|
1172 |
v->y_pos += (b[0]>>4) - 4; |
|
1173 |
v->z_pos += (b[1]&0xF) - 4; |
|
1174 |
v->cur_image = 4748 + (b[1] >> 4); |
|
1175 |
||
1176 |
VehiclePositionChanged(v); |
|
1177 |
EndVehicleMove(v); |
|
1178 |
} |
|
1179 |
||
1180 |
||
1181 |
typedef void EffectInitProc(Vehicle *v); |
|
1182 |
typedef void EffectTickProc(Vehicle *v); |
|
1183 |
||
1184 |
static EffectInitProc * const _effect_init_procs[] = { |
|
1185 |
EffectInit_0, |
|
1186 |
EffectInit_1, |
|
1187 |
EffectInit_2, |
|
1188 |
EffectInit_3, |
|
1189 |
EffectInit_4, |
|
1190 |
EffectInit_5, |
|
1191 |
EffectInit_6, |
|
1192 |
EffectInit_7, |
|
1193 |
EffectInit_8, |
|
1194 |
EffectInit_9, |
|
1195 |
}; |
|
1196 |
||
1197 |
static EffectTickProc * const _effect_tick_procs[] = { |
|
1198 |
EffectTick_0, |
|
1199 |
EffectTick_1, |
|
1200 |
EffectTick_2, |
|
1201 |
EffectTick_3, |
|
1202 |
EffectTick_4, |
|
1203 |
EffectTick_5, |
|
1204 |
EffectTick_6, |
|
1205 |
EffectTick_7, |
|
1206 |
EffectTick_8, |
|
1207 |
EffectTick_9, |
|
1208 |
}; |
|
1209 |
||
1210 |
||
1211 |
Vehicle *CreateEffectVehicle(int x, int y, int z, int type) |
|
1212 |
{ |
|
1213 |
Vehicle *v; |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
1214 |
|
0 | 1215 |
v = ForceAllocateSpecialVehicle(); |
1216 |
if (v != NULL) { |
|
1217 |
v->type = VEH_Special; |
|
1218 |
v->subtype = type; |
|
1219 |
v->x_pos = x; |
|
1220 |
v->y_pos = y; |
|
1221 |
v->z_pos = z; |
|
1222 |
v->z_height = v->sprite_width = v->sprite_height = 1; |
|
1223 |
v->x_offs = v->y_offs = 0; |
|
1224 |
v->tile = 0; |
|
1225 |
v->vehstatus = VS_UNCLICKABLE; |
|
1226 |
||
1227 |
_effect_init_procs[type](v); |
|
1228 |
||
1229 |
VehiclePositionChanged(v); |
|
1230 |
BeginVehicleMove(v); |
|
1231 |
EndVehicleMove(v); |
|
1232 |
} |
|
1233 |
return v; |
|
1234 |
} |
|
1235 |
||
1236 |
Vehicle *CreateEffectVehicleAbove(int x, int y, int z, int type) |
|
1237 |
{ |
|
1238 |
return CreateEffectVehicle(x, y, GetSlopeZ(x, y) + z, type); |
|
1239 |
} |
|
1240 |
||
1241 |
Vehicle *CreateEffectVehicleRel(Vehicle *v, int x, int y, int z, int type) |
|
1242 |
{ |
|
1243 |
return CreateEffectVehicle(v->x_pos + x, v->y_pos + y, v->z_pos + z, type); |
|
1244 |
} |
|
1245 |
||
410 | 1246 |
static void EffectVehicle_Tick(Vehicle *v) |
0 | 1247 |
{ |
1248 |
_effect_tick_procs[v->subtype](v); |
|
1249 |
} |
|
1250 |
||
1251 |
Vehicle *CheckClickOnVehicle(ViewPort *vp, int x, int y) |
|
1252 |
{ |
|
1253 |
Vehicle *found = NULL, *v; |
|
1254 |
uint dist, best_dist = (uint)-1; |
|
1255 |
||
1256 |
if ( (uint)(x -= vp->left) >= (uint)vp->width || |
|
1257 |
(uint)(y -= vp->top) >= (uint)vp->height) |
|
1258 |
return NULL; |
|
1259 |
||
1260 |
x = (x << vp->zoom) + vp->virtual_left; |
|
1261 |
y = (y << vp->zoom) + vp->virtual_top; |
|
1262 |
||
1263 |
FOR_ALL_VEHICLES(v) { |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
1264 |
if (v->type != 0 && (v->vehstatus & (VS_HIDDEN|VS_UNCLICKABLE)) == 0 && |
0 | 1265 |
x >= v->left_coord && x <= v->right_coord && |
1266 |
y >= v->top_coord && y <= v->bottom_coord) { |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
1267 |
|
0 | 1268 |
dist = max( |
1269 |
myabs( ((v->left_coord + v->right_coord)>>1) - x ), |
|
1270 |
myabs( ((v->top_coord + v->bottom_coord)>>1) - y ) |
|
1271 |
); |
|
1272 |
||
1273 |
if (dist < best_dist) { |
|
1274 |
found = v; |
|
1275 |
best_dist = dist; |
|
1276 |
} |
|
1277 |
} |
|
1278 |
} |
|
1279 |
||
1280 |
return found; |
|
1281 |
} |
|
1282 |
||
1283 |
||
1284 |
void DecreaseVehicleValue(Vehicle *v) |
|
1285 |
{ |
|
1286 |
v->value -= v->value >> 8; |
|
1287 |
InvalidateWindow(WC_VEHICLE_DETAILS, v->index); |
|
1288 |
} |
|
1289 |
||
1290 |
static const byte _breakdown_chance[64] = { |
|
1291 |
3, 3, 3, 3, 3, 3, 3, 3, |
|
1292 |
4, 4, 5, 5, 6, 6, 7, 7, |
|
1293 |
8, 8, 9, 9, 10, 10, 11, 11, |
|
1294 |
12, 13, 13, 13, 13, 14, 15, 16, |
|
1295 |
17, 19, 21, 25, 28, 31, 34, 37, |
|
1296 |
40, 44, 48, 52, 56, 60, 64, 68, |
|
1297 |
72, 80, 90, 100, 110, 120, 130, 140, |
|
1298 |
150, 170, 190, 210, 230, 250, 250, 250, |
|
1299 |
}; |
|
1300 |
||
1301 |
void CheckVehicleBreakdown(Vehicle *v) |
|
1302 |
{ |
|
1303 |
int rel, rel_old; |
|
1304 |
uint32 r; |
|
1305 |
int chance; |
|
1306 |
||
1307 |
/* decrease reliability */ |
|
1308 |
v->reliability = rel = max((rel_old = v->reliability) - v->reliability_spd_dec, 0); |
|
1309 |
if ((rel_old >> 8) != (rel >> 8)) |
|
1310 |
InvalidateWindow(WC_VEHICLE_DETAILS, v->index); |
|
1311 |
||
1312 |
if (v->breakdown_ctr != 0 || (v->vehstatus & VS_STOPPED) != 0 || |
|
1313 |
v->cur_speed < 5 || _game_mode == GM_MENU) |
|
1314 |
return; |
|
1315 |
||
1316 |
r = Random(); |
|
1317 |
||
1318 |
/* increase chance of failure */ |
|
1319 |
chance = v->breakdown_chance + 1; |
|
1320 |
if (CHANCE16I(1,25,r)) chance += 25; |
|
1321 |
v->breakdown_chance = min(255, chance); |
|
1322 |
||
1323 |
/* calculate reliability value to use in comparison */ |
|
1324 |
rel = v->reliability; |
|
1325 |
if (v->type == VEH_Ship) rel += 0x6666; |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
1326 |
|
0 | 1327 |
/* disabled breakdowns? */ |
1328 |
if (_opt.diff.vehicle_breakdowns < 1) |
|
1329 |
return; |
|
1330 |
||
1331 |
/* reduced breakdowns? */ |
|
1332 |
if (_opt.diff.vehicle_breakdowns == 1) rel += 0x6666; |
|
1333 |
||
1334 |
/* check if to break down */ |
|
1335 |
if (_breakdown_chance[(uint)min(rel, 0xffff) >> 10] <= v->breakdown_chance) { |
|
1336 |
v->breakdown_ctr = (byte)(((r >> 16) & 0x3F) + 0x3F); |
|
1337 |
v->breakdown_delay = (byte)(((r >> 24) & 0x7F) | 0x80); |
|
1338 |
v->breakdown_chance = 0; |
|
1339 |
} |
|
1340 |
} |
|
1341 |
||
1342 |
static const StringID _vehicle_type_names[4] = { |
|
1343 |
STR_019F_TRAIN, |
|
1344 |
STR_019C_ROAD_VEHICLE, |
|
1345 |
STR_019E_SHIP, |
|
1346 |
STR_019D_AIRCRAFT, |
|
1347 |
}; |
|
1348 |
||
1349 |
static void ShowVehicleGettingOld(Vehicle *v, StringID msg) |
|
1350 |
{ |
|
1351 |
if (v->owner != _local_player) |
|
1352 |
return; |
|
26 | 1353 |
// Do not show getting-old message if autorenew is active |
1354 |
if (_patches.autorenew) |
|
1355 |
return; |
|
0 | 1356 |
|
534
306bc86eb23e
(svn r901) Small step in the process to clean up the DPARAM mess:
tron
parents:
507
diff
changeset
|
1357 |
SetDParam(0, _vehicle_type_names[v->type - 0x10]); |
306bc86eb23e
(svn r901) Small step in the process to clean up the DPARAM mess:
tron
parents:
507
diff
changeset
|
1358 |
SetDParam(1, v->unitnumber); |
0 | 1359 |
AddNewsItem(msg, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0); |
1360 |
} |
|
1361 |
||
1362 |
void AgeVehicle(Vehicle *v) |
|
1363 |
{ |
|
1364 |
int age; |
|
1365 |
||
1366 |
if (v->age < 65535) |
|
1367 |
v->age++; |
|
1368 |
||
1369 |
age = v->age - v->max_age; |
|
1370 |
if (age == 366*0 || age == 366*1 || age == 366*2 || age == 366*3 || age == 366*4) |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
1371 |
v->reliability_spd_dec <<= 1; |
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
1372 |
|
0 | 1373 |
InvalidateWindow(WC_VEHICLE_DETAILS, v->index); |
1374 |
||
1375 |
if (age == -366) { |
|
1376 |
ShowVehicleGettingOld(v, STR_01A0_IS_GETTING_OLD); |
|
1377 |
} else if (age == 0) { |
|
1378 |
ShowVehicleGettingOld(v, STR_01A1_IS_GETTING_VERY_OLD); |
|
1379 |
} else if (age == 366*1 || age == 366*2 || age == 366*3 || age == 366*4 || age == 366*5) { |
|
1380 |
ShowVehicleGettingOld(v, STR_01A2_IS_GETTING_VERY_OLD_AND); |
|
1381 |
} |
|
1382 |
} |
|
1383 |
||
1384 |
void MaybeRenewVehicle(Vehicle *v, int32 build_cost) |
|
1385 |
{ |
|
1386 |
Engine *e; |
|
1387 |
||
26 | 1388 |
// A vehicle is autorenewed when it it gets the amount of months |
1389 |
// give by _patches.autorenew_months away for his max age. |
|
1390 |
// Standard is -6, meaning 6 months before his max age |
|
1391 |
// It can be any value between -12 and 12. |
|
1392 |
if (!_patches.autorenew || v->age - v->max_age < (_patches.autorenew_months * 30)) |
|
0 | 1393 |
return; |
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
1394 |
|
26 | 1395 |
if (DEREF_PLAYER(v->owner)->money64 < _patches.autorenew_money + build_cost - v->value) { |
1396 |
if (v->owner == _local_player) { |
|
1397 |
int message; |
|
534
306bc86eb23e
(svn r901) Small step in the process to clean up the DPARAM mess:
tron
parents:
507
diff
changeset
|
1398 |
SetDParam(0, v->unitnumber); |
26 | 1399 |
switch (v->type) { |
1400 |
case VEH_Train: message = STR_TRAIN_AUTORENEW_FAILED; break; |
|
1401 |
case VEH_Road: message = STR_ROADVEHICLE_AUTORENEW_FAILED; break; |
|
1402 |
case VEH_Ship: message = STR_SHIP_AUTORENEW_FAILED; break; |
|
1403 |
case VEH_Aircraft: message = STR_AIRCRAFT_AUTORENEW_FAILED; break; |
|
1404 |
// This should never happen |
|
1405 |
default: message = 0; break; |
|
1406 |
} |
|
1407 |
||
1408 |
AddNewsItem(message, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0); |
|
1409 |
} |
|
1410 |
return; |
|
1411 |
} |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
1412 |
|
26 | 1413 |
// Withdraw the money from the right player ;) |
1414 |
_current_player = v->owner; |
|
0 | 1415 |
|
1416 |
e = &_engines[v->engine_type]; |
|
1417 |
v->reliability = e->reliability; |
|
1418 |
v->reliability_spd_dec = e->reliability_spd_dec; |
|
1419 |
v->age = 0; |
|
1420 |
||
1421 |
v->date_of_last_service = _date; |
|
1422 |
v->build_year = _cur_year; |
|
1423 |
||
1424 |
SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES); |
|
1425 |
SubtractMoneyFromPlayer(build_cost - v->value); |
|
1426 |
v->value = build_cost; |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
1427 |
|
0 | 1428 |
InvalidateWindow(WC_VEHICLE_DETAILS, v->index); |
260
4819bcce8389
(svn r266) -Fix: hopefully fixed the desync problem nicely (and reverted the
truelight
parents:
193
diff
changeset
|
1429 |
|
4819bcce8389
(svn r266) -Fix: hopefully fixed the desync problem nicely (and reverted the
truelight
parents:
193
diff
changeset
|
1430 |
_current_player = OWNER_NONE; |
0 | 1431 |
} |
1432 |
||
1433 |
||
1434 |
int32 CmdNameVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2) |
|
1435 |
{ |
|
1436 |
Vehicle *v; |
|
1437 |
StringID str; |
|
1438 |
||
1439 |
v = &_vehicles[p1]; |
|
1440 |
||
1441 |
if (!CheckOwnership(v->owner)) |
|
1442 |
return CMD_ERROR; |
|
1443 |
||
543
946badd71033
(svn r942) -Merged branch/network back into the trunk
truelight
parents:
541
diff
changeset
|
1444 |
str = AllocateNameUnique((byte*)_decode_parameters, 2); |
0 | 1445 |
if (str == 0) |
1446 |
return CMD_ERROR; |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
1447 |
|
0 | 1448 |
if (flags & DC_EXEC) { |
1449 |
StringID old_str = v->string_id; |
|
1450 |
v->string_id = str; |
|
1451 |
DeleteName(old_str); |
|
164
0cbdf3c9bde1
(svn r165) -Feature: Option to sort vehicles in vehicle-list window by different criteria. Total independent sort for all types and players. Periodic resort of list every 10 TTD days. Thank you for your graphical inspiration follow and buxo (since none of you provided any code).
darkvater
parents:
26
diff
changeset
|
1452 |
_train_sort_dirty[v->owner] = true; |
0cbdf3c9bde1
(svn r165) -Feature: Option to sort vehicles in vehicle-list window by different criteria. Total independent sort for all types and players. Periodic resort of list every 10 TTD days. Thank you for your graphical inspiration follow and buxo (since none of you provided any code).
darkvater
parents:
26
diff
changeset
|
1453 |
_aircraft_sort_dirty[v->owner] = true; |
0cbdf3c9bde1
(svn r165) -Feature: Option to sort vehicles in vehicle-list window by different criteria. Total independent sort for all types and players. Periodic resort of list every 10 TTD days. Thank you for your graphical inspiration follow and buxo (since none of you provided any code).
darkvater
parents:
26
diff
changeset
|
1454 |
_ship_sort_dirty[v->owner] = true; |
0cbdf3c9bde1
(svn r165) -Feature: Option to sort vehicles in vehicle-list window by different criteria. Total independent sort for all types and players. Periodic resort of list every 10 TTD days. Thank you for your graphical inspiration follow and buxo (since none of you provided any code).
darkvater
parents:
26
diff
changeset
|
1455 |
_road_sort_dirty[v->owner] = true; |
0 | 1456 |
MarkWholeScreenDirty(); |
1457 |
} else { |
|
1458 |
DeleteName(str); |
|
1459 |
} |
|
1460 |
||
1461 |
return 0; |
|
1462 |
} |
|
1463 |
||
1464 |
||
1465 |
||
1466 |
static Rect _old_vehicle_coords; |
|
1467 |
||
1468 |
void BeginVehicleMove(Vehicle *v) { |
|
1469 |
_old_vehicle_coords.left = v->left_coord; |
|
1470 |
_old_vehicle_coords.top = v->top_coord; |
|
1471 |
_old_vehicle_coords.right = v->right_coord; |
|
1472 |
_old_vehicle_coords.bottom = v->bottom_coord; |
|
1473 |
} |
|
1474 |
||
1475 |
void EndVehicleMove(Vehicle *v) |
|
1476 |
{ |
|
1477 |
MarkAllViewportsDirty( |
|
1478 |
min(_old_vehicle_coords.left,v->left_coord), |
|
1479 |
min(_old_vehicle_coords.top,v->top_coord), |
|
1480 |
max(_old_vehicle_coords.right,v->right_coord)+1, |
|
1481 |
max(_old_vehicle_coords.bottom,v->bottom_coord)+1 |
|
1482 |
); |
|
1483 |
} |
|
1484 |
||
1485 |
void InvalidateVehicleOrderWidget(Vehicle *v) |
|
1486 |
{ |
|
1487 |
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4); |
|
1488 |
InvalidateWindowWidget(WC_VEHICLE_ORDERS, v->index, 2); |
|
1489 |
} |
|
1490 |
||
1491 |
/* returns true if staying in the same tile */ |
|
1492 |
bool GetNewVehiclePos(Vehicle *v, GetNewVehiclePosResult *gp) |
|
1493 |
{ |
|
1494 |
static const int8 _delta_coord[16] = { |
|
1495 |
-1,-1,-1, 0, 1, 1, 1, 0, /* x */ |
|
1496 |
-1, 0, 1, 1, 1, 0,-1,-1, /* y */ |
|
1497 |
}; |
|
1498 |
||
1499 |
int x = v->x_pos + _delta_coord[v->direction]; |
|
1500 |
int y = v->y_pos + _delta_coord[v->direction + 8]; |
|
1501 |
||
1502 |
gp->x = x; |
|
1503 |
gp->y = y; |
|
1504 |
gp->old_tile = v->tile; |
|
1505 |
gp->new_tile = TILE_FROM_XY(x,y); |
|
1506 |
return gp->old_tile == gp->new_tile; |
|
1507 |
} |
|
1508 |
||
1509 |
static const byte _new_direction_table[9] = { |
|
1510 |
0, 7, 6, |
|
1511 |
1, 3, 5, |
|
1512 |
2, 3, 4, |
|
1513 |
}; |
|
1514 |
||
1515 |
byte GetDirectionTowards(Vehicle *v, int x, int y) |
|
1516 |
{ |
|
1517 |
byte dirdiff, dir; |
|
1518 |
int i = 0; |
|
1519 |
||
1520 |
if (y >= v->y_pos) { |
|
1521 |
if (y != v->y_pos) i+=3; |
|
1522 |
i+=3; |
|
1523 |
} |
|
1524 |
||
1525 |
if (x >= v->x_pos) { |
|
1526 |
if (x != v->x_pos) i++; |
|
1527 |
i++; |
|
1528 |
} |
|
1529 |
||
1530 |
dir = v->direction; |
|
1531 |
||
1532 |
dirdiff = _new_direction_table[i] - dir; |
|
1533 |
if (dirdiff == 0) |
|
1534 |
return dir; |
|
1535 |
return (dir+((dirdiff&7)<5?1:-1)) & 7; |
|
1536 |
} |
|
1537 |
||
22 | 1538 |
/* Return value has bit 0x2 set, when the vehicle enters a station. Then, |
1539 |
* result << 8 contains the id of the station entered. If the return value has |
|
1540 |
* bit 0x8 set, the vehicle could not and did not enter the tile. Are there |
|
1541 |
* other bits that can be set? */ |
|
0 | 1542 |
uint32 VehicleEnterTile(Vehicle *v, uint tile, int x, int y) |
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
1543 |
{ |
0 | 1544 |
uint old_tile = v->tile; |
1545 |
uint32 result = _tile_type_procs[GET_TILETYPE(tile)]->vehicle_enter_tile_proc(v, tile, x, y); |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
1546 |
|
22 | 1547 |
/* When vehicle_enter_tile_proc returns 8, that apparently means that |
1548 |
* we cannot enter the tile at all. In that case, don't call |
|
1549 |
* leave_tile. */ |
|
0 | 1550 |
if (!(result & 8) && old_tile != tile) { |
1551 |
VehicleLeaveTileProc *proc = _tile_type_procs[GET_TILETYPE(old_tile)]->vehicle_leave_tile_proc; |
|
1552 |
if (proc != NULL) |
|
1553 |
proc(v, old_tile, x, y); |
|
1554 |
} |
|
1555 |
return result; |
|
1556 |
} |
|
1557 |
||
1558 |
uint GetFreeUnitNumber(byte type) |
|
1559 |
{ |
|
1560 |
uint unit_num = 0; |
|
1561 |
Vehicle *u; |
|
1562 |
||
1563 |
restart: |
|
1564 |
unit_num++; |
|
1565 |
FOR_ALL_VEHICLES(u) { |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
1566 |
if (u->type == type && u->owner == _current_player && |
0 | 1567 |
unit_num == u->unitnumber) |
1568 |
goto restart; |
|
1569 |
} |
|
1570 |
return unit_num; |
|
1571 |
} |
|
1572 |
||
1573 |
||
1574 |
// Save and load of vehicles |
|
1575 |
const byte _common_veh_desc[] = { |
|
1576 |
SLE_VAR(Vehicle,subtype, SLE_UINT8), |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
1577 |
|
0 | 1578 |
SLE_VAR(Vehicle,next_in_chain_old, SLE_UINT16), |
1579 |
SLE_VAR(Vehicle,string_id, SLE_STRINGID), |
|
1580 |
SLE_VAR(Vehicle,unitnumber, SLE_UINT8), |
|
1581 |
SLE_VAR(Vehicle,owner, SLE_UINT8), |
|
1582 |
SLE_VAR(Vehicle,tile, SLE_UINT16), |
|
1583 |
SLE_VAR(Vehicle,dest_tile, SLE_UINT16), |
|
1584 |
||
1585 |
SLE_VAR(Vehicle,x_pos, SLE_INT16), |
|
1586 |
SLE_VAR(Vehicle,y_pos, SLE_INT16), |
|
1587 |
SLE_VAR(Vehicle,z_pos, SLE_UINT8), |
|
1588 |
SLE_VAR(Vehicle,direction, SLE_UINT8), |
|
1589 |
||
1590 |
SLE_VAR(Vehicle,cur_image, SLE_UINT16), |
|
1591 |
SLE_VAR(Vehicle,spritenum, SLE_UINT8), |
|
1592 |
SLE_VAR(Vehicle,sprite_width, SLE_UINT8), |
|
1593 |
SLE_VAR(Vehicle,sprite_height, SLE_UINT8), |
|
1594 |
SLE_VAR(Vehicle,z_height, SLE_UINT8), |
|
1595 |
SLE_VAR(Vehicle,x_offs, SLE_INT8), |
|
1596 |
SLE_VAR(Vehicle,y_offs, SLE_INT8), |
|
1597 |
SLE_VAR(Vehicle,engine_type, SLE_UINT16), |
|
445
beafc0fb8f12
(svn r654) Hopefully complete support for randomized variational spritegroups (i.e. the cars transporter in DBSetXL gets different cars each time) (pasky)
tron
parents:
410
diff
changeset
|
1598 |
|
0 | 1599 |
SLE_VAR(Vehicle,max_speed, SLE_UINT16), |
1600 |
SLE_VAR(Vehicle,cur_speed, SLE_UINT16), |
|
1601 |
SLE_VAR(Vehicle,subspeed, SLE_UINT8), |
|
1602 |
SLE_VAR(Vehicle,acceleration, SLE_UINT8), |
|
1603 |
SLE_VAR(Vehicle,progress, SLE_UINT8), |
|
1604 |
||
1605 |
SLE_VAR(Vehicle,vehstatus, SLE_UINT8), |
|
1606 |
SLE_VAR(Vehicle,last_station_visited,SLE_UINT8), |
|
1607 |
||
1608 |
SLE_VAR(Vehicle,cargo_type, SLE_UINT8), |
|
1609 |
SLE_VAR(Vehicle,cargo_days, SLE_UINT8), |
|
1610 |
SLE_VAR(Vehicle,cargo_source, SLE_UINT8), |
|
1611 |
SLE_VAR(Vehicle,cargo_cap, SLE_UINT16), |
|
1612 |
SLE_VAR(Vehicle,cargo_count, SLE_UINT16), |
|
1613 |
||
1614 |
SLE_VAR(Vehicle,day_counter, SLE_UINT8), |
|
1615 |
SLE_VAR(Vehicle,tick_counter, SLE_UINT8), |
|
1616 |
||
1617 |
SLE_VAR(Vehicle,cur_order_index, SLE_UINT8), |
|
1618 |
SLE_VAR(Vehicle,num_orders, SLE_UINT8), |
|
555
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
1619 |
SLE_VAR(Vehicle,current_order, SLE_UINT8), /* XXX hack to avoid version bump */ |
556
59308f21c27e
(svn r957) -Fix: vehicle.c compiler problems for MSVC6 only! (Tron)
darkvater
parents:
555
diff
changeset
|
1620 |
#if _MSC_VER != 1200 |
555
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
1621 |
SLE_VAR(Vehicle,current_order.station, SLE_UINT8), |
556
59308f21c27e
(svn r957) -Fix: vehicle.c compiler problems for MSVC6 only! (Tron)
darkvater
parents:
555
diff
changeset
|
1622 |
#else /* XXX workaround for MSVC6 */ |
59308f21c27e
(svn r957) -Fix: vehicle.c compiler problems for MSVC6 only! (Tron)
darkvater
parents:
555
diff
changeset
|
1623 |
SLE_VAR2(Vehicle, current_order, Order, station, SLE_UINT8), |
59308f21c27e
(svn r957) -Fix: vehicle.c compiler problems for MSVC6 only! (Tron)
darkvater
parents:
555
diff
changeset
|
1624 |
#endif |
0 | 1625 |
SLE_REF(Vehicle,schedule_ptr, REF_SCHEDULE), |
1626 |
||
1627 |
SLE_VAR(Vehicle,age, SLE_UINT16), |
|
1628 |
SLE_VAR(Vehicle,max_age, SLE_UINT16), |
|
1629 |
SLE_VAR(Vehicle,date_of_last_service,SLE_UINT16), |
|
1630 |
SLE_VAR(Vehicle,service_interval, SLE_UINT16), |
|
1631 |
SLE_VAR(Vehicle,reliability, SLE_UINT16), |
|
1632 |
SLE_VAR(Vehicle,reliability_spd_dec,SLE_UINT16), |
|
1633 |
SLE_VAR(Vehicle,breakdown_ctr, SLE_UINT8), |
|
1634 |
SLE_VAR(Vehicle,breakdown_delay, SLE_UINT8), |
|
1635 |
SLE_VAR(Vehicle,breakdowns_since_last_service, SLE_UINT8), |
|
1636 |
SLE_VAR(Vehicle,breakdown_chance, SLE_UINT8), |
|
1637 |
SLE_VAR(Vehicle,build_year, SLE_UINT8), |
|
1638 |
||
1639 |
SLE_VAR(Vehicle,load_unload_time_rem, SLE_UINT16), |
|
1640 |
||
1641 |
SLE_VAR(Vehicle,profit_this_year, SLE_INT32), |
|
1642 |
SLE_VAR(Vehicle,profit_last_year, SLE_INT32), |
|
1643 |
SLE_VAR(Vehicle,value, SLE_UINT32), |
|
1644 |
||
445
beafc0fb8f12
(svn r654) Hopefully complete support for randomized variational spritegroups (i.e. the cars transporter in DBSetXL gets different cars each time) (pasky)
tron
parents:
410
diff
changeset
|
1645 |
SLE_VAR(Vehicle,random_bits, SLE_UINT8), |
beafc0fb8f12
(svn r654) Hopefully complete support for randomized variational spritegroups (i.e. the cars transporter in DBSetXL gets different cars each time) (pasky)
tron
parents:
410
diff
changeset
|
1646 |
SLE_VAR(Vehicle,waiting_triggers, SLE_UINT8), |
beafc0fb8f12
(svn r654) Hopefully complete support for randomized variational spritegroups (i.e. the cars transporter in DBSetXL gets different cars each time) (pasky)
tron
parents:
410
diff
changeset
|
1647 |
|
beafc0fb8f12
(svn r654) Hopefully complete support for randomized variational spritegroups (i.e. the cars transporter in DBSetXL gets different cars each time) (pasky)
tron
parents:
410
diff
changeset
|
1648 |
// reserve extra space in savegame here. (currently 14 bytes) |
beafc0fb8f12
(svn r654) Hopefully complete support for randomized variational spritegroups (i.e. the cars transporter in DBSetXL gets different cars each time) (pasky)
tron
parents:
410
diff
changeset
|
1649 |
SLE_CONDARR(NullStruct,null,SLE_FILE_U8 | SLE_VAR_NULL, 2, 2, 255), /* 2 */ |
beafc0fb8f12
(svn r654) Hopefully complete support for randomized variational spritegroups (i.e. the cars transporter in DBSetXL gets different cars each time) (pasky)
tron
parents:
410
diff
changeset
|
1650 |
SLE_CONDARR(NullStruct,null,SLE_FILE_U16 | SLE_VAR_NULL, 2, 2, 255), /* 4 */ |
beafc0fb8f12
(svn r654) Hopefully complete support for randomized variational spritegroups (i.e. the cars transporter in DBSetXL gets different cars each time) (pasky)
tron
parents:
410
diff
changeset
|
1651 |
SLE_CONDARR(NullStruct,null,SLE_FILE_U32 | SLE_VAR_NULL, 2, 2, 255), /* 8 */ |
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
1652 |
|
0 | 1653 |
SLE_END() |
1654 |
}; |
|
1655 |
||
1656 |
||
1657 |
static const byte _train_desc[] = { |
|
1658 |
SLE_WRITEBYTE(Vehicle,type,VEH_Train, 0), // Train type. VEH_Train in mem, 0 in file. |
|
1659 |
SLE_INCLUDEX(0, INC_VEHICLE_COMMON), |
|
1660 |
SLE_VARX(offsetof(Vehicle,u)+offsetof(VehicleRail,crash_anim_pos), SLE_UINT16), |
|
1661 |
SLE_VARX(offsetof(Vehicle,u)+offsetof(VehicleRail,force_proceed), SLE_UINT8), |
|
1662 |
SLE_VARX(offsetof(Vehicle,u)+offsetof(VehicleRail,railtype), SLE_UINT8), |
|
1663 |
SLE_VARX(offsetof(Vehicle,u)+offsetof(VehicleRail,track), SLE_UINT8), |
|
1664 |
||
1665 |
SLE_CONDVARX(offsetof(Vehicle,u)+offsetof(VehicleRail,flags), SLE_UINT8, 2, 255), |
|
1666 |
SLE_CONDVARX(offsetof(Vehicle,u)+offsetof(VehicleRail,days_since_order_progr), SLE_UINT16, 2, 255), |
|
1667 |
||
1668 |
// reserve extra space in savegame here. (currently 13 bytes) |
|
1669 |
SLE_CONDARR(NullStruct,null,SLE_FILE_U8 | SLE_VAR_NULL, 13, 2, 255), |
|
1670 |
||
1671 |
SLE_END() |
|
1672 |
}; |
|
1673 |
||
1674 |
static const byte _roadveh_desc[] = { |
|
1675 |
SLE_WRITEBYTE(Vehicle,type,VEH_Road, 1), // Road type. VEH_Road in mem, 1 in file. |
|
1676 |
SLE_INCLUDEX(0, INC_VEHICLE_COMMON), |
|
1677 |
SLE_VARX(offsetof(Vehicle,u)+offsetof(VehicleRoad,state), SLE_UINT8), |
|
1678 |
SLE_VARX(offsetof(Vehicle,u)+offsetof(VehicleRoad,frame), SLE_UINT8), |
|
1679 |
SLE_VARX(offsetof(Vehicle,u)+offsetof(VehicleRoad,unk2), SLE_UINT16), |
|
1680 |
SLE_VARX(offsetof(Vehicle,u)+offsetof(VehicleRoad,overtaking), SLE_UINT8), |
|
1681 |
SLE_VARX(offsetof(Vehicle,u)+offsetof(VehicleRoad,overtaking_ctr),SLE_UINT8), |
|
1682 |
SLE_VARX(offsetof(Vehicle,u)+offsetof(VehicleRoad,crashed_ctr), SLE_UINT16), |
|
1683 |
SLE_VARX(offsetof(Vehicle,u)+offsetof(VehicleRoad,reverse_ctr), SLE_UINT8), |
|
1684 |
||
1685 |
// reserve extra space in savegame here. (currently 16 bytes) |
|
1686 |
SLE_CONDARR(NullStruct,null,SLE_FILE_U64 | SLE_VAR_NULL, 2, 2, 255), |
|
1687 |
||
1688 |
SLE_END() |
|
1689 |
}; |
|
1690 |
||
1691 |
static const byte _ship_desc[] = { |
|
1692 |
SLE_WRITEBYTE(Vehicle,type,VEH_Ship, 2), // Ship type. VEH_Ship in mem, 2 in file. |
|
1693 |
SLE_INCLUDEX(0, INC_VEHICLE_COMMON), |
|
1694 |
SLE_VARX(offsetof(Vehicle,u)+offsetof(VehicleShip,state), SLE_UINT8), |
|
1695 |
||
1696 |
// reserve extra space in savegame here. (currently 16 bytes) |
|
1697 |
SLE_CONDARR(NullStruct,null,SLE_FILE_U64 | SLE_VAR_NULL, 2, 2, 255), |
|
1698 |
||
1699 |
SLE_END() |
|
1700 |
}; |
|
1701 |
||
1702 |
static const byte _aircraft_desc[] = { |
|
1703 |
SLE_WRITEBYTE(Vehicle,type,VEH_Aircraft, 3), // Aircraft type. VEH_Aircraft in mem, 3 in file. |
|
1704 |
SLE_INCLUDEX(0, INC_VEHICLE_COMMON), |
|
1705 |
SLE_VARX(offsetof(Vehicle,u)+offsetof(VehicleAir,crashed_counter), SLE_UINT16), |
|
1706 |
SLE_VARX(offsetof(Vehicle,u)+offsetof(VehicleAir,pos), SLE_UINT8), |
|
1707 |
SLE_VARX(offsetof(Vehicle,u)+offsetof(VehicleAir,targetairport), SLE_UINT8), |
|
1708 |
SLE_VARX(offsetof(Vehicle,u)+offsetof(VehicleAir,state), SLE_UINT8), |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
1709 |
|
0 | 1710 |
SLE_CONDVARX(offsetof(Vehicle,u)+offsetof(VehicleAir,previous_pos), SLE_UINT8, 2, 255), |
1711 |
||
1712 |
// reserve extra space in savegame here. (currently 15 bytes) |
|
1713 |
SLE_CONDARR(NullStruct,null,SLE_FILE_U8 | SLE_VAR_NULL, 15, 2, 255), |
|
1714 |
||
1715 |
SLE_END() |
|
1716 |
}; |
|
1717 |
||
1718 |
static const byte _special_desc[] = { |
|
1719 |
SLE_WRITEBYTE(Vehicle,type,VEH_Special, 4), |
|
1720 |
||
1721 |
SLE_VAR(Vehicle,subtype, SLE_UINT8), |
|
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
1722 |
|
0 | 1723 |
SLE_VAR(Vehicle,tile, SLE_UINT16), |
1724 |
||
1725 |
SLE_VAR(Vehicle,x_pos, SLE_INT16), |
|
1726 |
SLE_VAR(Vehicle,y_pos, SLE_INT16), |
|
1727 |
SLE_VAR(Vehicle,z_pos, SLE_UINT8), |
|
1728 |
||
1729 |
SLE_VAR(Vehicle,cur_image, SLE_UINT16), |
|
1730 |
SLE_VAR(Vehicle,sprite_width, SLE_UINT8), |
|
1731 |
SLE_VAR(Vehicle,sprite_height, SLE_UINT8), |
|
1732 |
SLE_VAR(Vehicle,z_height, SLE_UINT8), |
|
1733 |
SLE_VAR(Vehicle,x_offs, SLE_INT8), |
|
1734 |
SLE_VAR(Vehicle,y_offs, SLE_INT8), |
|
1735 |
SLE_VAR(Vehicle,progress, SLE_UINT8), |
|
1736 |
SLE_VAR(Vehicle,vehstatus, SLE_UINT8), |
|
1737 |
||
1738 |
SLE_VARX(offsetof(Vehicle,u)+offsetof(VehicleSpecial,unk0), SLE_UINT16), |
|
1739 |
SLE_VARX(offsetof(Vehicle,u)+offsetof(VehicleSpecial,unk2), SLE_UINT8), |
|
1740 |
||
1741 |
// reserve extra space in savegame here. (currently 16 bytes) |
|
1742 |
SLE_CONDARR(NullStruct,null,SLE_FILE_U64 | SLE_VAR_NULL, 2, 2, 255), |
|
1743 |
||
1744 |
SLE_END() |
|
1745 |
}; |
|
1746 |
||
1747 |
static const byte _disaster_desc[] = { |
|
1748 |
SLE_WRITEBYTE(Vehicle,type,VEH_Disaster, 5), |
|
1749 |
||
1750 |
SLE_VAR(Vehicle,next_in_chain_old,SLE_UINT16), |
|
1751 |
||
1752 |
SLE_VAR(Vehicle,subtype, SLE_UINT8), |
|
1753 |
SLE_VAR(Vehicle,tile, SLE_UINT16), |
|
1754 |
SLE_VAR(Vehicle,dest_tile, SLE_UINT16), |
|
1755 |
||
1756 |
SLE_VAR(Vehicle,x_pos, SLE_INT16), |
|
1757 |
SLE_VAR(Vehicle,y_pos, SLE_INT16), |
|
1758 |
SLE_VAR(Vehicle,z_pos, SLE_UINT8), |
|
1759 |
SLE_VAR(Vehicle,direction, SLE_UINT8), |
|
1760 |
||
1761 |
SLE_VAR(Vehicle,x_offs, SLE_INT8), |
|
1762 |
SLE_VAR(Vehicle,y_offs, SLE_INT8), |
|
1763 |
SLE_VAR(Vehicle,sprite_width, SLE_UINT8), |
|
1764 |
SLE_VAR(Vehicle,sprite_height, SLE_UINT8), |
|
1765 |
SLE_VAR(Vehicle,z_height, SLE_UINT8), |
|
1766 |
SLE_VAR(Vehicle,owner, SLE_UINT8), |
|
1767 |
SLE_VAR(Vehicle,vehstatus, SLE_UINT8), |
|
556
59308f21c27e
(svn r957) -Fix: vehicle.c compiler problems for MSVC6 only! (Tron)
darkvater
parents:
555
diff
changeset
|
1768 |
#if _MSC_VER != 1200 |
555
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
1769 |
SLE_VAR(Vehicle,current_order.station, SLE_UINT8), |
556
59308f21c27e
(svn r957) -Fix: vehicle.c compiler problems for MSVC6 only! (Tron)
darkvater
parents:
555
diff
changeset
|
1770 |
#else /* XXX workaround for MSVC6 */ |
59308f21c27e
(svn r957) -Fix: vehicle.c compiler problems for MSVC6 only! (Tron)
darkvater
parents:
555
diff
changeset
|
1771 |
SLE_VAR2(Vehicle, current_order, Order, station, SLE_UINT8), |
59308f21c27e
(svn r957) -Fix: vehicle.c compiler problems for MSVC6 only! (Tron)
darkvater
parents:
555
diff
changeset
|
1772 |
#endif |
0 | 1773 |
|
1774 |
SLE_VAR(Vehicle,cur_image, SLE_UINT16), |
|
1775 |
SLE_VAR(Vehicle,age, SLE_UINT16), |
|
1776 |
||
1777 |
SLE_VAR(Vehicle,tick_counter, SLE_UINT8), |
|
1778 |
||
1779 |
SLE_VARX(offsetof(Vehicle,u)+offsetof(VehicleDisaster,image_override), SLE_UINT16), |
|
1780 |
SLE_VARX(offsetof(Vehicle,u)+offsetof(VehicleDisaster,unk2), SLE_UINT16), |
|
1781 |
||
1782 |
// reserve extra space in savegame here. (currently 16 bytes) |
|
1783 |
SLE_CONDARR(NullStruct,null,SLE_FILE_U64 | SLE_VAR_NULL, 2, 2, 255), |
|
1784 |
||
1785 |
SLE_END() |
|
1786 |
}; |
|
1787 |
||
1788 |
||
1789 |
static const void *_veh_descs[] = { |
|
1790 |
_train_desc, |
|
1791 |
_roadveh_desc, |
|
1792 |
_ship_desc, |
|
1793 |
_aircraft_desc, |
|
1794 |
_special_desc, |
|
1795 |
_disaster_desc, |
|
1796 |
}; |
|
1797 |
||
1798 |
// Will be called when the vehicles need to be saved. |
|
1799 |
static void Save_VEHS() |
|
1800 |
{ |
|
1801 |
Vehicle *v; |
|
1802 |
// Write the vehicles |
|
1803 |
FOR_ALL_VEHICLES(v) { |
|
1804 |
if (v->type != 0) { |
|
1805 |
SlSetArrayIndex(v->index); |
|
1806 |
v->next_in_chain_old = v->next ? v->next->index : INVALID_VEHICLE; |
|
1807 |
SlObject(v, _veh_descs[v->type - 0x10]); |
|
1808 |
} |
|
1809 |
} |
|
1810 |
} |
|
1811 |
||
1812 |
// Will be called when vehicles need to be loaded. |
|
1813 |
static void Load_VEHS() |
|
1814 |
{ |
|
1815 |
int index; |
|
1816 |
Vehicle *v; |
|
1817 |
||
1818 |
while ((index = SlIterateArray()) != -1) { |
|
1819 |
Vehicle *v = &_vehicles[index]; |
|
1820 |
v->next_in_chain_old = INVALID_VEHICLE; |
|
1821 |
SlObject(v, _veh_descs[SlReadByte()]); |
|
1822 |
v->next = v->next_in_chain_old == INVALID_VEHICLE ? NULL : &_vehicles[v->next_in_chain_old]; |
|
1823 |
if (v->type == VEH_Train) |
|
1824 |
v->u.rail.first_engine = 0xffff; |
|
1825 |
} |
|
1826 |
||
1827 |
// Iterate through trains and set first_engine appropriately. |
|
1828 |
FOR_ALL_VEHICLES(v) { |
|
1829 |
Vehicle *w; |
|
1830 |
||
1831 |
if (v->type != VEH_Train || v->subtype != 0) |
|
1832 |
continue; |
|
1833 |
||
1834 |
for (w = v->next; w; w = w->next) |
|
1835 |
w->u.rail.first_engine = v->engine_type; |
|
1836 |
} |
|
1837 |
} |
|
1838 |
||
1839 |
static const byte _depot_desc[] = { |
|
1840 |
SLE_VAR(Depot,xy, SLE_UINT16), |
|
1841 |
SLE_VAR(Depot,town_index, SLE_UINT16), |
|
1842 |
SLE_END() |
|
1843 |
}; |
|
1844 |
||
1845 |
static void Save_DEPT() |
|
1846 |
{ |
|
1847 |
Depot *d; |
|
1848 |
int i; |
|
1849 |
for(i=0,d=_depots; i!=lengthof(_depots); i++,d++) { |
|
1850 |
if (d->xy != 0) { |
|
1851 |
SlSetArrayIndex(i); |
|
1852 |
SlObject(d, _depot_desc); |
|
1853 |
} |
|
1854 |
} |
|
1855 |
} |
|
1856 |
||
1857 |
static void Load_DEPT() |
|
1858 |
{ |
|
1859 |
int index; |
|
1860 |
while ((index = SlIterateArray()) != -1) { |
|
1861 |
SlObject(&_depots[index], _depot_desc); |
|
1862 |
} |
|
1863 |
} |
|
1864 |
||
395
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
1865 |
static const byte _waypoint_desc[] = { |
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
1866 |
SLE_VAR(Waypoint,xy, SLE_UINT16), |
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
1867 |
SLE_VAR(Waypoint,town_or_string, SLE_UINT16), |
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
1868 |
SLE_VAR(Waypoint,deleted, SLE_UINT8), |
0 | 1869 |
|
395
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
1870 |
SLE_CONDVAR(Waypoint, build_date, SLE_UINT16, 3, 255), |
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
1871 |
SLE_CONDVAR(Waypoint, stat_id, SLE_UINT8, 3, 255), |
0 | 1872 |
|
1873 |
SLE_END() |
|
1874 |
}; |
|
1875 |
||
1876 |
static void Save_CHKP() |
|
1877 |
{ |
|
395
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
1878 |
Waypoint *cp; |
0 | 1879 |
int i; |
395
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
1880 |
for(i=0,cp=_waypoints; i!=lengthof(_waypoints); i++,cp++) { |
0 | 1881 |
if (cp->xy != 0) { |
1882 |
SlSetArrayIndex(i); |
|
395
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
1883 |
SlObject(cp, _waypoint_desc); |
0 | 1884 |
} |
1885 |
} |
|
1886 |
} |
|
1887 |
||
1888 |
static void Load_CHKP() |
|
1889 |
{ |
|
1890 |
int index; |
|
1891 |
while ((index = SlIterateArray()) != -1) { |
|
395
788a9bba0889
(svn r587) -newgrf: Rename all /Checkpoint/i tokens to 'Waypoint's. The name actually makes some sense and is also compatible with TTDPatch (pasky).
darkvater
parents:
337
diff
changeset
|
1892 |
SlObject(&_waypoints[index], _waypoint_desc); |
0 | 1893 |
} |
1894 |
} |
|
1895 |
||
1896 |
||
1897 |
static void Save_ORDR() |
|
1898 |
{ |
|
555
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
1899 |
uint16 orders[lengthof(_order_array)]; |
0 | 1900 |
uint len = _ptr_to_next_order - _order_array; |
555
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
1901 |
uint i; |
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
1902 |
|
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
1903 |
assert (len <= lengthof(orders)); |
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
1904 |
|
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
1905 |
for (i = 0; i < len; ++i) |
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
1906 |
orders[i] = PackOrder(&_order_array[i]); |
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
1907 |
|
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
1908 |
SlArray(orders, len, SLE_UINT16); |
0 | 1909 |
} |
1910 |
||
1911 |
static void Load_ORDR() |
|
1912 |
{ |
|
555
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
1913 |
uint16 orders[lengthof(_order_array)]; |
0 | 1914 |
uint len = SlGetFieldLength() >> 1; |
555
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
1915 |
uint i; |
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
1916 |
|
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
1917 |
assert (len <= lengthof(orders)); |
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
1918 |
|
0 | 1919 |
_ptr_to_next_order = _order_array + len; |
555
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
1920 |
SlArray(orders, len, SLE_UINT16); |
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
1921 |
|
02df8a1b7f33
(svn r955) Replace uint16 for orders with struct Order
tron
parents:
548
diff
changeset
|
1922 |
for (i = 0; i < len; ++i) |
577 | 1923 |
_order_array[i] = UnpackOldOrder(orders[i]); |
0 | 1924 |
} |
1925 |
||
1926 |
const ChunkHandler _veh_chunk_handlers[] = { |
|
1927 |
{ 'VEHS', Save_VEHS, Load_VEHS, CH_SPARSE_ARRAY}, |
|
1928 |
{ 'ORDR', Save_ORDR, Load_ORDR, CH_RIFF}, |
|
1929 |
{ 'DEPT', Save_DEPT, Load_DEPT, CH_ARRAY}, |
|
1930 |
{ 'CHKP', Save_CHKP, Load_CHKP, CH_ARRAY | CH_LAST}, |
|
1931 |
}; |
|
1932 |
||
1933 |