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