newgrf_commons.cpp
Go to the documentation of this file.00001
00002
00007 #include "stdafx.h"
00008 #include "openttd.h"
00009 #include "variables.h"
00010 #include "landscape.h"
00011 #include "town.h"
00012 #include "industry.h"
00013 #include "newgrf.h"
00014 #include "newgrf_commons.h"
00015 #include "tile_map.h"
00016 #include "station_map.h"
00017 #include "settings_type.h"
00018 #include "tree_map.h"
00019
00025 OverrideManagerBase::OverrideManagerBase(uint16 offset, uint16 maximum, uint16 invalid)
00026 {
00027 max_offset = offset;
00028 max_new_entities = maximum;
00029 invalid_ID = invalid;
00030
00031 mapping_ID = CallocT<EntityIDMapping>(max_new_entities);
00032 entity_overrides = MallocT<uint16>(max_offset);
00033 memset(entity_overrides, invalid, sizeof(entity_overrides));
00034 grfid_overrides = CallocT<uint32>(max_offset);
00035 }
00036
00040 OverrideManagerBase::~OverrideManagerBase()
00041 {
00042 free(mapping_ID);
00043 free(entity_overrides);
00044 free(grfid_overrides);
00045 }
00046
00054 void OverrideManagerBase::Add(uint8 local_id, uint32 grfid, uint entity_type)
00055 {
00056 assert(entity_type < max_offset);
00057
00058 if (entity_overrides[entity_type] != invalid_ID) return;
00059 entity_overrides[entity_type] = local_id;
00060 grfid_overrides[entity_type] = grfid;
00061 }
00062
00064 void OverrideManagerBase::ResetMapping()
00065 {
00066 memset(mapping_ID, 0, (max_new_entities - 1) * sizeof(EntityIDMapping));
00067 }
00068
00070 void OverrideManagerBase::ResetOverride()
00071 {
00072 for (uint16 i = 0; i < max_offset; i++) {
00073 entity_overrides[i] = invalid_ID;
00074 grfid_overrides[i] = 0;
00075 }
00076 }
00077
00083 uint16 OverrideManagerBase::GetID(uint8 grf_local_id, uint32 grfid)
00084 {
00085 const EntityIDMapping *map;
00086
00087 for (uint16 id = 0; id < max_new_entities; id++) {
00088 map = &mapping_ID[id];
00089 if (map->entity_id == grf_local_id && map->grfid == grfid) {
00090 return id;
00091 }
00092 }
00093
00094 return invalid_ID;
00095 }
00096
00103 uint16 OverrideManagerBase::AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id)
00104 {
00105 uint16 id = this->GetID(grf_local_id, grfid);
00106 EntityIDMapping *map;
00107
00108
00109
00110
00111
00112 if (id != invalid_ID) {
00113 return id;
00114 }
00115
00116
00117 for (id = max_offset; id < max_new_entities; id++) {
00118 map = &mapping_ID[id];
00119
00120 if (CheckValidNewID(id) && map->entity_id == 0 && map->grfid == 0) {
00121 map->entity_id = grf_local_id;
00122 map->grfid = grfid;
00123 map->substitute_id = substitute_id;
00124 return id;
00125 }
00126 }
00127
00128 return invalid_ID;
00129 }
00130
00135 uint16 OverrideManagerBase::GetSubstituteID(byte entity_id)
00136 {
00137 return mapping_ID[entity_id].substitute_id;
00138 }
00139
00144 void HouseOverrideManager::SetEntitySpec(const HouseSpec *hs)
00145 {
00146 HouseID house_id = this->AddEntityID(hs->local_id, hs->grffile->grfid, hs->substitute_id);
00147
00148 if (house_id == invalid_ID) {
00149 grfmsg(1, "House.SetEntitySpec: Too many houses allocated. Ignoring.");
00150 return;
00151 }
00152
00153 memcpy(&_house_specs[house_id], hs, sizeof(*hs));
00154
00155
00156 for (int i = 0; i != max_offset; i++) {
00157 HouseSpec *overridden_hs = GetHouseSpecs(i);
00158
00159 if (entity_overrides[i] != hs->local_id || grfid_overrides[i] != hs->grffile->grfid) continue;
00160
00161 overridden_hs->override = house_id;
00162 entity_overrides[i] = invalid_ID;
00163 grfid_overrides[i] = 0;
00164 }
00165 }
00166
00172 uint16 IndustryOverrideManager::GetID(uint8 grf_local_id, uint32 grfid)
00173 {
00174 uint16 id = OverrideManagerBase::GetID(grf_local_id, grfid);
00175 if (id != invalid_ID) return id;
00176
00177
00178 for (id = 0; id < max_offset; id++) {
00179 if (entity_overrides[id] == grf_local_id && grfid_overrides[id] == grfid) return id;
00180 }
00181
00182 return invalid_ID;
00183 }
00184
00191 uint16 IndustryOverrideManager::AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id)
00192 {
00193
00194 for (uint16 id = 0; id < max_new_entities; id++) {
00195
00196 if (id < max_offset && entity_overrides[id] != invalid_ID) continue;
00197
00198
00199 const IndustrySpec *inds = GetIndustrySpec(id);
00200
00201
00202
00203
00204 if (!inds->enabled && inds->grf_prop.grffile == NULL) {
00205 EntityIDMapping *map = &mapping_ID[id];
00206
00207 if (map->entity_id == 0 && map->grfid == 0) {
00208
00209 map->entity_id = grf_local_id;
00210 map->grfid = grfid;
00211 map->substitute_id = substitute_id;
00212 return id;
00213 }
00214 }
00215 }
00216
00217 return invalid_ID;
00218 }
00219
00225 void IndustryOverrideManager::SetEntitySpec(IndustrySpec *inds)
00226 {
00227
00228 IndustryType ind_id = this->GetID(inds->grf_prop.local_id, inds->grf_prop.grffile->grfid);
00229
00230 if (ind_id == invalid_ID) {
00231
00232
00233
00234
00235 ind_id = this->AddEntityID(inds->grf_prop.local_id, inds->grf_prop.grffile->grfid, inds->grf_prop.subst_id);
00236 inds->grf_prop.override = invalid_ID;
00237 }
00238
00239 if (ind_id == invalid_ID) {
00240 grfmsg(1, "Industry.SetEntitySpec: Too many industries allocated. Ignoring.");
00241 return;
00242 }
00243
00244
00245 memcpy(&_industry_specs[ind_id], inds, sizeof(*inds));
00246
00247 _industry_specs[ind_id].enabled = true;
00248 }
00249
00250 void IndustryTileOverrideManager::SetEntitySpec(const IndustryTileSpec *its)
00251 {
00252 IndustryGfx indt_id = this->AddEntityID(its->grf_prop.local_id, its->grf_prop.grffile->grfid, its->grf_prop.subst_id);
00253
00254 if (indt_id == invalid_ID) {
00255 grfmsg(1, "IndustryTile.SetEntitySpec: Too many industry tiles allocated. Ignoring.");
00256 return;
00257 }
00258
00259 memcpy(&_industry_tile_specs[indt_id], its, sizeof(*its));
00260
00261
00262 for (int i = 0; i < max_offset; i++) {
00263 IndustryTileSpec *overridden_its = &_industry_tile_specs[i];
00264
00265 if (entity_overrides[i] != its->grf_prop.local_id || grfid_overrides[i] != its->grf_prop.grffile->grfid) continue;
00266
00267 overridden_its->grf_prop.override = indt_id;
00268 overridden_its->enabled = false;
00269 entity_overrides[i] = invalid_ID;
00270 grfid_overrides[i] = 0;
00271 }
00272 }
00273
00279 uint32 GetTerrainType(TileIndex tile)
00280 {
00281 switch (_opt.landscape) {
00282 case LT_TROPIC: return GetTropicZone(tile);
00283 case LT_ARCTIC: return GetTileZ(tile) > GetSnowLine() ? 4 : 0;
00284 default: return 0;
00285 }
00286 }
00287
00288 TileIndex GetNearbyTile(byte parameter, TileIndex tile)
00289 {
00290 int8 x = GB(parameter, 0, 4);
00291 int8 y = GB(parameter, 4, 4);
00292
00293 if (x >= 8) x -= 16;
00294 if (y >= 8) y -= 16;
00295
00296
00297 if (IsRailwayStationTile(tile) && GetRailStationAxis(tile) == AXIS_Y) Swap(x, y);
00298
00299
00300 return TILE_MASK(tile + TileDiffXY(x, y));
00301 }
00302
00309 uint32 GetNearbyTileInformation(TileIndex tile)
00310 {
00311 TileType tile_type = GetTileType(tile);
00312
00313
00314 if (IsTileType(tile, MP_TREES) && GetTreeGround(tile) == TREE_GROUND_SHORE) tile_type = MP_WATER;
00315
00316 uint z;
00317 Slope tileh = GetTileSlope(tile, &z);
00318 byte terrain_type = GetTerrainType(tile) << 2 | (tile_type == MP_WATER ? 1 : 0) << 1;
00319 return tile_type << 24 | z << 16 | terrain_type << 8 | tileh;
00320 }