newgrf_config.c
changeset 5393 cf584337ea2c
parent 5380 8ea58542b6e0
child 5401 b329aa268ce4
equal deleted inserted replaced
5392:dd535f122f1d 5393:cf584337ea2c
   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 };