|
1 /* $Id$ */ |
|
2 |
|
3 /** @file newgrf_commons.cpp Implementation of the class OverrideManagerBase |
|
4 * and its descendance, present and futur |
|
5 */ |
|
6 |
|
7 #include "stdafx.h" |
|
8 #include "openttd.h" |
|
9 #include "town.h" |
|
10 #include "industry.h" |
|
11 #include "newgrf.h" |
|
12 #include "newgrf_commons.h" |
|
13 |
|
14 /** Constructor of generic class |
|
15 * @param offset end of original data for this entity. i.e: houses = 110 |
|
16 * @param maximum of entities this manager can deal with. i.e: houses = 512 |
|
17 * @param invalid is the ID used to identify an invalid entity id |
|
18 */ |
|
19 OverrideManagerBase::OverrideManagerBase(uint16 offset, uint16 maximum, uint16 invalid) |
|
20 { |
|
21 max_offset = offset; |
|
22 max_new_entities = maximum; |
|
23 invalid_ID = invalid; |
|
24 |
|
25 mapping_ID = CallocT<EntityIDMapping>(max_new_entities); |
|
26 entity_overrides = MallocT<uint16>(max_offset); |
|
27 memset(entity_overrides, invalid, sizeof(entity_overrides)); |
|
28 } |
|
29 |
|
30 /** Destructor of the generic class. |
|
31 * Frees allocated memory of constructor |
|
32 */ |
|
33 OverrideManagerBase::~OverrideManagerBase() |
|
34 { |
|
35 free(mapping_ID); |
|
36 free(entity_overrides); |
|
37 } |
|
38 |
|
39 /** Since the entity IDs defined by the GRF file does not necessarily correlate |
|
40 * to those used by the game, the IDs used for overriding old entities must be |
|
41 * translated when the entity spec is set. |
|
42 * @param local_id id in grf file |
|
43 * @param entity_type original entity type |
|
44 */ |
|
45 void OverrideManagerBase::Add(uint8 local_id, uint entity_type) |
|
46 { |
|
47 assert(entity_type < max_offset); |
|
48 entity_overrides[entity_type] = local_id; |
|
49 } |
|
50 |
|
51 /** Resets the mapping, which is used while initializing game */ |
|
52 void OverrideManagerBase::ResetMapping() |
|
53 { |
|
54 memset(mapping_ID, 0, (max_new_entities - 1) * sizeof(EntityIDMapping)); |
|
55 } |
|
56 |
|
57 /** Resets the override, which is used while initializing game */ |
|
58 void OverrideManagerBase::ResetOverride() |
|
59 { |
|
60 for (uint16 i = 0; i < max_offset; i++) { |
|
61 entity_overrides[i] = invalid_ID; |
|
62 } |
|
63 } |
|
64 |
|
65 /** Return the ID (if ever available) of a previously inserted entity. |
|
66 * @param grf_local_id ID of this enity withing the grfID |
|
67 * @param grfid ID of the grf file |
|
68 * @return the ID of the candidate, of the Invalid flag item ID |
|
69 */ |
|
70 uint16 OverrideManagerBase::GetID(uint8 grf_local_id, uint32 grfid) |
|
71 { |
|
72 const EntityIDMapping *map; |
|
73 |
|
74 for (uint16 id = max_offset; id < max_new_entities; id++) { |
|
75 map = &mapping_ID[id]; |
|
76 if (map->entity_id == grf_local_id && map->grfid == grfid) { |
|
77 return id; |
|
78 } |
|
79 } |
|
80 return invalid_ID; |
|
81 } |
|
82 |
|
83 /** Reserves a place in the mapping array for an entity to be installed |
|
84 * @param grf_local_id is an arbitrary id given by the grf's author. Also known as setid |
|
85 * @param grfid is the id of the grf file itself |
|
86 * @param substitute_id is the original entity from which data is copied for the new one |
|
87 * @return the proper usable slot id, or invalid marker if none is found |
|
88 */ |
|
89 uint16 OverrideManagerBase::AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id) |
|
90 { |
|
91 uint16 id = this->GetID(grf_local_id, grfid); |
|
92 EntityIDMapping *map; |
|
93 |
|
94 /* Look to see if this entity has already been added. This is done |
|
95 * separately from the loop below in case a GRF has been deleted, and there |
|
96 * are any gaps in the array. |
|
97 */ |
|
98 if (id != invalid_ID) { |
|
99 return id; |
|
100 } |
|
101 |
|
102 /* This entity hasn't been defined before, so give it an ID now. */ |
|
103 for (id = max_offset; id < max_new_entities; id++) { |
|
104 map = &mapping_ID[id]; |
|
105 |
|
106 if (map->entity_id == 0 && map->grfid == 0) { |
|
107 map->entity_id = grf_local_id; |
|
108 map->grfid = grfid; |
|
109 map->substitute_id = substitute_id; |
|
110 return id; |
|
111 } |
|
112 } |
|
113 |
|
114 return invalid_ID; |
|
115 } |
|
116 |
|
117 /** Gives the substitute of the entity, as specified by the grf file |
|
118 * @param entity_id of the entity being queried |
|
119 * @return mapped id |
|
120 */ |
|
121 uint16 OverrideManagerBase::GetSubstituteID(byte entity_id) |
|
122 { |
|
123 return mapping_ID[entity_id].substitute_id; |
|
124 } |
|
125 |
|
126 /** Install the specs into the HouseSpecs array |
|
127 * It will find itself the proper slot onwhich it will go |
|
128 * @param hs HouseSpec read from the grf file, ready for inclusion |
|
129 */ |
|
130 void HouseOverrideManager::SetEntitySpec(const HouseSpec *hs) |
|
131 { |
|
132 HouseID house_id = this->AddEntityID(hs->local_id, hs->grffile->grfid, hs->substitute_id); |
|
133 |
|
134 if (house_id == invalid_ID) { |
|
135 grfmsg(1, "House.SetEntitySpec: Too many houses allocated. Ignoring."); |
|
136 return; |
|
137 } |
|
138 |
|
139 memcpy(&_house_specs[house_id], hs, sizeof(*hs)); |
|
140 |
|
141 /* Now add the overrides. */ |
|
142 for (int i = 0; i != max_offset; i++) { |
|
143 HouseSpec *overridden_hs = GetHouseSpecs(i); |
|
144 |
|
145 if (entity_overrides[i] != hs->local_id) continue; |
|
146 |
|
147 overridden_hs->override = house_id; |
|
148 entity_overrides[i] = invalid_ID; |
|
149 } |
|
150 } |