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 "newgrf_spritegroup.h"
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
00405 TileIndex GetNearbyTile(byte parameter, TileIndex tile, bool signed_offsets)
00406 {
00407 int8 x = GB(parameter, 0, 4);
00408 int8 y = GB(parameter, 4, 4);
00409
00410 if (signed_offsets && x >= 8) x -= 16;
00411 if (signed_offsets && y >= 8) y -= 16;
00412
00413
00414 if (HasStationTileRail(tile) && GetRailStationAxis(tile) == AXIS_Y) Swap(x, y);
00415
00416
00417 return TILE_MASK(tile + TileDiffXY(x, y));
00418 }
00419
00426 uint32 GetNearbyTileInformation(TileIndex tile)
00427 {
00428 TileType tile_type = GetTileType(tile);
00429
00430
00431 if (IsTileType(tile, MP_TREES) && GetTreeGround(tile) == TREE_GROUND_SHORE) tile_type = MP_WATER;
00432
00433 uint z;
00434 Slope tileh = GetTileSlope(tile, &z);
00435 byte terrain_type = GetTerrainType(tile) << 2 | (tile_type == MP_WATER ? 1 : 0) << 1;
00436 return tile_type << 24 | z << 16 | terrain_type << 8 | tileh;
00437 }
00438
00439 SmallVector<DrawTileSeqStruct, 8> NewGRFSpriteLayout::result_seq;
00440
00445 void NewGRFSpriteLayout::Clone(const DrawTileSeqStruct *source)
00446 {
00447 assert(this->seq == NULL);
00448 assert(source != NULL);
00449
00450 size_t count = 1;
00451 const DrawTileSeqStruct *element;
00452 foreach_draw_tile_seq(element, source) count++;
00453
00454 DrawTileSeqStruct *sprites = MallocT<DrawTileSeqStruct>(count);
00455 MemCpyT(sprites, source, count);
00456 this->seq = sprites;
00457 }
00458
00463 void NewGRFSpriteLayout::Clone(const NewGRFSpriteLayout *source)
00464 {
00465 this->Clone((const DrawTileSprites*)source);
00466
00467 if (source->registers != NULL) {
00468 size_t count = 1;
00469 const DrawTileSeqStruct *element;
00470 foreach_draw_tile_seq(element, source->seq) count++;
00471
00472 TileLayoutRegisters *regs = MallocT<TileLayoutRegisters>(count);
00473 MemCpyT(regs, source->registers, count);
00474 this->registers = regs;
00475 }
00476 }
00477
00478
00483 void NewGRFSpriteLayout::Allocate(uint num_sprites)
00484 {
00485 assert(this->seq == NULL);
00486
00487 DrawTileSeqStruct *sprites = CallocT<DrawTileSeqStruct>(num_sprites + 1);
00488 sprites[num_sprites].MakeTerminator();
00489 this->seq = sprites;
00490 }
00491
00495 void NewGRFSpriteLayout::AllocateRegisters()
00496 {
00497 assert(this->seq != NULL);
00498 assert(this->registers == NULL);
00499
00500 size_t count = 1;
00501 const DrawTileSeqStruct *element;
00502 foreach_draw_tile_seq(element, this->seq) count++;
00503
00504 this->registers = CallocT<TileLayoutRegisters>(count);
00505 }
00506
00518 uint32 NewGRFSpriteLayout::PrepareLayout(uint32 orig_offset, uint32 newgrf_ground_offset, uint32 newgrf_offset, bool separate_ground) const
00519 {
00520 result_seq.Clear();
00521 uint32 var10_values = 0;
00522
00523
00524
00525 DrawTileSeqStruct *result = result_seq.Append();
00526 result->image = ground;
00527 result->delta_x = 0;
00528 result->delta_y = 0;
00529 result->delta_z = 0x80;
00530
00531 const DrawTileSeqStruct *dtss;
00532 foreach_draw_tile_seq(dtss, this->seq) {
00533 *result_seq.Append() = *dtss;
00534 }
00535 result_seq.Append()->MakeTerminator();
00536
00537
00538
00539 const TileLayoutRegisters *regs = this->registers;
00540 bool ground = true;
00541 foreach_draw_tile_seq(result, result_seq.Begin()) {
00542 TileLayoutFlags flags = TLF_NOTHING;
00543 if (regs != NULL) flags = regs->flags;
00544
00545
00546 if (HasBit(result->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE) || (flags & TLF_SPRITE_REG_FLAGS)) {
00547 uint8 var10 = (flags & TLF_SPRITE_VAR10) ? regs->sprite_var10 : (ground && separate_ground ? 1 : 0);
00548 SetBit(var10_values, var10);
00549 }
00550
00551
00552 if (!(flags & TLF_SPRITE)) {
00553 if (HasBit(result->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE)) {
00554 result->image.sprite += ground ? newgrf_ground_offset : newgrf_offset;
00555 } else {
00556 result->image.sprite += orig_offset;
00557 }
00558 }
00559
00560
00561 if (HasBit(result->image.pal, SPRITE_MODIFIER_CUSTOM_SPRITE) || (flags & TLF_PALETTE_REG_FLAGS)) {
00562 uint8 var10 = (flags & TLF_PALETTE_VAR10) ? regs->palette_var10 : (ground && separate_ground ? 1 : 0);
00563 SetBit(var10_values, var10);
00564 }
00565
00566
00567 if (!(flags & TLF_PALETTE)) {
00568 if (HasBit(result->image.pal, SPRITE_MODIFIER_CUSTOM_SPRITE)) {
00569 result->image.sprite += ground ? newgrf_ground_offset : newgrf_offset;
00570 }
00571 }
00572
00573 ground = false;
00574 if (regs != NULL) regs++;
00575 }
00576
00577 return var10_values;
00578 }
00579
00588 void NewGRFSpriteLayout::ProcessRegisters(uint8 resolved_var10, uint32 resolved_sprite, bool separate_ground) const
00589 {
00590 DrawTileSeqStruct *result;
00591 const TileLayoutRegisters *regs = this->registers;
00592 bool ground = true;
00593 foreach_draw_tile_seq(result, result_seq.Begin()) {
00594 TileLayoutFlags flags = TLF_NOTHING;
00595 if (regs != NULL) flags = regs->flags;
00596
00597
00598 if (HasBit(result->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE) || (flags & TLF_SPRITE_REG_FLAGS)) {
00599
00600 uint8 var10 = (flags & TLF_SPRITE_VAR10) ? regs->sprite_var10 : (ground && separate_ground ? 1 : 0);
00601 if (var10 == resolved_var10) {
00602
00603 if ((flags & TLF_DODRAW) && GetRegister(regs->dodraw) == 0) {
00604 result->image.sprite = 0;
00605 continue;
00606 }
00607 if (HasBit(result->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE)) result->image.sprite += resolved_sprite;
00608 if (flags & TLF_SPRITE) result->image.sprite += (int16)GetRegister(regs->sprite);
00609
00610 if (result->IsParentSprite()) {
00611 if (flags & TLF_BB_XY_OFFSET) {
00612 result->delta_x += (int32)GetRegister(regs->delta.parent[0]);
00613 result->delta_y += (int32)GetRegister(regs->delta.parent[1]);
00614 }
00615 if (flags & TLF_BB_Z_OFFSET) result->delta_z += (int32)GetRegister(regs->delta.parent[2]);
00616 } else {
00617 if (flags & TLF_CHILD_X_OFFSET) result->delta_x += (int32)GetRegister(regs->delta.child[0]);
00618 if (flags & TLF_CHILD_Y_OFFSET) result->delta_y += (int32)GetRegister(regs->delta.child[1]);
00619 }
00620 }
00621 }
00622
00623
00624 if (HasBit(result->image.pal, SPRITE_MODIFIER_CUSTOM_SPRITE) || (flags & TLF_PALETTE_REG_FLAGS)) {
00625
00626 uint8 var10 = (flags & TLF_PALETTE_VAR10) ? regs->palette_var10 : (ground && separate_ground ? 1 : 0);
00627 if (var10 == resolved_var10) {
00628
00629 if (HasBit(result->image.pal, SPRITE_MODIFIER_CUSTOM_SPRITE)) result->image.pal += resolved_sprite;
00630 if (flags & TLF_PALETTE) result->image.pal += (int16)GetRegister(regs->palette);
00631 }
00632 }
00633
00634 ground = false;
00635 if (regs != NULL) regs++;
00636 }
00637 }