1 /* $Id: script_tilelist.cpp 23355 2011-11-29 23:15:35Z truebrain $ */
4 * This file is part of OpenTTD.
5 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
10 /** @file script_tilelist.cpp Implementation of ScriptTileList and friends. */
12 #include "../../stdafx.h"
13 #include "script_tilelist.hpp"
14 #include "script_industry.hpp"
15 #include "../../industry.h"
16 #include "../../station_base.h"
18 #include "../../safeguards.h"
20 void ScriptTileList::AddRectangle(TileIndex t1
, TileIndex t2
)
22 if (!::IsValidTile(t1
)) return;
23 if (!::IsValidTile(t2
)) return;
26 TILE_AREA_LOOP(t
, ta
) this->AddItem(t
);
29 void ScriptTileList::AddTile(TileIndex tile
)
31 if (!::IsValidTile(tile
)) return;
36 void ScriptTileList::RemoveRectangle(TileIndex t1
, TileIndex t2
)
38 if (!::IsValidTile(t1
)) return;
39 if (!::IsValidTile(t2
)) return;
42 TILE_AREA_LOOP(t
, ta
) this->RemoveItem(t
);
45 void ScriptTileList::RemoveTile(TileIndex tile
)
47 if (!::IsValidTile(tile
)) return;
49 this->RemoveItem(tile
);
52 ScriptTileList_IndustryAccepting::ScriptTileList_IndustryAccepting(IndustryID industry_id
, int radius
)
54 if (!ScriptIndustry::IsValidIndustry(industry_id
) || radius
<= 0) return;
56 const Industry
*i
= ::Industry::Get(industry_id
);
58 /* Check if this industry accepts anything */
60 bool cargo_accepts
= false;
61 for (byte j
= 0; j
< lengthof(i
->accepts_cargo
); j
++) {
62 if (i
->accepts_cargo
[j
] != CT_INVALID
) cargo_accepts
= true;
64 if (!cargo_accepts
) return;
67 if (!_settings_game
.station
.modified_catchment
) radius
= CA_UNMODIFIED
;
69 TileArea
ta(i
->location
.tile
- ::TileDiffXY(radius
, radius
), i
->location
.w
+ radius
* 2, i
->location
.h
+ radius
* 2);
70 TILE_AREA_LOOP(cur_tile
, ta
) {
71 if (!::IsValidTile(cur_tile
)) continue;
72 /* Exclude all tiles that belong to this industry */
73 if (::IsTileType(cur_tile
, MP_INDUSTRY
) && ::GetIndustryIndex(cur_tile
) == industry_id
) continue;
75 /* Only add the tile if it accepts the cargo (sometimes just 1 tile of an
76 * industry triggers the acceptance). */
77 CargoArray acceptance
= ::GetAcceptanceAroundTiles(cur_tile
, 1, 1, radius
);
79 bool cargo_accepts
= false;
80 for (byte j
= 0; j
< lengthof(i
->accepts_cargo
); j
++) {
81 if (i
->accepts_cargo
[j
] != CT_INVALID
&& acceptance
[i
->accepts_cargo
[j
]] != 0) cargo_accepts
= true;
83 if (!cargo_accepts
) continue;
86 this->AddTile(cur_tile
);
90 ScriptTileList_IndustryProducing::ScriptTileList_IndustryProducing(IndustryID industry_id
, int radius
)
92 if (!ScriptIndustry::IsValidIndustry(industry_id
) || radius
<= 0) return;
94 const Industry
*i
= ::Industry::Get(industry_id
);
96 /* Check if this industry produces anything */
97 bool cargo_produces
= false;
98 for (byte j
= 0; j
< lengthof(i
->produced_cargo
); j
++) {
99 if (i
->produced_cargo
[j
] != CT_INVALID
) cargo_produces
= true;
101 if (!cargo_produces
) return;
103 if (!_settings_game
.station
.modified_catchment
) radius
= CA_UNMODIFIED
;
105 TileArea
ta(i
->location
.tile
- ::TileDiffXY(radius
, radius
), i
->location
.w
+ radius
* 2, i
->location
.h
+ radius
* 2);
106 TILE_AREA_LOOP(cur_tile
, ta
) {
107 if (!::IsValidTile(cur_tile
)) continue;
108 /* Exclude all tiles that belong to this industry */
109 if (::IsTileType(cur_tile
, MP_INDUSTRY
) && ::GetIndustryIndex(cur_tile
) == industry_id
) continue;
111 this->AddTile(cur_tile
);
115 ScriptTileList_StationType::ScriptTileList_StationType(StationID station_id
, ScriptStation::StationType station_type
)
117 if (!ScriptStation::IsValidStation(station_id
)) return;
119 const StationRect
*rect
= &::Station::Get(station_id
)->rect
;
121 uint station_type_value
= 0;
122 /* Convert ScriptStation::StationType to ::StationType, but do it in a
123 * bitmask, so we can scan for multiple entries at the same time. */
124 if ((station_type
& ScriptStation::STATION_TRAIN
) != 0) station_type_value
|= (1 << ::STATION_RAIL
);
125 if ((station_type
& ScriptStation::STATION_TRUCK_STOP
) != 0) station_type_value
|= (1 << ::STATION_TRUCK
);
126 if ((station_type
& ScriptStation::STATION_BUS_STOP
) != 0) station_type_value
|= (1 << ::STATION_BUS
);
127 if ((station_type
& ScriptStation::STATION_AIRPORT
) != 0) station_type_value
|= (1 << ::STATION_AIRPORT
) | (1 << ::STATION_OILRIG
);
128 if ((station_type
& ScriptStation::STATION_DOCK
) != 0) station_type_value
|= (1 << ::STATION_DOCK
) | (1 << ::STATION_OILRIG
);
130 TileArea
ta(::TileXY(rect
->left
, rect
->top
), rect
->right
- rect
->left
+ 1, rect
->bottom
- rect
->top
+ 1);
131 TILE_AREA_LOOP(cur_tile
, ta
) {
132 if (!::IsTileType(cur_tile
, MP_STATION
)) continue;
133 if (::GetStationIndex(cur_tile
) != station_id
) continue;
134 if (!HasBit(station_type_value
, ::GetStationType(cur_tile
))) continue;
135 this->AddTile(cur_tile
);