21 #include "date.h" |
21 #include "date.h" |
22 #include "table/engines.h" |
22 #include "table/engines.h" |
23 #include "group.h" |
23 #include "group.h" |
24 #include "string.h" |
24 #include "string.h" |
25 #include "strings.h" |
25 #include "strings.h" |
|
26 #include "misc/autoptr.hpp" |
26 |
27 |
27 EngineInfo _engine_info[TOTAL_NUM_ENGINES]; |
28 EngineInfo _engine_info[TOTAL_NUM_ENGINES]; |
28 RailVehicleInfo _rail_vehicle_info[NUM_TRAIN_ENGINES]; |
29 RailVehicleInfo _rail_vehicle_info[NUM_TRAIN_ENGINES]; |
29 ShipVehicleInfo _ship_vehicle_info[NUM_SHIP_ENGINES]; |
30 ShipVehicleInfo _ship_vehicle_info[NUM_SHIP_ENGINES]; |
30 AircraftVehicleInfo _aircraft_vehicle_info[NUM_AIRCRAFT_ENGINES]; |
31 AircraftVehicleInfo _aircraft_vehicle_info[NUM_AIRCRAFT_ENGINES]; |
477 |
478 |
478 /************************************************************************ |
479 /************************************************************************ |
479 * Engine Replacement stuff |
480 * Engine Replacement stuff |
480 ************************************************************************/ |
481 ************************************************************************/ |
481 |
482 |
482 static void EngineRenewPoolNewBlock(uint start_item); |
483 DEFINE_OLD_POOL_GENERIC(EngineRenew, EngineRenew) |
483 |
|
484 DEFINE_OLD_POOL(EngineRenew, EngineRenew, EngineRenewPoolNewBlock, NULL) |
|
485 |
|
486 static void EngineRenewPoolNewBlock(uint start_item) |
|
487 { |
|
488 EngineRenew *er; |
|
489 |
|
490 /* We don't use FOR_ALL here, because FOR_ALL skips invalid items. |
|
491 * TODO - This is just a temporary stage, this will be removed. */ |
|
492 for (er = GetEngineRenew(start_item); er != NULL; er = (er->index + 1U < GetEngineRenewPoolSize()) ? GetEngineRenew(er->index + 1U) : NULL) { |
|
493 er->index = start_item++; |
|
494 er->from = INVALID_ENGINE; |
|
495 } |
|
496 } |
|
497 |
|
498 |
|
499 static EngineRenew *AllocateEngineRenew() |
|
500 { |
|
501 EngineRenew *er; |
|
502 |
|
503 /* We don't use FOR_ALL here, because FOR_ALL skips invalid items. |
|
504 * TODO - This is just a temporary stage, this will be removed. */ |
|
505 for (er = GetEngineRenew(0); er != NULL; er = (er->index + 1U < GetEngineRenewPoolSize()) ? GetEngineRenew(er->index + 1U) : NULL) { |
|
506 if (IsValidEngineRenew(er)) continue; |
|
507 |
|
508 er->to = INVALID_ENGINE; |
|
509 er->next = NULL; |
|
510 er->group_id = ALL_GROUP; |
|
511 return er; |
|
512 } |
|
513 |
|
514 /* Check if we can add a block to the pool */ |
|
515 if (AddBlockToPool(&_EngineRenew_pool)) return AllocateEngineRenew(); |
|
516 |
|
517 return NULL; |
|
518 } |
|
519 |
484 |
520 /** |
485 /** |
521 * Retrieves the EngineRenew that specifies the replacement of the given |
486 * Retrieves the EngineRenew that specifies the replacement of the given |
522 * engine type from the given renewlist */ |
487 * engine type from the given renewlist */ |
523 static EngineRenew *GetEngineReplacement(EngineRenewList erl, EngineID engine, GroupID group) |
488 static EngineRenew *GetEngineReplacement(EngineRenewList erl, EngineID engine, GroupID group) |
559 if (er != NULL) { |
524 if (er != NULL) { |
560 if (flags & DC_EXEC) er->to = new_engine; |
525 if (flags & DC_EXEC) er->to = new_engine; |
561 return CommandCost(); |
526 return CommandCost(); |
562 } |
527 } |
563 |
528 |
564 er = AllocateEngineRenew(); |
529 er = new EngineRenew(old_engine, new_engine); |
565 if (er == NULL) return CMD_ERROR; |
530 if (er == NULL) return CMD_ERROR; |
|
531 AutoPtrT<EngineRenew> er_auto_delete = er; |
|
532 |
566 |
533 |
567 if (flags & DC_EXEC) { |
534 if (flags & DC_EXEC) { |
568 er->from = old_engine; |
|
569 er->to = new_engine; |
|
570 er->group_id = group; |
535 er->group_id = group; |
571 |
536 |
572 /* Insert before the first element */ |
537 /* Insert before the first element */ |
573 er->next = (EngineRenew *)(*erl); |
538 er->next = (EngineRenew *)(*erl); |
574 *erl = (EngineRenewList)er; |
539 *erl = (EngineRenewList)er; |
|
540 |
|
541 er_auto_delete.Detach(); |
575 } |
542 } |
576 |
543 |
577 return CommandCost(); |
544 return CommandCost(); |
578 } |
545 } |
579 |
546 |
626 static void Load_ERNW() |
593 static void Load_ERNW() |
627 { |
594 { |
628 int index; |
595 int index; |
629 |
596 |
630 while ((index = SlIterateArray()) != -1) { |
597 while ((index = SlIterateArray()) != -1) { |
631 EngineRenew *er; |
598 EngineRenew *er = new (index) EngineRenew(); |
632 |
|
633 if (!AddBlockIfNeeded(&_EngineRenew_pool, index)) |
|
634 error("EngineRenews: failed loading savegame: too many EngineRenews"); |
|
635 |
|
636 er = GetEngineRenew(index); |
|
637 SlObject(er, _engine_renew_desc); |
599 SlObject(er, _engine_renew_desc); |
638 |
600 |
639 /* Advanced vehicle lists, ungrouped vehicles got added */ |
601 /* Advanced vehicle lists, ungrouped vehicles got added */ |
640 if (CheckSavegameVersion(60)) { |
602 if (CheckSavegameVersion(60)) { |
641 er->group_id = ALL_GROUP; |
603 er->group_id = ALL_GROUP; |