src/newgrf_commons.cpp
branchNewGRF_ports
changeset 6871 5a9dc001e1ad
parent 6870 ca3fd1fbe311
child 6872 1c4a4a609f85
equal deleted inserted replaced
6870:ca3fd1fbe311 6871:5a9dc001e1ad
    25 	invalid_ID = invalid;
    25 	invalid_ID = invalid;
    26 
    26 
    27 	mapping_ID = CallocT<EntityIDMapping>(max_new_entities);
    27 	mapping_ID = CallocT<EntityIDMapping>(max_new_entities);
    28 	entity_overrides = MallocT<uint16>(max_offset);
    28 	entity_overrides = MallocT<uint16>(max_offset);
    29 	memset(entity_overrides, invalid, sizeof(entity_overrides));
    29 	memset(entity_overrides, invalid, sizeof(entity_overrides));
       
    30 	grfid_overrides = CallocT<uint32>(max_offset);
    30 }
    31 }
    31 
    32 
    32 /** Destructor of the generic class.
    33 /** Destructor of the generic class.
    33  * Frees allocated memory of constructor
    34  * Frees allocated memory of constructor
    34  */
    35  */
    35 OverrideManagerBase::~OverrideManagerBase()
    36 OverrideManagerBase::~OverrideManagerBase()
    36 {
    37 {
    37 	free(mapping_ID);
    38 	free(mapping_ID);
    38 	free(entity_overrides);
    39 	free(entity_overrides);
       
    40 	free(grfid_overrides);
    39 }
    41 }
    40 
    42 
    41 /** Since the entity IDs defined by the GRF file does not necessarily correlate
    43 /** Since the entity IDs defined by the GRF file does not necessarily correlate
    42  * to those used by the game, the IDs used for overriding old entities must be
    44  * to those used by the game, the IDs used for overriding old entities must be
    43  * translated when the entity spec is set.
    45  * translated when the entity spec is set.
    44  * @param local_id id in grf file
    46  * @param local_id ID in grf file
       
    47  * @param grfid  ID of the grf file
    45  * @param entity_type original entity type
    48  * @param entity_type original entity type
    46  */
    49  */
    47 void OverrideManagerBase::Add(uint8 local_id, uint entity_type)
    50 void OverrideManagerBase::Add(uint8 local_id, uint32 grfid, uint entity_type)
    48 {
    51 {
    49 	assert(entity_type < max_offset);
    52 	assert(entity_type < max_offset);
       
    53 	/* An override can be set only once */
       
    54 	if (entity_overrides[entity_type] != invalid_ID) return;
    50 	entity_overrides[entity_type] = local_id;
    55 	entity_overrides[entity_type] = local_id;
       
    56 	grfid_overrides[entity_type] = grfid;
    51 }
    57 }
    52 
    58 
    53 /** Resets the mapping, which is used while initializing game */
    59 /** Resets the mapping, which is used while initializing game */
    54 void OverrideManagerBase::ResetMapping()
    60 void OverrideManagerBase::ResetMapping()
    55 {
    61 {
    59 /** Resets the override, which is used while initializing game */
    65 /** Resets the override, which is used while initializing game */
    60 void OverrideManagerBase::ResetOverride()
    66 void OverrideManagerBase::ResetOverride()
    61 {
    67 {
    62 	for (uint16 i = 0; i < max_offset; i++) {
    68 	for (uint16 i = 0; i < max_offset; i++) {
    63 		entity_overrides[i] = invalid_ID;
    69 		entity_overrides[i] = invalid_ID;
       
    70 		grfid_overrides[i] = 0;
    64 	}
    71 	}
    65 }
    72 }
    66 
    73 
    67 /** Return the ID (if ever available) of a previously inserted entity.
    74 /** Return the ID (if ever available) of a previously inserted entity.
    68  * @param grf_local_id ID of this enity withing the grfID
    75  * @param grf_local_id ID of this enity withing the grfID
    77 		map = &mapping_ID[id];
    84 		map = &mapping_ID[id];
    78 		if (map->entity_id == grf_local_id && map->grfid == grfid) {
    85 		if (map->entity_id == grf_local_id && map->grfid == grfid) {
    79 			return id;
    86 			return id;
    80 		}
    87 		}
    81 	}
    88 	}
       
    89 
       
    90 	/* No mapping found, try the overrides */
       
    91 	for (uint16 id = 0; id < max_offset; id++) {
       
    92 		if (entity_overrides[id] == grf_local_id && grfid_overrides[id] == grfid) return id;
       
    93 	}
       
    94 
    82 	return invalid_ID;
    95 	return invalid_ID;
    83 }
    96 }
    84 
    97 
    85 /** Reserves a place in the mapping array for an entity to be installed
    98 /** Reserves a place in the mapping array for an entity to be installed
    86  * @param grf_local_id is an arbitrary id given by the grf's author.  Also known as setid
    99  * @param grf_local_id is an arbitrary id given by the grf's author.  Also known as setid
   142 
   155 
   143 	/* Now add the overrides. */
   156 	/* Now add the overrides. */
   144 	for (int i = 0; i != max_offset; i++) {
   157 	for (int i = 0; i != max_offset; i++) {
   145 		HouseSpec *overridden_hs = GetHouseSpecs(i);
   158 		HouseSpec *overridden_hs = GetHouseSpecs(i);
   146 
   159 
   147 		if (entity_overrides[i] != hs->local_id) continue;
   160 		if (entity_overrides[i] != hs->local_id || grfid_overrides[i] != hs->grffile->grfid) continue;
   148 
   161 
   149 		overridden_hs->override = house_id;
   162 		overridden_hs->override = house_id;
   150 		entity_overrides[i] = invalid_ID;
   163 		entity_overrides[i] = invalid_ID;
       
   164 		grfid_overrides[i] = 0;
   151 	}
   165 	}
   152 }
   166 }
   153 
   167 
   154 /** Method to find an entity ID and to mark it as reserved for the Industry to be included.
   168 /** Method to find an entity ID and to mark it as reserved for the Industry to be included.
   155  * @param grf_local_id ID used by the grf file for pre-installation work (equivalent of TTDPatch's setid
   169  * @param grf_local_id ID used by the grf file for pre-installation work (equivalent of TTDPatch's setid
   159  */
   173  */
   160 uint16 IndustryOverrideManager::AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id)
   174 uint16 IndustryOverrideManager::AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id)
   161 {
   175 {
   162 	/* This entity hasn't been defined before, so give it an ID now. */
   176 	/* This entity hasn't been defined before, so give it an ID now. */
   163 	for (uint16 id = 0; id < max_new_entities; id++) {
   177 	for (uint16 id = 0; id < max_new_entities; id++) {
       
   178 		/* Skip overriden industries */
       
   179 		if (id < max_offset && entity_overrides[id] != invalid_ID) continue;
       
   180 
   164 		/* Get the real live industry */
   181 		/* Get the real live industry */
   165 		const IndustrySpec *inds = GetIndustrySpec(id);
   182 		const IndustrySpec *inds = GetIndustrySpec(id);
   166 
   183 
   167 		/* This industry must be one that is not available(enabled), mostly because of climate.
   184 		/* This industry must be one that is not available(enabled), mostly because of climate.
   168 		 * And it must not already be used by a grf (grffile == NULL).
   185 		 * And it must not already be used by a grf (grffile == NULL).
   191 void IndustryOverrideManager::SetEntitySpec(IndustrySpec *inds)
   208 void IndustryOverrideManager::SetEntitySpec(IndustrySpec *inds)
   192 {
   209 {
   193 	/* First step : We need to find if this industry is already specified in the savegame data */
   210 	/* First step : We need to find if this industry is already specified in the savegame data */
   194 	IndustryType ind_id = this->GetID(inds->grf_prop.local_id, inds->grf_prop.grffile->grfid);
   211 	IndustryType ind_id = this->GetID(inds->grf_prop.local_id, inds->grf_prop.grffile->grfid);
   195 
   212 
   196 	if (ind_id == invalid_ID) { // not found?  So this is the introduction of a new industry
   213 	if (ind_id == invalid_ID) {
   197 		/* Second step is dealing with the override. */
   214 		/* Not found.
   198 		if (inds->grf_prop.override != invalid_ID && _industry_specs[inds->grf_prop.override].grf_prop.override == invalid_ID) {
   215 		 * Or it has already been overriden, so you've lost your place old boy.
   199 			/* this is an override, which means it will take the place of the industry it is
   216 		 * Or it is a simple substitute.
   200 			 * designed to replace. Before we conclude that the override is allowed,
   217 		 * We need to find a free available slot */
   201 			* we first need to verify that the slot is not holding another override
   218 		ind_id = this->AddEntityID(inds->grf_prop.local_id, inds->grf_prop.grffile->grfid, inds->grf_prop.subst_id);
   202 			* If it's the case,it will be considered as a normal substitute */
   219 		inds->grf_prop.override = invalid_ID;  // make sure it will not be detected as overriden
   203 			ind_id = inds->grf_prop.override;
       
   204 		} else {
       
   205 			/* It has already been overriden, so you've lost your place old boy.
       
   206 			 * Or it is a simple substitute.
       
   207 			 * In both case, we need to find a free available slot */
       
   208 			ind_id = this->AddEntityID(inds->grf_prop.local_id, inds->grf_prop.grffile->grfid, inds->grf_prop.subst_id);
       
   209 			inds->grf_prop.override = invalid_ID;  // make sure it will not be detected as overriden
       
   210 		}
       
   211 	}
   220 	}
   212 
   221 
   213 	if (ind_id == invalid_ID) {
   222 	if (ind_id == invalid_ID) {
   214 		grfmsg(1, "Industry.SetEntitySpec: Too many industries allocated. Ignoring.");
   223 		grfmsg(1, "Industry.SetEntitySpec: Too many industries allocated. Ignoring.");
   215 		return;
   224 		return;
   234 
   243 
   235 	/* Now add the overrides. */
   244 	/* Now add the overrides. */
   236 	for (int i = 0; i < max_offset; i++) {
   245 	for (int i = 0; i < max_offset; i++) {
   237 		IndustryTileSpec *overridden_its = &_industry_tile_specs[i];
   246 		IndustryTileSpec *overridden_its = &_industry_tile_specs[i];
   238 
   247 
   239 		if (entity_overrides[i] != its->grf_prop.local_id) continue;
   248 		if (entity_overrides[i] != its->grf_prop.local_id || grfid_overrides[i] != its->grf_prop.grffile->grfid) continue;
   240 
   249 
   241 		overridden_its->grf_prop.override = indt_id;
   250 		overridden_its->grf_prop.override = indt_id;
   242 		overridden_its->enabled = false;
   251 		overridden_its->enabled = false;
   243 		entity_overrides[i] = invalid_ID;
   252 		entity_overrides[i] = invalid_ID;
       
   253 		grfid_overrides[i] = 0;
   244 	}
   254 	}
   245 }
   255 }
   246 
   256 
   247 /** Function used by houses (and soon industries) to get information
   257 /** Function used by houses (and soon industries) to get information
   248  * on type of "terrain" the tile it is queries sits on.
   258  * on type of "terrain" the tile it is queries sits on.