ai_tilelist.cpp

Go to the documentation of this file.
00001 /* $Id: ai_tilelist.cpp 15299 2009-01-31 20:16:06Z smatz $ */
00002 
00005 #include "ai_tilelist.hpp"
00006 #include "ai_industry.hpp"
00007 #include "../../tile_map.h"
00008 #include "../../industry_map.h"
00009 #include "../../station_map.h"
00010 #include "../../settings_type.h"
00011 
00012 void AITileList::FixRectangleSpan(TileIndex &t1, TileIndex &t2)
00013 {
00014   uint x1 = ::TileX(t1);
00015   uint x2 = ::TileX(t2);
00016 
00017   uint y1 = ::TileY(t1);
00018   uint y2 = ::TileY(t2);
00019 
00020   if (x1 >= x2) ::Swap(x1, x2);
00021   if (y1 >= y2) ::Swap(y1, y2);
00022 
00023   t1 = ::TileXY(x1, y1);
00024   t2 = ::TileXY(x2, y2);
00025 }
00026 
00027 void AITileList::AddRectangle(TileIndex t1, TileIndex t2)
00028 {
00029   if (!::IsValidTile(t1)) return;
00030   if (!::IsValidTile(t2)) return;
00031 
00032   this->FixRectangleSpan(t1, t2);
00033 
00034   uint w = TileX(t2) - TileX(t1) + 1;
00035   uint h = TileY(t2) - TileY(t1) + 1;
00036 
00037   BEGIN_TILE_LOOP(t, w, h, t1) {
00038     this->AddItem(t);
00039   } END_TILE_LOOP(t, w, h, t1)
00040 }
00041 
00042 void AITileList::AddTile(TileIndex tile)
00043 {
00044   if (!::IsValidTile(tile)) return;
00045 
00046   this->AddItem(tile);
00047 }
00048 
00049 void AITileList::RemoveRectangle(TileIndex t1, TileIndex t2)
00050 {
00051   if (!::IsValidTile(t1)) return;
00052   if (!::IsValidTile(t2)) return;
00053 
00054   this->FixRectangleSpan(t1, t2);
00055 
00056   uint w = TileX(t2) - TileX(t1) + 1;
00057   uint h = TileY(t2) - TileY(t1) + 1;
00058 
00059   BEGIN_TILE_LOOP(t, w, h, t1) {
00060     this->RemoveItem(t);
00061   } END_TILE_LOOP(t, w, h, t1)
00062 }
00063 
00064 void AITileList::RemoveTile(TileIndex tile)
00065 {
00066   if (!::IsValidTile(tile)) return;
00067 
00068   this->RemoveItem(tile);
00069 }
00070 
00071 AITileList_IndustryAccepting::AITileList_IndustryAccepting(IndustryID industry_id, uint radius)
00072 {
00073   if (!AIIndustry::IsValidIndustry(industry_id)) return;
00074 
00075   const Industry *i = ::GetIndustry(industry_id);
00076 
00077   /* Check if this industry accepts anything */
00078   {
00079     bool cargo_accepts = false;
00080     for (byte j = 0; j < lengthof(i->accepts_cargo); j++) {
00081       if (i->accepts_cargo[j] != CT_INVALID) cargo_accepts = true;
00082     }
00083     if (!cargo_accepts) return;
00084   }
00085 
00086   if (!_settings_game.station.modified_catchment) radius = CA_UNMODIFIED;
00087 
00088   BEGIN_TILE_LOOP(cur_tile, i->width + radius * 2, i->height + radius * 2, i->xy - ::TileDiffXY(radius, radius)) {
00089     if (!::IsValidTile(cur_tile)) continue;
00090     /* Exclude all tiles that belong to this industry */
00091     if (::IsTileType(cur_tile, MP_INDUSTRY) && ::GetIndustryIndex(cur_tile) == industry_id) continue;
00092 
00093     /* Only add the tile if it accepts the cargo (sometimes just 1 tile of an
00094      *  industry triggers the acceptance). */
00095     AcceptedCargo accepts;
00096 		::GetAcceptanceAroundTiles(accepts, cur_tile, 1, 1, radius);
00097     {
00098       bool cargo_accepts = false;
00099       for (byte j = 0; j < lengthof(i->accepts_cargo); j++) {
00100         if (i->accepts_cargo[j] != CT_INVALID && accepts[i->accepts_cargo[j]] != 0) cargo_accepts = true;
00101       }
00102       if (!cargo_accepts) continue;
00103     }
00104 
00105     this->AddTile(cur_tile);
00106   } END_TILE_LOOP(cur_tile, i->width + radius * 2, i->height + radius * 2, i->xy - ::TileDiffXY(radius, radius))
00107 }
00108 
00109 AITileList_IndustryProducing::AITileList_IndustryProducing(IndustryID industry_id, uint radius)
00110 {
00111   if (!AIIndustry::IsValidIndustry(industry_id)) return;
00112 
00113   const Industry *i = ::GetIndustry(industry_id);
00114 
00115   /* Check if this industry produces anything */
00116   {
00117     bool cargo_produces = false;
00118     for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
00119       if (i->produced_cargo[j] != CT_INVALID) cargo_produces = true;
00120     }
00121     if (!cargo_produces) return;
00122   }
00123 
00124   if (!_settings_game.station.modified_catchment) radius = CA_UNMODIFIED;
00125 
00126   BEGIN_TILE_LOOP(cur_tile, i->width + radius * 2, i->height + radius * 2, i->xy - ::TileDiffXY(radius, radius)) {
00127     if (!::IsValidTile(cur_tile)) continue;
00128     /* Exclude all tiles that belong to this industry */
00129     if (::IsTileType(cur_tile, MP_INDUSTRY) && ::GetIndustryIndex(cur_tile) == industry_id) continue;
00130 
00131     /* Only add the tile if it produces the cargo (a bug in OpenTTD makes this
00132      *  inconsitance). */
00133     AcceptedCargo produces;
00134 		::GetProductionAroundTiles(produces, cur_tile, 1, 1, radius);
00135     {
00136       bool cargo_produces = false;
00137       for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
00138         if (i->produced_cargo[j] != CT_INVALID && produces[i->produced_cargo[j]] != 0) cargo_produces = true;
00139       }
00140       if (!cargo_produces) continue;
00141     }
00142 
00143     this->AddTile(cur_tile);
00144   } END_TILE_LOOP(cur_tile, i->width + radius * 2, i->height + radius * 2, i->xy - ::TileDiffXY(radius, radius))
00145 }
00146 
00147 AITileList_StationType::AITileList_StationType(StationID station_id, AIStation::StationType station_type)
00148 {
00149   if (!AIStation::IsValidStation(station_id)) return;
00150 
00151   const StationRect *rect = &::GetStation(station_id)->rect;
00152 
00153   uint station_type_value = 0;
00154   /* Convert AIStation::StationType to ::StationType, but do it in a
00155    *  bitmask, so we can scan for multiple entries at the same time. */
00156   if ((station_type & AIStation::STATION_TRAIN) != 0)      station_type_value |= (1 << ::STATION_RAIL);
00157   if ((station_type & AIStation::STATION_TRUCK_STOP) != 0) station_type_value |= (1 << ::STATION_TRUCK);
00158   if ((station_type & AIStation::STATION_BUS_STOP) != 0)   station_type_value |= (1 << ::STATION_BUS);
00159   if ((station_type & AIStation::STATION_AIRPORT) != 0)    station_type_value |= (1 << ::STATION_AIRPORT) | (1 << ::STATION_OILRIG);
00160   if ((station_type & AIStation::STATION_DOCK) != 0)       station_type_value |= (1 << ::STATION_DOCK)    | (1 << ::STATION_OILRIG);
00161 
00162   BEGIN_TILE_LOOP(cur_tile, rect->right - rect->left + 1, rect->bottom - rect->top + 1, ::TileXY(rect->left, rect->top)) {
00163     if (!::IsTileType(cur_tile, MP_STATION)) continue;
00164     if (::GetStationIndex(cur_tile) != station_id) continue;
00165     if (!HasBit(station_type_value, ::GetStationType(cur_tile))) continue;
00166     this->AddTile(cur_tile);
00167   } END_TILE_LOOP(cur_tile, rect->right - rect->left + 1, rect->bottom - rect->top + 1, ::TileXY(rect->left, rect->top))
00168 }

Generated on Sun Mar 15 22:49:45 2009 for openttd by  doxygen 1.5.6