diff --git a/src/newgrf_airporttiles.cpp b/src/newgrf_airporttiles.cpp index 8f4fc836c9..53174cbe96 100644 --- a/src/newgrf_airporttiles.cpp +++ b/src/newgrf_airporttiles.cpp @@ -106,12 +106,14 @@ StationGfx GetTranslatedAirportTileID(StationGfx gfx) * @param grf_version8 True, if we are dealing with a new NewGRF which uses GRF version >= 8. * @return a construction of bits obeying the newgrf format */ -static uint32 GetNearbyAirportTileInformation(byte parameter, TileIndex tile, StationID index, bool grf_version8) +static uint32 GetNearbyAirportTileInformation(byte parameter, TileIndex tile, StationID index, bool grf_version8, uint32 mask) { if (parameter != 0) tile = GetNearbyTile(parameter, tile); // only perform if it is required bool is_same_airport = (IsTileType(tile, MP_STATION) && IsAirport(tile) && GetStationIndex(tile) == index); - return GetNearbyTileInformation(tile, grf_version8) | (is_same_airport ? 1 : 0) << 8; + uint32 result = (is_same_airport ? 1 : 0) << 8; + if (mask & ~0x100) result |= GetNearbyTileInformation(tile, grf_version8, mask); + return result; } @@ -178,7 +180,7 @@ static uint32 GetAirportTileIDAtOffset(TileIndex tile, const Station *st, uint32 case 0x44: return GetAnimationFrame(this->tile); /* Land info of nearby tiles */ - case 0x60: return GetNearbyAirportTileInformation(parameter, this->tile, this->st->index, this->ro.grffile->grf_version >= 8); + case 0x60: return GetNearbyAirportTileInformation(parameter, this->tile, this->st->index, this->ro.grffile->grf_version >= 8, extra->mask); /* Animation stage of nearby tiles */ case 0x61: { diff --git a/src/newgrf_commons.cpp b/src/newgrf_commons.cpp index ee6964dab9..496e011cc5 100644 --- a/src/newgrf_commons.cpp +++ b/src/newgrf_commons.cpp @@ -444,22 +444,33 @@ TileIndex GetNearbyTile(byte parameter, TileIndex tile, bool signed_offsets, Axi * @param grf_version8 True, if we are dealing with a new NewGRF which uses GRF version >= 8. * @return 0czzbbss: c = TileType; zz = TileZ; bb: 7-3 zero, 4-2 TerrainType, 1 water/shore, 0 zero; ss = TileSlope */ -uint32 GetNearbyTileInformation(TileIndex tile, bool grf_version8) +uint32 GetNearbyTileInformation(TileIndex tile, bool grf_version8, uint32 mask) { - TileType tile_type = GetTileType(tile); + uint32 result = 0; + TileType tile_type = MP_CLEAR; + if (mask & 0xFF000200) { + tile_type = GetTileType(tile); - /* Fake tile type for trees on shore */ - if (IsTileType(tile, MP_TREES) && GetTreeGround(tile) == TREE_GROUND_SHORE) tile_type = MP_WATER; + /* Fake tile type for trees on shore */ + if (IsTileType(tile, MP_TREES) && GetTreeGround(tile) == TREE_GROUND_SHORE) tile_type = MP_WATER; - /* Fake tile type for road waypoints */ - if (IsRoadWaypointTile(tile)) tile_type = MP_ROAD; + /* Fake tile type for road waypoints */ + if (IsRoadWaypointTile(tile)) tile_type = MP_ROAD; - int z; - Slope tileh = GetTilePixelSlope(tile, &z); - /* Return 0 if the tile is a land tile */ - byte terrain_type = (HasTileWaterClass(tile) ? (GetWaterClass(tile) + 1) & 3 : 0) << 5 | GetTerrainType(tile) << 2 | (tile_type == MP_WATER ? 1 : 0) << 1; - if (grf_version8) z /= TILE_HEIGHT; - return tile_type << 24 | Clamp(z, 0, 0xFF) << 16 | terrain_type << 8 | tileh; + result |= tile_type << 24; + } + if (mask & 0xFF00) { + /* Return 0 if the tile is a land tile */ + byte terrain_type = (HasTileWaterClass(tile) ? (GetWaterClass(tile) + 1) & 3 : 0) << 5 | GetTerrainType(tile) << 2 | (tile_type == MP_WATER ? 1 : 0) << 1; + result |= terrain_type << 8; + } + if (mask & 0xFF00FF) { + int z; + Slope tileh = GetTilePixelSlope(tile, &z); + if (grf_version8) z /= TILE_HEIGHT; + result |= Clamp(z, 0, 0xFF) << 16 | tileh; + } + return result; } /** diff --git a/src/newgrf_commons.h b/src/newgrf_commons.h index 774ab4a61b..473123da73 100644 --- a/src/newgrf_commons.h +++ b/src/newgrf_commons.h @@ -295,7 +295,7 @@ extern ObjectOverrideManager _object_mngr; uint32 GetTerrainType(TileIndex tile, TileContext context = TCX_NORMAL); TileIndex GetNearbyTile(byte parameter, TileIndex tile, bool signed_offsets = true, Axis axis = INVALID_AXIS); -uint32 GetNearbyTileInformation(TileIndex tile, bool grf_version8); +uint32 GetNearbyTileInformation(TileIndex tile, bool grf_version8, uint32 mask); uint32 GetCompanyInfo(CompanyID owner, const struct Livery *l = nullptr); CommandCost GetErrorMessageFromLocationCallbackResult(uint16 cb_res, const GRFFile *grffile, StringID default_error); diff --git a/src/newgrf_house.cpp b/src/newgrf_house.cpp index 116713bf18..89af0470b1 100644 --- a/src/newgrf_house.cpp +++ b/src/newgrf_house.cpp @@ -202,10 +202,10 @@ static uint32 GetNumHouses(HouseID house_id, const Town *town) * @param grf_version8 True, if we are dealing with a new NewGRF which uses GRF version >= 8. * @return a construction of bits obeying the newgrf format */ -static uint32 GetNearbyTileInformation(byte parameter, TileIndex tile, bool grf_version8) +static uint32 GetNearbyTileInformation(byte parameter, TileIndex tile, bool grf_version8, uint32 mask) { tile = GetNearbyTile(parameter, tile); - return GetNearbyTileInformation(tile, grf_version8); + return GetNearbyTileInformation(tile, grf_version8, mask); } /** Structure with user-data for SearchNearbyHouseXXX - functions */ @@ -362,7 +362,7 @@ static uint32 GetDistanceFromNearbyHouse(uint8 parameter, TileIndex tile, HouseI } /* Land info for nearby tiles. */ - case 0x62: return GetNearbyTileInformation(parameter, this->tile, this->ro.grffile->grf_version >= 8); + case 0x62: return GetNearbyTileInformation(parameter, this->tile, this->ro.grffile->grf_version >= 8, extra->mask); /* Current animation frame of nearby house tiles */ case 0x63: { diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp index c5823bdcf3..50809a1b8d 100644 --- a/src/newgrf_industries.cpp +++ b/src/newgrf_industries.cpp @@ -264,7 +264,7 @@ static uint32 GetCountAndDistanceOfClosestInstance(byte param_setID, byte layout /* Land info of nearby tiles */ case 0x62: if (this->tile == INVALID_TILE) break; - return GetNearbyIndustryTileInformation(parameter, this->tile, INVALID_INDUSTRY, false, this->ro.grffile->grf_version >= 8); + return GetNearbyIndustryTileInformation(parameter, this->tile, INVALID_INDUSTRY, false, this->ro.grffile->grf_version >= 8, extra->mask); /* Animation stage of nearby tiles */ case 0x63: { diff --git a/src/newgrf_industries.h b/src/newgrf_industries.h index 3e2d99d4fe..6fc0c3f770 100644 --- a/src/newgrf_industries.h +++ b/src/newgrf_industries.h @@ -97,6 +97,6 @@ bool IndustryTemporarilyRefusesCargo(Industry *ind, CargoID cargo_type); IndustryType MapNewGRFIndustryType(IndustryType grf_type, uint32 grf_id); /* in newgrf_industrytiles.cpp*/ -uint32 GetNearbyIndustryTileInformation(byte parameter, TileIndex tile, IndustryID index, bool signed_offsets, bool grf_version8); +uint32 GetNearbyIndustryTileInformation(byte parameter, TileIndex tile, IndustryID index, bool signed_offsets, bool grf_version8, uint32 mask); #endif /* NEWGRF_INDUSTRIES_H */ diff --git a/src/newgrf_industrytiles.cpp b/src/newgrf_industrytiles.cpp index 68771d4cec..5badcabb97 100644 --- a/src/newgrf_industrytiles.cpp +++ b/src/newgrf_industrytiles.cpp @@ -31,12 +31,14 @@ * @param grf_version8 True, if we are dealing with a new NewGRF which uses GRF version >= 8. * @return a construction of bits obeying the newgrf format */ -uint32 GetNearbyIndustryTileInformation(byte parameter, TileIndex tile, IndustryID index, bool signed_offsets, bool grf_version8) +uint32 GetNearbyIndustryTileInformation(byte parameter, TileIndex tile, IndustryID index, bool signed_offsets, bool grf_version8, uint32 mask) { if (parameter != 0) tile = GetNearbyTile(parameter, tile, signed_offsets); // only perform if it is required bool is_same_industry = (IsTileType(tile, MP_INDUSTRY) && GetIndustryIndex(tile) == index); - return GetNearbyTileInformation(tile, grf_version8) | (is_same_industry ? 1 : 0) << 8; + uint32 result = (is_same_industry ? 1 : 0) << 8; + if (mask & ~0x100) result |= GetNearbyTileInformation(tile, grf_version8, mask); + return result; } /** @@ -78,7 +80,7 @@ uint32 GetRelativePosition(TileIndex tile, TileIndex ind_tile) /* Land info of nearby tiles */ case 0x60: return GetNearbyIndustryTileInformation(parameter, this->tile, - this->industry == nullptr ? (IndustryID)INVALID_INDUSTRY : this->industry->index, true, this->ro.grffile->grf_version >= 8); + this->industry == nullptr ? (IndustryID)INVALID_INDUSTRY : this->industry->index, true, this->ro.grffile->grf_version >= 8, extra->mask); /* Animation stage of nearby tiles */ case 0x61: { diff --git a/src/newgrf_object.cpp b/src/newgrf_object.cpp index cefd897d83..9d27c9a68d 100644 --- a/src/newgrf_object.cpp +++ b/src/newgrf_object.cpp @@ -170,12 +170,14 @@ static uint32 GetObjectIDAtOffset(TileIndex tile, uint32 cur_grfid) * @param grf_version8 True, if we are dealing with a new NewGRF which uses GRF version >= 8. * @return a construction of bits obeying the newgrf format */ -static uint32 GetNearbyObjectTileInformation(byte parameter, TileIndex tile, ObjectID index, bool grf_version8) +static uint32 GetNearbyObjectTileInformation(byte parameter, TileIndex tile, ObjectID index, bool grf_version8, uint32 mask) { if (parameter != 0) tile = GetNearbyTile(parameter, tile); // only perform if it is required bool is_same_object = (IsTileType(tile, MP_OBJECT) && GetObjectIndex(tile) == index); - return GetNearbyTileInformation(tile, grf_version8) | (is_same_object ? 1 : 0) << 8; + uint32 result = (is_same_object ? 1 : 0) << 8; + if (mask & ~0x100) result |= GetNearbyTileInformation(tile, grf_version8, mask); + return result; } /** @@ -330,7 +332,7 @@ static uint32 GetCountAndDistanceOfClosestInstance(byte local_id, uint32 grfid, } /* Land info of nearby tiles */ - case 0x62: return GetNearbyObjectTileInformation(parameter, this->tile, this->obj == nullptr ? INVALID_OBJECT : this->obj->index, this->ro.grffile->grf_version >= 8); + case 0x62: return GetNearbyObjectTileInformation(parameter, this->tile, this->obj == nullptr ? INVALID_OBJECT : this->obj->index, this->ro.grffile->grf_version >= 8, extra->mask); /* Animation counter of nearby tile */ case 0x63: { diff --git a/src/newgrf_roadstop.cpp b/src/newgrf_roadstop.cpp index 041804454e..5f4a76e126 100644 --- a/src/newgrf_roadstop.cpp +++ b/src/newgrf_roadstop.cpp @@ -146,7 +146,7 @@ uint32 RoadStopScopeResolver::GetVariable(uint16 variable, uint32 parameter, Get if (this->tile == INVALID_TILE) return 0; TileIndex tile = this->tile; if (parameter != 0) tile = GetNearbyTile(parameter, tile); // only perform if it is required - return GetNearbyTileInformation(tile, this->ro.grffile->grf_version >= 8); + return GetNearbyTileInformation(tile, this->ro.grffile->grf_version >= 8, extra->mask); } /* Road stop info of nearby tiles */ diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index fd7278655c..9c31a8155b 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -286,10 +286,12 @@ TownScopeResolver *StationResolverObject::GetTown() TileIndex tile = this->tile; if (parameter != 0) tile = GetNearbyTile(parameter, tile, true, this->axis); // only perform if it is required - Slope tileh = GetTileSlope(tile); - bool swap = (this->axis == AXIS_Y && HasBit(tileh, CORNER_W) != HasBit(tileh, CORNER_E)); - - return GetNearbyTileInformation(tile, this->ro.grffile->grf_version >= 8) ^ (swap ? SLOPE_EW : 0); + uint32 result = GetNearbyTileInformation(tile, this->ro.grffile->grf_version >= 8, extra->mask); + if (extra->mask & SLOPE_EW) { + Slope tileh = GetTileSlope(tile); + if (this->axis == AXIS_Y && HasBit(tileh, CORNER_W) != HasBit(tileh, CORNER_E)) result ^= SLOPE_EW; + } + return result; } break; @@ -345,10 +347,12 @@ TownScopeResolver *StationResolverObject::GetTown() TileIndex tile = this->tile; if (parameter != 0) tile = GetNearbyTile(parameter, tile); // only perform if it is required - Slope tileh = GetTileSlope(tile); - bool swap = (axis == AXIS_Y && HasBit(tileh, CORNER_W) != HasBit(tileh, CORNER_E)); - - return GetNearbyTileInformation(tile, this->ro.grffile->grf_version >= 8) ^ (swap ? SLOPE_EW : 0); + uint32 result = GetNearbyTileInformation(tile, this->ro.grffile->grf_version >= 8, extra->mask); + if (extra->mask & SLOPE_EW) { + Slope tileh = GetTileSlope(tile); + if (axis == AXIS_Y && HasBit(tileh, CORNER_W) != HasBit(tileh, CORNER_E)) result ^= SLOPE_EW; + } + return result; } case 0x68: { // Station info of nearby tiles