newgrf_commons.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00014 #include "stdafx.h"
00015 #include "landscape.h"
00016 #include "house.h"
00017 #include "industrytype.h"
00018 #include "newgrf.h"
00019 #include "newgrf_commons.h"
00020 #include "clear_map.h"
00021 #include "station_map.h"
00022 #include "tree_map.h"
00023 #include "tunnelbridge_map.h"
00024 #include "variables.h"
00025 #include "core/mem_func.hpp"
00026
00032 OverrideManagerBase::OverrideManagerBase(uint16 offset, uint16 maximum, uint16 invalid)
00033 {
00034 max_offset = offset;
00035 max_new_entities = maximum;
00036 invalid_ID = invalid;
00037
00038 mapping_ID = CallocT<EntityIDMapping>(max_new_entities);
00039 entity_overrides = MallocT<uint16>(max_offset);
00040 for (size_t i = 0; i < max_offset; i++) entity_overrides[i] = invalid;
00041 grfid_overrides = CallocT<uint32>(max_offset);
00042 }
00043
00047 OverrideManagerBase::~OverrideManagerBase()
00048 {
00049 free(mapping_ID);
00050 free(entity_overrides);
00051 free(grfid_overrides);
00052 }
00053
00061 void OverrideManagerBase::Add(uint8 local_id, uint32 grfid, uint entity_type)
00062 {
00063 assert(entity_type < max_offset);
00064
00065 if (entity_overrides[entity_type] != invalid_ID) return;
00066 entity_overrides[entity_type] = local_id;
00067 grfid_overrides[entity_type] = grfid;
00068 }
00069
00071 void OverrideManagerBase::ResetMapping()
00072 {
00073 memset(mapping_ID, 0, (max_new_entities - 1) * sizeof(EntityIDMapping));
00074 }
00075
00077 void OverrideManagerBase::ResetOverride()
00078 {
00079 for (uint16 i = 0; i < max_offset; i++) {
00080 entity_overrides[i] = invalid_ID;
00081 grfid_overrides[i] = 0;
00082 }
00083 }
00084
00090 uint16 OverrideManagerBase::GetID(uint8 grf_local_id, uint32 grfid)
00091 {
00092 const EntityIDMapping *map;
00093
00094 for (uint16 id = 0; id < max_new_entities; id++) {
00095 map = &mapping_ID[id];
00096 if (map->entity_id == grf_local_id && map->grfid == grfid) {
00097 return id;
00098 }
00099 }
00100
00101 return invalid_ID;
00102 }
00103
00110 uint16 OverrideManagerBase::AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id)
00111 {
00112 uint16 id = this->GetID(grf_local_id, grfid);
00113 EntityIDMapping *map;
00114
00115
00116
00117
00118
00119 if (id != invalid_ID) {
00120 return id;
00121 }
00122
00123
00124 for (id = max_offset; id < max_new_entities; id++) {
00125 map = &mapping_ID[id];
00126
00127 if (CheckValidNewID(id) && map->entity_id == 0 && map->grfid == 0) {
00128 map->entity_id = grf_local_id;
00129 map->grfid = grfid;
00130 map->substitute_id = substitute_id;
00131 return id;
00132 }
00133 }
00134
00135 return invalid_ID;
00136 }
00137
00142 uint16 OverrideManagerBase::GetSubstituteID(uint16 entity_id)
00143 {
00144 return mapping_ID[entity_id].substitute_id;
00145 }
00146
00151 void HouseOverrideManager::SetEntitySpec(const HouseSpec *hs)
00152 {
00153 HouseID house_id = this->AddEntityID(hs->local_id, hs->grffile->grfid, hs->substitute_id);
00154
00155 if (house_id == invalid_ID) {
00156 grfmsg(1, "House.SetEntitySpec: Too many houses allocated. Ignoring.");
00157 return;
00158 }
00159
00160 MemCpyT(HouseSpec::Get(house_id), hs);
00161
00162
00163 for (int i = 0; i != max_offset; i++) {
00164 HouseSpec *overridden_hs = HouseSpec::Get(i);
00165
00166 if (entity_overrides[i] != hs->local_id || grfid_overrides[i] != hs->grffile->grfid) continue;
00167
00168 overridden_hs->override = house_id;
00169 entity_overrides[i] = invalid_ID;
00170 grfid_overrides[i] = 0;
00171 }
00172 }
00173
00179 uint16 IndustryOverrideManager::GetID(uint8 grf_local_id, uint32 grfid)
00180 {
00181 uint16 id = OverrideManagerBase::GetID(grf_local_id, grfid);
00182 if (id != invalid_ID) return id;
00183
00184
00185 for (id = 0; id < max_offset; id++) {
00186 if (entity_overrides[id] == grf_local_id && grfid_overrides[id] == grfid) return id;
00187 }
00188
00189 return invalid_ID;
00190 }
00191
00198 uint16 IndustryOverrideManager::AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id)
00199 {
00200
00201 for (uint16 id = 0; id < max_new_entities; id++) {
00202
00203 if (id < max_offset && entity_overrides[id] != invalid_ID) continue;
00204
00205
00206 const IndustrySpec *inds = GetIndustrySpec(id);
00207
00208
00209
00210
00211 if (!inds->enabled && inds->grf_prop.grffile == NULL) {
00212 EntityIDMapping *map = &mapping_ID[id];
00213
00214 if (map->entity_id == 0 && map->grfid == 0) {
00215
00216 map->entity_id = grf_local_id;
00217 map->grfid = grfid;
00218 map->substitute_id = substitute_id;
00219 return id;
00220 }
00221 }
00222 }
00223
00224 return invalid_ID;
00225 }
00226
00232 void IndustryOverrideManager::SetEntitySpec(IndustrySpec *inds)
00233 {
00234
00235 IndustryType ind_id = this->GetID(inds->grf_prop.local_id, inds->grf_prop.grffile->grfid);
00236
00237 if (ind_id == invalid_ID) {
00238
00239
00240
00241
00242 ind_id = this->AddEntityID(inds->grf_prop.local_id, inds->grf_prop.grffile->grfid, inds->grf_prop.subst_id);
00243 inds->grf_prop.override = invalid_ID;
00244 }
00245
00246 if (ind_id == invalid_ID) {
00247 grfmsg(1, "Industry.SetEntitySpec: Too many industries allocated. Ignoring.");
00248 return;
00249 }
00250
00251
00252 memcpy(&_industry_specs[ind_id], inds, sizeof(*inds));
00253
00254 _industry_specs[ind_id].enabled = true;
00255 }
00256
00257 void IndustryTileOverrideManager::SetEntitySpec(const IndustryTileSpec *its)
00258 {
00259 IndustryGfx indt_id = this->AddEntityID(its->grf_prop.local_id, its->grf_prop.grffile->grfid, its->grf_prop.subst_id);
00260
00261 if (indt_id == invalid_ID) {
00262 grfmsg(1, "IndustryTile.SetEntitySpec: Too many industry tiles allocated. Ignoring.");
00263 return;
00264 }
00265
00266 memcpy(&_industry_tile_specs[indt_id], its, sizeof(*its));
00267
00268
00269 for (int i = 0; i < max_offset; i++) {
00270 IndustryTileSpec *overridden_its = &_industry_tile_specs[i];
00271
00272 if (entity_overrides[i] != its->grf_prop.local_id || grfid_overrides[i] != its->grf_prop.grffile->grfid) continue;
00273
00274 overridden_its->grf_prop.override = indt_id;
00275 overridden_its->enabled = false;
00276 entity_overrides[i] = invalid_ID;
00277 grfid_overrides[i] = 0;
00278 }
00279 }
00280
00287 uint32 GetTerrainType(TileIndex tile, TileContext context)
00288 {
00289 switch (_settings_game.game_creation.landscape) {
00290 case LT_TROPIC: return GetTropicZone(tile);
00291 case LT_ARCTIC: {
00292 bool has_snow;
00293 switch (GetTileType(tile)) {
00294 case MP_CLEAR:
00295
00296 if (_generating_world) goto genworld;
00297 has_snow = IsSnowTile(tile) && GetClearDensity(tile) >= 2;
00298 break;
00299
00300 case MP_RAILWAY: {
00301
00302 if (_generating_world) goto genworld;
00303 RailGroundType ground = GetRailGroundType(tile);
00304 has_snow = (ground == RAIL_GROUND_ICE_DESERT || (context == TCX_UPPER_HALFTILE && ground == RAIL_GROUND_HALF_SNOW));
00305 break;
00306 }
00307
00308 case MP_ROAD:
00309
00310 if (_generating_world) goto genworld;
00311 has_snow = IsOnSnow(tile);
00312 break;
00313
00314 case MP_TREES: {
00315
00316 if (_generating_world) goto genworld;
00317 TreeGround ground = GetTreeGround(tile);
00318 has_snow = (ground == TREE_GROUND_SNOW_DESERT || ground == TREE_GROUND_ROUGH_SNOW) && GetTreeDensity(tile) >= 2;
00319 break;
00320 }
00321
00322 case MP_TUNNELBRIDGE:
00323 if (context == TCX_ON_BRIDGE) {
00324 has_snow = (GetBridgeHeight(tile) > GetSnowLine());
00325 } else {
00326
00327 if (_generating_world) goto genworld;
00328 has_snow = HasTunnelBridgeSnowOrDesert(tile);
00329 }
00330 break;
00331
00332 case MP_STATION:
00333 case MP_HOUSE:
00334 case MP_INDUSTRY:
00335 case MP_UNMOVABLE:
00336
00337 has_snow = (GetTileMaxZ(tile) > GetSnowLine());
00338 break;
00339
00340 case MP_VOID:
00341 case MP_WATER:
00342 genworld:
00343 has_snow = (GetTileZ(tile) > GetSnowLine());
00344 break;
00345
00346 default: NOT_REACHED();
00347 }
00348 return has_snow ? 4 : 0;
00349 }
00350 default: return 0;
00351 }
00352 }
00353
00354 TileIndex GetNearbyTile(byte parameter, TileIndex tile)
00355 {
00356 int8 x = GB(parameter, 0, 4);
00357 int8 y = GB(parameter, 4, 4);
00358
00359 if (x >= 8) x -= 16;
00360 if (y >= 8) y -= 16;
00361
00362
00363 if (HasStationTileRail(tile) && GetRailStationAxis(tile) == AXIS_Y) Swap(x, y);
00364
00365
00366 return TILE_MASK(tile + TileDiffXY(x, y));
00367 }
00368
00375 uint32 GetNearbyTileInformation(TileIndex tile)
00376 {
00377 TileType tile_type = GetTileType(tile);
00378
00379
00380 if (IsTileType(tile, MP_TREES) && GetTreeGround(tile) == TREE_GROUND_SHORE) tile_type = MP_WATER;
00381
00382 uint z;
00383 Slope tileh = GetTileSlope(tile, &z);
00384 byte terrain_type = GetTerrainType(tile) << 2 | (tile_type == MP_WATER ? 1 : 0) << 1;
00385 return tile_type << 24 | z << 16 | terrain_type << 8 | tileh;
00386 }