|
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 } |