129 } |
129 } |
130 |
130 |
131 return dst; |
131 return dst; |
132 } |
132 } |
133 |
133 |
|
134 /** |
|
135 * Removes duplicates from lists of GRFConfigs. These duplicates |
|
136 * are introduced when the _grfconfig_static GRFs are appended |
|
137 * to the _grfconfig on a newgame or savegame. As the parameters |
|
138 * of the static GRFs could be different that the parameters of |
|
139 * the ones used non-statically. This can result in desyncs in |
|
140 * multiplayers, so the duplicate static GRFs have to be removed. |
|
141 * |
|
142 * This function _assumes_ that all static GRFs are placed after |
|
143 * the non-static GRFs. |
|
144 * |
|
145 * @param list the list to remove the duplicates from |
|
146 */ |
|
147 static void RemoveDuplicatesFromGRFConfigList(GRFConfig *list) |
|
148 { |
|
149 GRFConfig *prev; |
|
150 GRFConfig *cur; |
|
151 |
|
152 if (list == NULL) return; |
|
153 |
|
154 for (prev = list, cur = list->next; cur != NULL; prev = cur, cur = cur->next) { |
|
155 if (cur->grfid != list->grfid) continue; |
|
156 assert(HASBIT(cur->flags, GCF_STATIC)); |
|
157 prev->next = cur->next; |
|
158 ClearGRFConfig(&cur); |
|
159 cur = prev; // Just go back one so it continues as normal later on |
|
160 } |
|
161 |
|
162 RemoveDuplicatesFromGRFConfigList(list->next); |
|
163 } |
|
164 |
|
165 /** |
|
166 * Appends the static GRFs to a list of GRFs |
|
167 * @param dst the head of the list to add to |
|
168 */ |
|
169 void AppendStaticGRFConfigs(GRFConfig **dst) |
|
170 { |
|
171 GRFConfig **tail = dst; |
|
172 while (*tail != NULL) tail = &(*tail)->next; |
|
173 |
|
174 CopyGRFConfigList(tail, _grfconfig_static); |
|
175 RemoveDuplicatesFromGRFConfigList(*dst); |
|
176 } |
|
177 |
134 |
178 |
135 /* Reset the current GRF Config to either blank or newgame settings */ |
179 /* Reset the current GRF Config to either blank or newgame settings */ |
136 void ResetGRFConfig(bool defaults) |
180 void ResetGRFConfig(bool defaults) |
137 { |
181 { |
138 GRFConfig **c = &_grfconfig; |
182 GRFConfig **c = &_grfconfig; |
139 |
183 |
140 if (defaults) c = CopyGRFConfigList(c, _grfconfig_newgame); |
184 if (defaults) c = CopyGRFConfigList(c, _grfconfig_newgame); |
141 CopyGRFConfigList(c, _grfconfig_static); |
185 AppendStaticGRFConfigs(&_grfconfig); |
142 } |
186 } |
143 |
187 |
144 |
188 |
145 /* Check if all GRFs in the GRF Config can be loaded */ |
189 /* Check if all GRFs in the GRF Config can be loaded */ |
146 bool IsGoodGRFConfigList(void) |
190 bool IsGoodGRFConfigList(void) |
398 /* Append static NewGRF configuration */ |
442 /* Append static NewGRF configuration */ |
399 CopyGRFConfigList(last, _grfconfig_static); |
443 CopyGRFConfigList(last, _grfconfig_static); |
400 |
444 |
401 ClearGRFConfigList(&_grfconfig); |
445 ClearGRFConfigList(&_grfconfig); |
402 _grfconfig = first; |
446 _grfconfig = first; |
|
447 AppendStaticGRFConfigs(&_grfconfig); |
403 } |
448 } |
404 |
449 |
405 const ChunkHandler _newgrf_chunk_handlers[] = { |
450 const ChunkHandler _newgrf_chunk_handlers[] = { |
406 { 'NGRF', Save_NGRF, Load_NGRF, CH_ARRAY | CH_LAST } |
451 { 'NGRF', Save_NGRF, Load_NGRF, CH_ARRAY | CH_LAST } |
407 }; |
452 }; |