src/autoreplace.cpp
changeset 10127 4f53c1cfcfe9
equal deleted inserted replaced
10126:48162ce1b642 10127:4f53c1cfcfe9
       
     1 /* $Id$ */
       
     2 
       
     3 /** @file autoreplace.cpp Management of replacement lists. */
       
     4 
       
     5 #include "stdafx.h"
       
     6 #include "openttd.h"
       
     7 #include "debug.h"
       
     8 #include "command_func.h"
       
     9 #include "saveload.h"
       
    10 #include "group.h"
       
    11 #include "autoreplace_base.h"
       
    12 #include "oldpool_func.h"
       
    13 
       
    14 DEFINE_OLD_POOL_GENERIC(EngineRenew, EngineRenew)
       
    15 
       
    16 /**
       
    17  * Retrieves the EngineRenew that specifies the replacement of the given
       
    18  * engine type from the given renewlist */
       
    19 static EngineRenew *GetEngineReplacement(EngineRenewList erl, EngineID engine, GroupID group)
       
    20 {
       
    21 	EngineRenew *er = (EngineRenew *)erl;
       
    22 
       
    23 	while (er) {
       
    24 		if (er->from == engine && er->group_id == group) return er;
       
    25 		er = er->next;
       
    26 	}
       
    27 	return NULL;
       
    28 }
       
    29 
       
    30 void RemoveAllEngineReplacement(EngineRenewList *erl)
       
    31 {
       
    32 	EngineRenew *er = (EngineRenew *)(*erl);
       
    33 	EngineRenew *next;
       
    34 
       
    35 	while (er != NULL) {
       
    36 		next = er->next;
       
    37 		delete er;
       
    38 		er = next;
       
    39 	}
       
    40 	*erl = NULL; // Empty list
       
    41 }
       
    42 
       
    43 EngineID EngineReplacement(EngineRenewList erl, EngineID engine, GroupID group)
       
    44 {
       
    45 	const EngineRenew *er = GetEngineReplacement(erl, engine, group);
       
    46 	if (er == NULL && (group == DEFAULT_GROUP || (IsValidGroupID(group) && !GetGroup(group)->replace_protection))) {
       
    47 		/* We didn't find anything useful in the vehicle's own group so we will try ALL_GROUP */
       
    48 		er = GetEngineReplacement(erl, engine, ALL_GROUP);
       
    49 	}
       
    50 	return er == NULL ? INVALID_ENGINE : er->to;
       
    51 }
       
    52 
       
    53 CommandCost AddEngineReplacement(EngineRenewList *erl, EngineID old_engine, EngineID new_engine, GroupID group, uint32 flags)
       
    54 {
       
    55 	EngineRenew *er;
       
    56 
       
    57 	/* Check if the old vehicle is already in the list */
       
    58 	er = GetEngineReplacement(*erl, old_engine, group);
       
    59 	if (er != NULL) {
       
    60 		if (flags & DC_EXEC) er->to = new_engine;
       
    61 		return CommandCost();
       
    62 	}
       
    63 
       
    64 	if (!EngineRenew::CanAllocateItem()) return CMD_ERROR;
       
    65 
       
    66 	if (flags & DC_EXEC) {
       
    67 		er = new EngineRenew(old_engine, new_engine);
       
    68 		er->group_id = group;
       
    69 
       
    70 		/* Insert before the first element */
       
    71 		er->next = (EngineRenew *)(*erl);
       
    72 		*erl = (EngineRenewList)er;
       
    73 	}
       
    74 
       
    75 	return CommandCost();
       
    76 }
       
    77 
       
    78 CommandCost RemoveEngineReplacement(EngineRenewList *erl, EngineID engine, GroupID group, uint32 flags)
       
    79 {
       
    80 	EngineRenew *er = (EngineRenew *)(*erl);
       
    81 	EngineRenew *prev = NULL;
       
    82 
       
    83 	while (er)
       
    84 	{
       
    85 		if (er->from == engine && er->group_id == group) {
       
    86 			if (flags & DC_EXEC) {
       
    87 				if (prev == NULL) { // First element
       
    88 					/* The second becomes the new first element */
       
    89 					*erl = (EngineRenewList)er->next;
       
    90 				} else {
       
    91 					/* Cut this element out */
       
    92 					prev->next = er->next;
       
    93 				}
       
    94 				delete er;
       
    95 			}
       
    96 			return CommandCost();
       
    97 		}
       
    98 		prev = er;
       
    99 		er = er->next;
       
   100 	}
       
   101 
       
   102 	return CMD_ERROR;
       
   103 }
       
   104 
       
   105 static const SaveLoad _engine_renew_desc[] = {
       
   106 	    SLE_VAR(EngineRenew, from,     SLE_UINT16),
       
   107 	    SLE_VAR(EngineRenew, to,       SLE_UINT16),
       
   108 
       
   109 	    SLE_REF(EngineRenew, next,     REF_ENGINE_RENEWS),
       
   110 	SLE_CONDVAR(EngineRenew, group_id, SLE_UINT16, 60, SL_MAX_VERSION),
       
   111 	SLE_END()
       
   112 };
       
   113 
       
   114 static void Save_ERNW()
       
   115 {
       
   116 	EngineRenew *er;
       
   117 
       
   118 	FOR_ALL_ENGINE_RENEWS(er) {
       
   119 		SlSetArrayIndex(er->index);
       
   120 		SlObject(er, _engine_renew_desc);
       
   121 	}
       
   122 }
       
   123 
       
   124 static void Load_ERNW()
       
   125 {
       
   126 	int index;
       
   127 
       
   128 	while ((index = SlIterateArray()) != -1) {
       
   129 		EngineRenew *er = new (index) EngineRenew();
       
   130 		SlObject(er, _engine_renew_desc);
       
   131 
       
   132 		/* Advanced vehicle lists, ungrouped vehicles got added */
       
   133 		if (CheckSavegameVersion(60)) {
       
   134 			er->group_id = ALL_GROUP;
       
   135 		} else if (CheckSavegameVersion(71)) {
       
   136 			if (er->group_id == DEFAULT_GROUP) er->group_id = ALL_GROUP;
       
   137 		}
       
   138 	}
       
   139 }
       
   140 
       
   141 extern const ChunkHandler _autoreplace_chunk_handlers[] = {
       
   142 	{ 'ERNW', Save_ERNW,     Load_ERNW,     CH_ARRAY | CH_LAST},
       
   143 };
       
   144 
       
   145 void InitializeEngineRenews()
       
   146 {
       
   147 	/* Clean the engine renew pool and create 1 block in it */
       
   148 	_EngineRenew_pool.CleanPool();
       
   149 	_EngineRenew_pool.AddBlockToPool();
       
   150 }