77 v->sprite_height = 2; |
77 v->sprite_height = 2; |
78 v->z_height = 5; |
78 v->z_height = 5; |
79 v->owner = OWNER_NONE; |
79 v->owner = OWNER_NONE; |
80 v->vehstatus = VS_UNCLICKABLE; |
80 v->vehstatus = VS_UNCLICKABLE; |
81 v->u.disaster.image_override = 0; |
81 v->u.disaster.image_override = 0; |
82 v->next_order = 0; |
82 v->current_order.type = OT_NOTHING; |
|
83 v->current_order.flags = 0; |
|
84 v->current_order.station = 0; |
83 |
85 |
84 DisasterVehicleUpdateImage(v); |
86 DisasterVehicleUpdateImage(v); |
85 VehiclePositionChanged(v); |
87 VehiclePositionChanged(v); |
86 BeginVehicleMove(v); |
88 BeginVehicleMove(v); |
87 EndVehicleMove(v); |
89 EndVehicleMove(v); |
139 byte z; |
141 byte z; |
140 uint tile; |
142 uint tile; |
141 |
143 |
142 ++v->tick_counter; |
144 ++v->tick_counter; |
143 |
145 |
144 if (v->next_order < 2) { |
146 if (v->current_order.station < 2) { |
145 if (v->tick_counter&1) |
147 if (v->tick_counter&1) |
146 return; |
148 return; |
147 |
149 |
148 GetNewVehiclePos(v, &gp); |
150 GetNewVehiclePos(v, &gp); |
149 |
151 |
150 SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos); |
152 SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos); |
151 |
153 |
152 if (v->next_order == 1) { |
154 if (v->current_order.station == 1) { |
153 if (++v->age == 38) { |
155 if (++v->age == 38) { |
154 v->next_order = 2; |
156 v->current_order.station = 2; |
155 v->age = 0; |
157 v->age = 0; |
156 } |
158 } |
157 |
159 |
158 if ((v->tick_counter&7)==0) { |
160 if ((v->tick_counter&7)==0) { |
159 CreateEffectVehicleRel(v, 0, -17, 2, EV_SMOKE_3); |
161 CreateEffectVehicleRel(v, 0, -17, 2, EV_SMOKE_3); |
160 } |
162 } |
161 } else if (v->next_order == 0) { |
163 } else if (v->current_order.station == 0) { |
162 tile = v->tile; /**/ |
164 tile = v->tile; /**/ |
163 |
165 |
164 if (IS_TILETYPE(tile, MP_STATION) && |
166 if (IS_TILETYPE(tile, MP_STATION) && |
165 IS_BYTE_INSIDE(_map5[tile], 8, 0x43) && |
167 IS_BYTE_INSIDE(_map5[tile], 8, 0x43) && |
166 IS_HUMAN_PLAYER(_map_owner[tile])) { |
168 IS_HUMAN_PLAYER(_map_owner[tile])) { |
167 |
169 |
168 v->next_order = 1; |
170 v->current_order.station = 1; |
169 v->age = 0; |
171 v->age = 0; |
170 |
172 |
171 SetDParam(0, _map2[tile]); |
173 SetDParam(0, _map2[tile]); |
172 AddNewsItem(STR_B000_ZEPPELIN_DISASTER_AT, |
174 AddNewsItem(STR_B000_ZEPPELIN_DISASTER_AT, |
173 NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0), |
175 NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0), |
246 uint dist; |
248 uint dist; |
247 byte z; |
249 byte z; |
248 |
250 |
249 v->u.disaster.image_override = (++v->tick_counter & 8) ? 0xF45 : 0xF44; |
251 v->u.disaster.image_override = (++v->tick_counter & 8) ? 0xF45 : 0xF44; |
250 |
252 |
251 if (v->next_order == 0) { |
253 if (v->current_order.station == 0) { |
252 // fly around randomly |
254 // fly around randomly |
253 int x = GET_TILE_X(v->dest_tile)*16; |
255 int x = GET_TILE_X(v->dest_tile)*16; |
254 int y = GET_TILE_Y(v->dest_tile)*16; |
256 int y = GET_TILE_Y(v->dest_tile)*16; |
255 if (abs(x - v->x_pos) + abs(y - v->y_pos) >= 16) { |
257 if (abs(x - v->x_pos) + abs(y - v->y_pos) >= 16) { |
256 v->direction = GetDirectionTowards(v, x, y); |
258 v->direction = GetDirectionTowards(v, x, y); |
334 static void DisasterTick_2(Vehicle *v) |
336 static void DisasterTick_2(Vehicle *v) |
335 { |
337 { |
336 GetNewVehiclePosResult gp; |
338 GetNewVehiclePosResult gp; |
337 |
339 |
338 v->tick_counter++; |
340 v->tick_counter++; |
339 v->u.disaster.image_override = (v->next_order == 1 && v->tick_counter&4) ? 0xF4F : 0; |
341 v->u.disaster.image_override = |
|
342 (v->current_order.station == 1 && v->tick_counter&4) ? 0xF4F : 0; |
340 |
343 |
341 GetNewVehiclePos(v, &gp); |
344 GetNewVehiclePos(v, &gp); |
342 SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos); |
345 SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos); |
343 |
346 |
344 if (gp.x < -160) { |
347 if (gp.x < -160) { |
345 DeleteDisasterVeh(v); |
348 DeleteDisasterVeh(v); |
346 return; |
349 return; |
347 } |
350 } |
348 |
351 |
349 if (v->next_order == 2) { |
352 if (v->current_order.station == 2) { |
350 if (!(v->tick_counter&3)) { |
353 if (!(v->tick_counter&3)) { |
351 Industry *i = DEREF_INDUSTRY(v->dest_tile); |
354 Industry *i = DEREF_INDUSTRY(v->dest_tile); |
352 int x = GET_TILE_X(i->xy)*16; |
355 int x = GET_TILE_X(i->xy)*16; |
353 int y = GET_TILE_Y(i->xy)*16; |
356 int y = GET_TILE_Y(i->xy)*16; |
354 uint32 r = Random(); |
357 uint32 r = Random(); |
358 y + (r >> 6 & 0x3F), |
361 y + (r >> 6 & 0x3F), |
359 (r >> 12 & 0xF), |
362 (r >> 12 & 0xF), |
360 EV_DEMOLISH); |
363 EV_DEMOLISH); |
361 |
364 |
362 if (++v->age >= 55) |
365 if (++v->age >= 55) |
363 v->next_order = 3; |
366 v->current_order.station = 3; |
364 } |
367 } |
365 } else if (v->next_order == 1) { |
368 } else if (v->current_order.station == 1) { |
366 if (++v->age == 112) { |
369 if (++v->age == 112) { |
367 Industry *i; |
370 Industry *i; |
368 |
371 |
369 v->next_order = 2; |
372 v->current_order.station = 2; |
370 v->age = 0; |
373 v->age = 0; |
371 |
374 |
372 i = DEREF_INDUSTRY(v->dest_tile); |
375 i = DEREF_INDUSTRY(v->dest_tile); |
373 DestructIndustry(i); |
376 DestructIndustry(i); |
374 |
377 |
375 SetDParam(0, i->town->index); |
378 SetDParam(0, i->town->index); |
376 AddNewsItem(STR_B002_OIL_REFINERY_EXPLOSION, NEWS_FLAGS(NM_THIN,NF_VIEWPORT|NF_TILE,NT_ACCIDENT,0), i->xy, 0); |
379 AddNewsItem(STR_B002_OIL_REFINERY_EXPLOSION, NEWS_FLAGS(NM_THIN,NF_VIEWPORT|NF_TILE,NT_ACCIDENT,0), i->xy, 0); |
377 SndPlayTileFx(SND_12_EXPLOSION, i->xy); |
380 SndPlayTileFx(SND_12_EXPLOSION, i->xy); |
378 } |
381 } |
379 } else if (v->next_order == 0) { |
382 } else if (v->current_order.station == 0) { |
380 int x,y; |
383 int x,y; |
381 uint tile; |
384 uint tile; |
382 int ind; |
385 int ind; |
383 |
386 |
384 x = v->x_pos - 15*16; |
387 x = v->x_pos - 15*16; |
404 static void DisasterTick_3(Vehicle *v) |
407 static void DisasterTick_3(Vehicle *v) |
405 { |
408 { |
406 GetNewVehiclePosResult gp; |
409 GetNewVehiclePosResult gp; |
407 |
410 |
408 v->tick_counter++; |
411 v->tick_counter++; |
409 v->u.disaster.image_override = (v->next_order == 1 && v->tick_counter&4) ? 0xF53 : 0; |
412 v->u.disaster.image_override = |
|
413 (v->current_order.station == 1 && v->tick_counter&4) ? 0xF53 : 0; |
410 |
414 |
411 GetNewVehiclePos(v, &gp); |
415 GetNewVehiclePos(v, &gp); |
412 SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos); |
416 SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos); |
413 |
417 |
414 if (gp.x > TILES_X * 16 + 9*16 - 1) { |
418 if (gp.x > TILES_X * 16 + 9*16 - 1) { |
415 DeleteDisasterVeh(v); |
419 DeleteDisasterVeh(v); |
416 return; |
420 return; |
417 } |
421 } |
418 |
422 |
419 if (v->next_order == 2) { |
423 if (v->current_order.station == 2) { |
420 if (!(v->tick_counter&3)) { |
424 if (!(v->tick_counter&3)) { |
421 Industry *i = DEREF_INDUSTRY(v->dest_tile); |
425 Industry *i = DEREF_INDUSTRY(v->dest_tile); |
422 int x = GET_TILE_X(i->xy)*16; |
426 int x = GET_TILE_X(i->xy)*16; |
423 int y = GET_TILE_Y(i->xy)*16; |
427 int y = GET_TILE_Y(i->xy)*16; |
424 uint32 r = Random(); |
428 uint32 r = Random(); |
428 y + (r >> 6 & 0x3F), |
432 y + (r >> 6 & 0x3F), |
429 (r >> 12 & 0xF), |
433 (r >> 12 & 0xF), |
430 EV_DEMOLISH); |
434 EV_DEMOLISH); |
431 |
435 |
432 if (++v->age >= 55) |
436 if (++v->age >= 55) |
433 v->next_order = 3; |
437 v->current_order.station = 3; |
434 } |
438 } |
435 } else if (v->next_order == 1) { |
439 } else if (v->current_order.station == 1) { |
436 if (++v->age == 112) { |
440 if (++v->age == 112) { |
437 Industry *i; |
441 Industry *i; |
438 |
442 |
439 v->next_order = 2; |
443 v->current_order.station = 2; |
440 v->age = 0; |
444 v->age = 0; |
441 |
445 |
442 i = DEREF_INDUSTRY(v->dest_tile); |
446 i = DEREF_INDUSTRY(v->dest_tile); |
443 DestructIndustry(i); |
447 DestructIndustry(i); |
444 |
448 |
445 SetDParam(0, i->town->index); |
449 SetDParam(0, i->town->index); |
446 AddNewsItem(STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS, NEWS_FLAGS(NM_THIN,NF_VIEWPORT|NF_TILE,NT_ACCIDENT,0), i->xy, 0); |
450 AddNewsItem(STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS, NEWS_FLAGS(NM_THIN,NF_VIEWPORT|NF_TILE,NT_ACCIDENT,0), i->xy, 0); |
447 SndPlayTileFx(SND_12_EXPLOSION, i->xy); |
451 SndPlayTileFx(SND_12_EXPLOSION, i->xy); |
448 } |
452 } |
449 } else if (v->next_order == 0) { |
453 } else if (v->current_order.station == 0) { |
450 int x,y; |
454 int x,y; |
451 uint tile; |
455 uint tile; |
452 int ind; |
456 int ind; |
453 |
457 |
454 x = v->x_pos - 15*16; |
458 x = v->x_pos - 15*16; |
494 Town *t; |
498 Town *t; |
495 uint tile,tile_org; |
499 uint tile,tile_org; |
496 |
500 |
497 v->tick_counter++; |
501 v->tick_counter++; |
498 |
502 |
499 if (v->next_order == 1) { |
503 if (v->current_order.station == 1) { |
500 int x = GET_TILE_X(v->dest_tile)*16 + 8; |
504 int x = GET_TILE_X(v->dest_tile)*16 + 8; |
501 int y = GET_TILE_Y(v->dest_tile)*16 + 8; |
505 int y = GET_TILE_Y(v->dest_tile)*16 + 8; |
502 if (abs(v->x_pos - x) + abs(v->y_pos - y) >= 8) { |
506 if (abs(v->x_pos - x) + abs(v->y_pos - y) >= 8) { |
503 v->direction = GetDirectionTowards(v, x, y); |
507 v->direction = GetDirectionTowards(v, x, y); |
504 |
508 |
511 if (z < v->z_pos) { |
515 if (z < v->z_pos) { |
512 SetDisasterVehiclePos(v, v->x_pos, v->y_pos, v->z_pos - 1); |
516 SetDisasterVehiclePos(v, v->x_pos, v->y_pos, v->z_pos - 1); |
513 return; |
517 return; |
514 } |
518 } |
515 |
519 |
516 v->next_order = 2; |
520 v->current_order.station = 2; |
517 |
521 |
518 FOR_ALL_VEHICLES(u) { |
522 FOR_ALL_VEHICLES(u) { |
519 if (u->type == VEH_Train || u->type == VEH_Road) { |
523 if (u->type == VEH_Train || u->type == VEH_Road) { |
520 if (abs(u->x_pos - v->x_pos) + abs(u->y_pos - v->y_pos) <= 12*16) { |
524 if (abs(u->x_pos - v->x_pos) + abs(u->y_pos - v->y_pos) <= 12*16) { |
521 u->breakdown_ctr = 5; |
525 u->breakdown_ctr = 5; |
545 return; |
549 return; |
546 |
550 |
547 u->next = w; |
551 u->next = w; |
548 InitializeDisasterVehicle(w, -6*16, v->y_pos, 0, 5, 12); |
552 InitializeDisasterVehicle(w, -6*16, v->y_pos, 0, 5, 12); |
549 w->vehstatus |= VS_DISASTER; |
553 w->vehstatus |= VS_DISASTER; |
550 } else if (v->next_order < 1) { |
554 } else if (v->current_order.station < 1) { |
551 |
555 |
552 int x = GET_TILE_X(v->dest_tile)*16; |
556 int x = GET_TILE_X(v->dest_tile)*16; |
553 int y = GET_TILE_Y(v->dest_tile)*16; |
557 int y = GET_TILE_Y(v->dest_tile)*16; |
554 if (abs(x - v->x_pos) + abs(y - v->y_pos) >= 16) { |
558 if (abs(x - v->x_pos) + abs(y - v->y_pos) >= 16) { |
555 v->direction = GetDirectionTowards(v, x, y); |
559 v->direction = GetDirectionTowards(v, x, y); |
560 |
564 |
561 if (++v->age < 6) { |
565 if (++v->age < 6) { |
562 v->dest_tile = TILE_MASK(Random()); |
566 v->dest_tile = TILE_MASK(Random()); |
563 return; |
567 return; |
564 } |
568 } |
565 v->next_order = 1; |
569 v->current_order.station = 1; |
566 |
570 |
567 tile_org = tile = TILE_MASK(Random()); |
571 tile_org = tile = TILE_MASK(Random()); |
568 do { |
572 do { |
569 if (IS_TILETYPE(tile, MP_RAILWAY) && |
573 if (IS_TILETYPE(tile, MP_RAILWAY) && |
570 (_map5[tile]&~3)!=0xC0 && IS_HUMAN_PLAYER(_map_owner[tile])) |
574 (_map5[tile]&~3)!=0xC0 && IS_HUMAN_PLAYER(_map_owner[tile])) |
592 if (gp.x > TILES_X * 16 + 9*16 - 1) { |
596 if (gp.x > TILES_X * 16 + 9*16 - 1) { |
593 DeleteDisasterVeh(v); |
597 DeleteDisasterVeh(v); |
594 return; |
598 return; |
595 } |
599 } |
596 |
600 |
597 if (v->next_order == 0) { |
601 if (v->current_order.station == 0) { |
598 u = &_vehicles[v->u.disaster.unk2]; |
602 u = &_vehicles[v->u.disaster.unk2]; |
599 if (abs(v->x_pos - u->x_pos) > 16) |
603 if (abs(v->x_pos - u->x_pos) > 16) |
600 return; |
604 return; |
601 v->next_order = 1; |
605 v->current_order.station = 1; |
602 |
606 |
603 CreateEffectVehicleRel(u, 0, 7, 8, EV_CRASHED_SMOKE); |
607 CreateEffectVehicleRel(u, 0, 7, 8, EV_CRASHED_SMOKE); |
604 SndPlayVehicleFx(SND_12_EXPLOSION, u); |
608 SndPlayVehicleFx(SND_12_EXPLOSION, u); |
605 |
609 |
606 DeleteDisasterVeh(u); |
610 DeleteDisasterVeh(u); |