00001
00002
00003
00004
00005
00006
00007
00008
00009
00015 #include "stdafx.h"
00016 #include "landscape.h"
00017 #include "house.h"
00018 #include "industrytype.h"
00019 #include "newgrf.h"
00020 #include "clear_map.h"
00021 #include "station_map.h"
00022 #include "tree_map.h"
00023 #include "tunnelbridge_map.h"
00024 #include "newgrf_object.h"
00025 #include "genworld.h"
00026 #include "core/mem_func.hpp"
00027
00034 OverrideManagerBase::OverrideManagerBase(uint16 offset, uint16 maximum, uint16 invalid)
00035 {
00036 max_offset = offset;
00037 max_new_entities = maximum;
00038 invalid_ID = invalid;
00039
00040 mapping_ID = CallocT<EntityIDMapping>(max_new_entities);
00041 entity_overrides = MallocT<uint16>(max_offset);
00042 for (size_t i = 0; i < max_offset; i++) entity_overrides[i] = invalid;
00043 grfid_overrides = CallocT<uint32>(max_offset);
00044 }
00045
00050 OverrideManagerBase::~OverrideManagerBase()
00051 {
00052 free(mapping_ID);
00053 free(entity_overrides);
00054 free(grfid_overrides);
00055 }
00056
00065 void OverrideManagerBase::Add(uint8 local_id, uint32 grfid, uint entity_type)
00066 {
00067 assert(entity_type < max_offset);
00068
00069 if (entity_overrides[entity_type] != invalid_ID) return;
00070 entity_overrides[entity_type] = local_id;
00071 grfid_overrides[entity_type] = grfid;
00072 }
00073
00075 void OverrideManagerBase::ResetMapping()
00076 {
00077 memset(mapping_ID, 0, (max_new_entities - 1) * sizeof(EntityIDMapping));
00078 }
00079
00081 void OverrideManagerBase::ResetOverride()
00082 {
00083 for (uint16 i = 0; i < max_offset; i++) {
00084 entity_overrides[i] = invalid_ID;
00085 grfid_overrides[i] = 0;
00086 }
00087 }
00088
00095 uint16 OverrideManagerBase::GetID(uint8 grf_local_id, uint32 grfid) const
00096 {
00097 const EntityIDMapping *map;
00098
00099 for (uint16 id = 0; id < max_new_entities; id++) {
00100 map = &mapping_ID[id];
00101 if (map->entity_id == grf_local_id && map->grfid == grfid) {
00102 return id;
00103 }
00104 }
00105
00106 return invalid_ID;
00107 }
00108
00116 uint16 OverrideManagerBase::AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id)
00117 {
00118 uint16 id = this->GetID(grf_local_id, grfid);
00119 EntityIDMapping *map;
00120
00121
00122
00123
00124
00125 if (id != invalid_ID) {
00126 return id;
00127 }
00128
00129
00130 for (id = max_offset; id < max_new_entities; id++) {
00131 map = &mapping_ID[id];
00132
00133 if (CheckValidNewID(id) && map->entity_id == 0 && map->grfid == 0) {
00134 map->entity_id = grf_local_id;
00135 map->grfid = grfid;
00136 map->substitute_id = substitute_id;
00137 return id;
00138 }
00139 }
00140
00141 return invalid_ID;
00142 }
00143
00149 uint16 OverrideManagerBase::GetSubstituteID(uint16 entity_id) const
00150 {
00151 return mapping_ID[entity_id].substitute_id;
00152 }
00153
00159 void HouseOverrideManager::SetEntitySpec(const HouseSpec *hs)
00160 {
00161 HouseID house_id = this->AddEntityID(hs->grf_prop.local_id, hs->grf_prop.grffile->grfid, hs->grf_prop.subst_id);
00162
00163 if (house_id == invalid_ID) {
00164 grfmsg(1, "House.SetEntitySpec: Too many houses allocated. Ignoring.");
00165 return;
00166 }
00167
00168 MemCpyT(HouseSpec::Get(house_id), hs);
00169
00170
00171 for (int i = 0; i != max_offset; i++) {
00172 HouseSpec *overridden_hs = HouseSpec::Get(i);
00173
00174 if (entity_overrides[i] != hs->grf_prop.local_id || grfid_overrides[i] != hs->grf_prop.grffile->grfid) continue;
00175
00176 overridden_hs->grf_prop.override = house_id;
00177 entity_overrides[i] = invalid_ID;
00178 grfid_overrides[i] = 0;
00179 }
00180 }
00181
00188 uint16 IndustryOverrideManager::GetID(uint8 grf_local_id, uint32 grfid) const
00189 {
00190 uint16 id = OverrideManagerBase::GetID(grf_local_id, grfid);
00191 if (id != invalid_ID) return id;
00192
00193
00194 for (id = 0; id < max_offset; id++) {
00195 if (entity_overrides[id] == grf_local_id && grfid_overrides[id] == grfid) return id;
00196 }
00197
00198 return invalid_ID;
00199 }
00200
00208 uint16 IndustryOverrideManager::AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id)
00209 {
00210
00211 for (uint16 id = 0; id < max_new_entities; id++) {
00212
00213 if (id < max_offset && entity_overrides[id] != invalid_ID) continue;
00214
00215
00216 const IndustrySpec *inds = GetIndustrySpec(id);
00217
00218
00219
00220
00221 if (!inds->enabled && inds->grf_prop.grffile == NULL) {
00222 EntityIDMapping *map = &mapping_ID[id];
00223
00224 if (map->entity_id == 0 && map->grfid == 0) {
00225
00226 map->entity_id = grf_local_id;
00227 map->grfid = grfid;
00228 map->substitute_id = substitute_id;
00229 return id;
00230 }
00231 }
00232 }
00233
00234 return invalid_ID;
00235 }
00236
00243 void IndustryOverrideManager::SetEntitySpec(IndustrySpec *inds)
00244 {
00245
00246 IndustryType ind_id = this->GetID(inds->grf_prop.local_id, inds->grf_prop.grffile->grfid);
00247
00248 if (ind_id == invalid_ID) {
00249
00250
00251
00252
00253 ind_id = this->AddEntityID(inds->grf_prop.local_id, inds->grf_prop.grffile->grfid, inds->grf_prop.subst_id);
00254 inds->grf_prop.override = invalid_ID;
00255 }
00256
00257 if (ind_id == invalid_ID) {
00258 grfmsg(1, "Industry.SetEntitySpec: Too many industries allocated. Ignoring.");
00259 return;
00260 }
00261
00262
00263 memcpy(&_industry_specs[ind_id], inds, sizeof(*inds));
00264
00265 _industry_specs[ind_id].enabled = true;
00266 }
00267
00268 void IndustryTileOverrideManager::SetEntitySpec(const IndustryTileSpec *its)
00269 {
00270 IndustryGfx indt_id = this->AddEntityID(its->grf_prop.local_id, its->grf_prop.grffile->grfid, its->grf_prop.subst_id);
00271
00272 if (indt_id == invalid_ID) {
00273 grfmsg(1, "IndustryTile.SetEntitySpec: Too many industry tiles allocated. Ignoring.");
00274 return;
00275 }
00276
00277 memcpy(&_industry_tile_specs[indt_id], its, sizeof(*its));
00278
00279
00280 for (int i = 0; i < max_offset; i++) {
00281 IndustryTileSpec *overridden_its = &_industry_tile_specs[i];
00282
00283 if (entity_overrides[i] != its->grf_prop.local_id || grfid_overrides[i] != its->grf_prop.grffile->grfid) continue;
00284
00285 overridden_its->grf_prop.override = indt_id;
00286 overridden_its->enabled = false;
00287 entity_overrides[i] = invalid_ID;
00288 grfid_overrides[i] = 0;
00289 }
00290 }
00291
00298 void ObjectOverrideManager::SetEntitySpec(ObjectSpec *spec)
00299 {
00300
00301 ObjectType type = this->GetID(spec->grf_prop.local_id, spec->grf_prop.grffile->grfid);
00302
00303 if (type == invalid_ID) {
00304
00305
00306
00307
00308 type = this->AddEntityID(spec->grf_prop.local_id, spec->grf_prop.grffile->grfid, OBJECT_TRANSMITTER);
00309 }
00310
00311 if (type == invalid_ID) {
00312 grfmsg(1, "Object.SetEntitySpec: Too many objects allocated. Ignoring.");
00313 return;
00314 }
00315
00316 extern ObjectSpec _object_specs[NUM_OBJECTS];
00317
00318
00319 memcpy(&_object_specs[type], spec, sizeof(*spec));
00320 ObjectClass::Assign(&_object_specs[type]);
00321 }
00322
00331 uint32 GetTerrainType(TileIndex tile, TileContext context)
00332 {
00333 switch (_settings_game.game_creation.landscape) {
00334 case LT_TROPIC: return GetTropicZone(tile);
00335 case LT_ARCTIC: {
00336 bool has_snow;
00337 switch (GetTileType(tile)) {
00338 case MP_CLEAR:
00339
00340 if (_generating_world) goto genworld;
00341 has_snow = IsSnowTile(tile) && GetClearDensity(tile) >= 2;
00342 break;
00343
00344 case MP_RAILWAY: {
00345
00346 if (_generating_world) goto genworld;
00347 RailGroundType ground = GetRailGroundType(tile);
00348 has_snow = (ground == RAIL_GROUND_ICE_DESERT || (context == TCX_UPPER_HALFTILE && ground == RAIL_GROUND_HALF_SNOW));
00349 break;
00350 }
00351
00352 case MP_ROAD:
00353
00354 if (_generating_world) goto genworld;
00355 has_snow = IsOnSnow(tile);
00356 break;
00357
00358 case MP_TREES: {
00359
00360 if (_generating_world) goto genworld;
00361 TreeGround ground = GetTreeGround(tile);
00362 has_snow = (ground == TREE_GROUND_SNOW_DESERT || ground == TREE_GROUND_ROUGH_SNOW) && GetTreeDensity(tile) >= 2;
00363 break;
00364 }
00365
00366 case MP_TUNNELBRIDGE:
00367 if (context == TCX_ON_BRIDGE) {
00368 has_snow = (GetBridgeHeight(tile) > GetSnowLine());
00369 } else {
00370
00371 if (_generating_world) goto genworld;
00372 has_snow = HasTunnelBridgeSnowOrDesert(tile);
00373 }
00374 break;
00375
00376 case MP_STATION:
00377 case MP_HOUSE:
00378 case MP_INDUSTRY:
00379 case MP_OBJECT:
00380
00381 has_snow = (GetTileMaxZ(tile) > GetSnowLine());
00382 break;
00383
00384 case MP_VOID:
00385 case MP_WATER:
00386 genworld:
00387 has_snow = (GetTileZ(tile) > GetSnowLine());
00388 break;
00389
00390 default: NOT_REACHED();
00391 }
00392 return has_snow ? 4 : 0;
00393 }
00394 default: return 0;
00395 }
00396 }
00397
00398 TileIndex GetNearbyTile(byte parameter, TileIndex tile, bool signed_offsets)
00399 {
00400 int8 x = GB(parameter, 0, 4);
00401 int8 y = GB(parameter, 4, 4);
00402
00403 if (signed_offsets && x >= 8) x -= 16;
00404 if (signed_offsets && y >= 8) y -= 16;
00405
00406
00407 if (HasStationTileRail(tile) && GetRailStationAxis(tile) == AXIS_Y) Swap(x, y);
00408
00409
00410 return TILE_MASK(tile + TileDiffXY(x, y));
00411 }
00412
00419 uint32 GetNearbyTileInformation(TileIndex tile)
00420 {
00421 TileType tile_type = GetTileType(tile);
00422
00423
00424 if (IsTileType(tile, MP_TREES) && GetTreeGround(tile) == TREE_GROUND_SHORE) tile_type = MP_WATER;
00425
00426 uint z;
00427 Slope tileh = GetTileSlope(tile, &z);
00428 byte terrain_type = GetTerrainType(tile) << 2 | (tile_type == MP_WATER ? 1 : 0) << 1;
00429 return tile_type << 24 | z << 16 | terrain_type << 8 | tileh;
00430 }