src/newgrf_house.cpp
changeset 7125 4ce0c7a12a3f
parent 6923 6913c8a82cc0
child 7138 feca3eff4054
equal deleted inserted replaced
7124:b45674a97d9e 7125:4ce0c7a12a3f
    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