src/newgrf_commons.cpp
branchNewGRF_ports
changeset 6720 35756db7e577
parent 6719 4cc327ad39d5
child 6870 ca3fd1fbe311
equal deleted inserted replaced
6719:4cc327ad39d5 6720:35756db7e577
     4  * and its descendance, present and futur
     4  * and its descendance, present and futur
     5  */
     5  */
     6 
     6 
     7 #include "stdafx.h"
     7 #include "stdafx.h"
     8 #include "openttd.h"
     8 #include "openttd.h"
       
     9 #include "variables.h"
       
    10 #include "landscape.h"
     9 #include "town.h"
    11 #include "town.h"
    10 #include "industry.h"
    12 #include "industry.h"
    11 #include "newgrf.h"
    13 #include "newgrf.h"
    12 #include "newgrf_commons.h"
    14 #include "newgrf_commons.h"
    13 
    15 
    69  */
    71  */
    70 uint16 OverrideManagerBase::GetID(uint8 grf_local_id, uint32 grfid)
    72 uint16 OverrideManagerBase::GetID(uint8 grf_local_id, uint32 grfid)
    71 {
    73 {
    72 	const EntityIDMapping *map;
    74 	const EntityIDMapping *map;
    73 
    75 
    74 	for (uint16 id = max_offset; id < max_new_entities; id++) {
    76 	for (uint16 id = 0; id < max_new_entities; id++) {
    75 		map = &mapping_ID[id];
    77 		map = &mapping_ID[id];
    76 		if (map->entity_id == grf_local_id && map->grfid == grfid) {
    78 		if (map->entity_id == grf_local_id && map->grfid == grfid) {
    77 			return id;
    79 			return id;
    78 		}
    80 		}
    79 	}
    81 	}
   146 
   148 
   147 		overridden_hs->override = house_id;
   149 		overridden_hs->override = house_id;
   148 		entity_overrides[i] = invalid_ID;
   150 		entity_overrides[i] = invalid_ID;
   149 	}
   151 	}
   150 }
   152 }
       
   153 
       
   154 /** 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
       
   156  * @param grfid ID of the current grf file
       
   157  * @param substitute_id industry from which data has been copied
       
   158  * @return a free entity id (slotid) if ever one has been found, or Invalid_ID marker otherwise
       
   159  */
       
   160 uint16 IndustryOverrideManager::AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id)
       
   161 {
       
   162 	/* This entity hasn't been defined before, so give it an ID now. */
       
   163 	for (uint16 id = 0; id < max_new_entities; id++) {
       
   164 		/* Get the real live industry */
       
   165 		const IndustrySpec *inds = GetIndustrySpec(id);
       
   166 
       
   167 		/* 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).
       
   169 		 * So reseve this slot here, as it is the chosen one */
       
   170 		if (!inds->enabled && inds->grf_prop.grffile == NULL) {
       
   171 			EntityIDMapping *map = &mapping_ID[id];
       
   172 
       
   173 			if (map->entity_id == 0 && map->grfid == 0) {
       
   174 				/* winning slot, mark it as been used */
       
   175 				map->entity_id     = grf_local_id;
       
   176 				map->grfid         = grfid;
       
   177 				map->substitute_id = substitute_id;
       
   178 				return id;
       
   179 			}
       
   180 		}
       
   181 	}
       
   182 
       
   183 	return invalid_ID;
       
   184 }
       
   185 
       
   186 /** Method to install the new indistry data in its proper slot
       
   187  * The slot assigment is internal of this method, since it requires
       
   188  * checking what is available
       
   189  * @param inds Industryspec that comes from the grf decoding process
       
   190  */
       
   191 void IndustryOverrideManager::SetEntitySpec(const IndustrySpec *inds)
       
   192 {
       
   193 	/* 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);
       
   195 
       
   196 	if (ind_id == invalid_ID) { // not found?  So this is the introduction of a new industry
       
   197 		/* Second step is dealing with the override. */
       
   198 		if (inds->grf_prop.override != invalid_ID && _industry_specs[inds->grf_prop.override].grf_prop.override == invalid_ID) {
       
   199 			/* this is an override, which means it will take the place of the industry it is
       
   200 			 * designed to replace. Before we conclude that the override is allowed,
       
   201 			* we first need to verify that the slot is not holding another override
       
   202 			* If it's the case,it will be considered as a normal substitute */
       
   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 		}
       
   210 	}
       
   211 
       
   212 	if (ind_id == invalid_ID) {
       
   213 		grfmsg(1, "Industry.SetEntitySpec: Too many industries allocated. Ignoring.");
       
   214 		return;
       
   215 	}
       
   216 
       
   217 	/* Now that we know we can use the given id, copy the spech to its final destination*/
       
   218 	memcpy(&_industry_specs[ind_id], inds, sizeof(*inds));
       
   219 	/* and mark it as usable*/
       
   220 	_industry_specs[ind_id].enabled = true;
       
   221 }
       
   222 
       
   223 void IndustryTileOverrideManager::SetEntitySpec(const IndustryTileSpec *its)
       
   224 {
       
   225 	IndustryGfx indt_id = this->AddEntityID(its->grf_prop.local_id, its->grf_prop.grffile->grfid, its->grf_prop.subst_id);
       
   226 
       
   227 	if (indt_id == invalid_ID) {
       
   228 		grfmsg(1, "IndustryTile.SetEntitySpec: Too many industry tiles allocated. Ignoring.");
       
   229 		return;
       
   230 	}
       
   231 
       
   232 	memcpy(&_industry_tile_specs[indt_id], its, sizeof(*its));
       
   233 
       
   234 	/* Now add the overrides. */
       
   235 	for (int i = 0; i < max_offset; i++) {
       
   236 		IndustryTileSpec *overridden_its = &_industry_tile_specs[i];
       
   237 
       
   238 		if (entity_overrides[i] != its->grf_prop.local_id) continue;
       
   239 
       
   240 		overridden_its->grf_prop.override = indt_id;
       
   241 		overridden_its->enabled = false;
       
   242 		entity_overrides[i] = invalid_ID;
       
   243 	}
       
   244 }
       
   245 
       
   246 /** Function used by houses (and soon industries) to get information
       
   247  * on type of "terrain" the tile it is queries sits on.
       
   248  * @param tile TileIndex of the tile been queried
       
   249  * @return value corresponding to the grf expected format:
       
   250  *         Terrain type: 0 normal, 1 desert, 2 rainforest, 4 on or above snowline */
       
   251 uint32 GetTerrainType(TileIndex tile)
       
   252 {
       
   253 	switch (_opt.landscape) {
       
   254 		case LT_TROPIC: return GetTropicZone(tile) == TROPICZONE_DESERT ? 1 : 2;
       
   255 		case LT_ARCTIC: return GetTileZ(tile) >= GetSnowLine() ? 4 : 0;
       
   256 		default:        return 0;
       
   257 	}
       
   258 }
       
   259 
       
   260 TileIndex GetNearbyTile(byte parameter, TileIndex tile)
       
   261 {
       
   262 	int8 x = GB(parameter, 0, 4);
       
   263 	int8 y = GB(parameter, 4, 4);
       
   264 
       
   265 	if (x >= 8) x -= 16;
       
   266 	if (y >= 8) y -= 16;
       
   267 
       
   268 	/* Make sure we never roam outside of the map */
       
   269 	return TILE_MASK(tile + TileDiffXY(x, y));
       
   270 }