22 #include "newgrf_house.h" |
22 #include "newgrf_house.h" |
23 #include "newgrf_spritegroup.h" |
23 #include "newgrf_spritegroup.h" |
24 #include "newgrf_callbacks.h" |
24 #include "newgrf_callbacks.h" |
25 #include "newgrf_town.h" |
25 #include "newgrf_town.h" |
26 #include "newgrf_sound.h" |
26 #include "newgrf_sound.h" |
|
27 #include "newgrf_commons.h" |
27 |
28 |
28 static BuildingCounts _building_counts; |
29 static BuildingCounts _building_counts; |
29 static HouseClassMapping _class_mapping[HOUSE_CLASS_MAX]; |
30 static HouseClassMapping _class_mapping[HOUSE_CLASS_MAX]; |
30 HouseIDMapping _house_id_mapping[HOUSE_MAX]; |
31 |
31 |
32 HouseOverrideManager _house_mngr(NEW_HOUSE_OFFSET, HOUSE_MAX, INVALID_HOUSE_ID); |
32 /* Since the house IDs defined by the GRF file don't necessarily correlate |
|
33 * to those used by the game, the IDs used for overriding old houses must be |
|
34 * translated when the house spec is set. */ |
|
35 static uint16 _house_overrides[NEW_HOUSE_OFFSET]; |
|
36 |
|
37 void AddHouseOverride(uint8 local_id, uint house_type) |
|
38 { |
|
39 assert(house_type < NEW_HOUSE_OFFSET); |
|
40 _house_overrides[house_type] = local_id; |
|
41 } |
|
42 |
|
43 void ResetHouseOverrides() |
|
44 { |
|
45 for (int i = 0; i != lengthof(_house_overrides); i++) { |
|
46 _house_overrides[i] = INVALID_HOUSE_ID; |
|
47 } |
|
48 } |
|
49 |
|
50 static HouseID GetHouseID(byte grf_local_id, uint32 grfid) |
|
51 { |
|
52 const HouseIDMapping *map; |
|
53 |
|
54 for (HouseID house_id = NEW_HOUSE_OFFSET; house_id != lengthof(_house_id_mapping); house_id++) { |
|
55 map = &_house_id_mapping[house_id]; |
|
56 if (map->house_id == grf_local_id && map->grfid == grfid) return house_id; |
|
57 } |
|
58 return INVALID_HOUSE_ID; |
|
59 } |
|
60 |
|
61 static HouseID AddHouseID(byte grf_local_id, uint32 grfid, byte substitute_id) |
|
62 { |
|
63 HouseID house_id; |
|
64 HouseIDMapping *map; |
|
65 |
|
66 /* Look to see if this house has already been added. This is done |
|
67 * separately from the loop below in case a GRF has been deleted, and there |
|
68 * are any gaps in the array. */ |
|
69 house_id = GetHouseID(grf_local_id, grfid); |
|
70 if (house_id != INVALID_HOUSE_ID) return house_id; |
|
71 |
|
72 /* This house hasn't been defined before, so give it an ID now. */ |
|
73 for (house_id = NEW_HOUSE_OFFSET; house_id != lengthof(_house_id_mapping); house_id++) { |
|
74 map = &_house_id_mapping[house_id]; |
|
75 |
|
76 if (map->house_id == 0 && map->grfid == 0) { |
|
77 map->house_id = grf_local_id; |
|
78 map->grfid = grfid; |
|
79 map->substitute_id = substitute_id; |
|
80 return house_id; |
|
81 } |
|
82 } |
|
83 |
|
84 return INVALID_HOUSE_ID; |
|
85 } |
|
86 |
|
87 void SetHouseSpec(const HouseSpec *hs) |
|
88 { |
|
89 HouseID house_id = AddHouseID(hs->local_id, hs->grffile->grfid, hs->substitute_id); |
|
90 |
|
91 if (house_id == INVALID_HOUSE_ID) { |
|
92 grfmsg(1, "SetHouseSpec: Too many houses allocated. Ignoring."); |
|
93 return; |
|
94 } |
|
95 |
|
96 memcpy(&_house_specs[house_id], hs, sizeof(*hs)); |
|
97 |
|
98 /* Now add the overrides. */ |
|
99 for (int i = 0; i != lengthof(_house_overrides); i++) { |
|
100 HouseSpec *overridden_hs = GetHouseSpecs(i); |
|
101 |
|
102 if (_house_overrides[i] != hs->local_id) continue; |
|
103 |
|
104 overridden_hs->override = house_id; |
|
105 _house_overrides[i] = INVALID_HOUSE_ID; |
|
106 } |
|
107 } |
|
108 |
|
109 void ResetHouseIDMapping() |
|
110 { |
|
111 memset(&_house_id_mapping, 0, sizeof(_house_id_mapping)); |
|
112 } |
|
113 |
33 |
114 void CheckHouseIDs() |
34 void CheckHouseIDs() |
115 { |
35 { |
116 for (TileIndex t = 0; t < MapSize(); t++) { |
36 for (TileIndex t = 0; t < MapSize(); t++) { |
117 HouseID house_id; |
37 HouseID house_id; |
120 |
40 |
121 house_id = GetHouseType(t); |
41 house_id = GetHouseType(t); |
122 if (!GetHouseSpecs(house_id)->enabled && house_id >= NEW_HOUSE_OFFSET) { |
42 if (!GetHouseSpecs(house_id)->enabled && house_id >= NEW_HOUSE_OFFSET) { |
123 /* The specs for this type of house are not available any more, so |
43 /* The specs for this type of house are not available any more, so |
124 * replace it with the substitute original house type. */ |
44 * replace it with the substitute original house type. */ |
125 SetHouseType(t, _house_id_mapping[house_id].substitute_id); |
45 SetHouseType(t, _house_mngr.GetSubstituteID(house_id)); |
126 } |
46 } |
127 } |
47 } |
128 |
48 |
129 InitializeBuildingCounts(); |
49 InitializeBuildingCounts(); |
130 AfterLoadCountBuildings(); |
50 AfterLoadCountBuildings(); |
311 /* Building counts for new houses with id = parameter. */ |
231 /* Building counts for new houses with id = parameter. */ |
312 case 0x61: { |
232 case 0x61: { |
313 const HouseSpec *hs = GetHouseSpecs(house_id); |
233 const HouseSpec *hs = GetHouseSpecs(house_id); |
314 if (hs->grffile == NULL) return 0; |
234 if (hs->grffile == NULL) return 0; |
315 |
235 |
316 HouseID new_house = GetHouseID(parameter, hs->grffile->grfid); |
236 HouseID new_house = _house_mngr.GetID(parameter, hs->grffile->grfid); |
317 return new_house == INVALID_HOUSE_ID ? 0 : GetNumHouses(new_house, town); |
237 return new_house == INVALID_HOUSE_ID ? 0 : GetNumHouses(new_house, town); |
318 } |
238 } |
319 |
239 |
320 /* Land info for nearby tiles. */ |
240 /* Land info for nearby tiles. */ |
321 case 0x62: { |
241 case 0x62: { |
575 if (GetHouseProcessingTime(tile) > 0) { |
495 if (GetHouseProcessingTime(tile) > 0) { |
576 DecHouseProcessingTime(tile); |
496 DecHouseProcessingTime(tile); |
577 return true; |
497 return true; |
578 } |
498 } |
579 |
499 |
580 /* @todo: Magic with triggers goes here. Got to implement that, one day. .. */ |
500 /* @todo: Magic with triggers goes here. Got to implement that, one day. .. |
|
501 * Process randomizing of tiles following specs. |
|
502 * Once done, redraw the house |
|
503 * MarkTileDirtyByTile(tile); |
|
504 */ |
581 |
505 |
582 if (HASBIT(hs->callback_mask, CBM_ANIMATION_START_STOP)) { |
506 if (HASBIT(hs->callback_mask, CBM_ANIMATION_START_STOP)) { |
583 /* If this house is marked as having a synchronised callback, all the |
507 /* If this house is marked as having a synchronised callback, all the |
584 * tiles will have the callback called at once, rather than when the |
508 * tiles will have the callback called at once, rather than when the |
585 * tile loop reaches them. This should only be enabled for the northern |
509 * tile loop reaches them. This should only be enabled for the northern |