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