00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "buildingtypeselector.h"
00019 #include "selectionwindow.h"
00020 #include "unitinfodialog.h"
00021
00022 #include "../buildingtype.h"
00023 #include "../iconrepository.h"
00024 #include "../spfst.h"
00025 #include "../unitset.h"
00026
00027
00028
00029 const int buildingHeight = 5 * fielddisty + fieldsizey;
00030 const int buildingWidth = 4 * fielddistx;
00031
00032 int BuildingTypeBaseWidget :: getBuildingHeight( const BuildingType* type )
00033 {
00034 int miny = maxint;
00035 int maxy = minint;
00036 for ( int y = 0; y < 6; ++y )
00037 for ( int x = 0; x < 4; ++x )
00038 if ( type->fieldExists( BuildingType::LocalCoordinate( x, y ))) {
00039 miny = min( miny, y );
00040 maxy = max( maxy, y );
00041 }
00042
00043 return (maxy - miny) * fielddisty + fieldsizey;
00044 }
00045
00046
00047 BuildingTypeBaseWidget :: BuildingTypeBaseWidget( PG_Widget* parent, const PG_Point& pos, int width, const BuildingType* buildingType, const Player& player ) : SelectionWidget( parent, PG_Rect( pos.x, pos.y, width, getBuildingHeight(buildingType)+10 )), vt( buildingType ), actplayer(player)
00048 {
00049
00050 new PG_Label( this, PG_Rect( buildingWidth, 20, Width() - buildingWidth - 10, 25 ), vt->name );
00051
00052 SetTransparency( 255 );
00053 };
00054
00055
00056
00057 ASCString BuildingTypeBaseWidget::getName() const
00058 {
00059 return vt->getName();
00060 };
00061
00062 void BuildingTypeBaseWidget::display( SDL_Surface * surface, const PG_Rect & src, const PG_Rect & dst )
00063 {
00064 if ( !getClippingSurface().valid() )
00065 getClippingSurface() = Surface::createSurface( buildingWidth + 10, buildingHeight + 10, 32, 0 );
00066
00067 getClippingSurface().Fill(0);
00068
00069 int yoffs = maxint;
00070 int xoffs = maxint;
00071 for ( int y = 0; y < 6; ++y )
00072 for ( int x = 0; x < 4; ++x )
00073 if ( vt->fieldExists( BuildingType::LocalCoordinate( x, y ))) {
00074 yoffs = min( yoffs, y * fielddisty );
00075 xoffs = min( xoffs, x * fielddistx + (y&1)*fielddisthalfx);
00076 }
00077
00078 for ( int y = 0; y < 6; ++y )
00079 for ( int x = 0; x < 4; ++x )
00080 if ( vt->fieldExists( BuildingType::LocalCoordinate( x, y )))
00081 vt->paintSingleField( getClippingSurface(), SPoint(5 - xoffs, 5 - yoffs), BuildingType::LocalCoordinate(x,y), actplayer.getPlayerColor() );
00082
00083
00084 PG_Draw::BlitSurface( getClippingSurface().getBaseSurface(), src, surface, dst);
00085 }
00086
00087 Surface BuildingTypeBaseWidget::clippingSurface;
00088
00089
00090
00091 BuildingTypeResourceWidget::BuildingTypeResourceWidget( PG_Widget* parent, const PG_Point& pos, int width, const BuildingType* BuildingType, int lackingResources, const Resources& cost, const Player& player )
00092 : BuildingTypeBaseWidget( parent,pos, width, BuildingType, player )
00093 {
00094 int col1 = 50;
00095 int lineheight = 20;
00096
00097 int sw = (width - col1 - 10) / 6;
00098
00099 static const char* filenames[3] = { "energy.png", "material.png", "fuel.png" };
00100
00101 for ( int i = 0; i < 3; ++i ) {
00102 new PG_Image ( this, PG_Point( col1 + 2 + 5 * sw, i * 12 + 5), IconRepository::getIcon( filenames[i] ).getBaseSurface(), false );
00103 PG_Label* lbl = new PG_Label( this, PG_Rect( col1 + 3 * sw, i * 12, sw * 2, lineheight ), ASCString::toString(cost.resource(i)) );
00104 lbl->SetAlignment( PG_Label::RIGHT );
00105 lbl->SetFontSize( lbl->GetFontSize() - 3 );
00106 if ( lackingResources & (1<<i) )
00107 lbl->SetFontColor( 0xff0000);
00108 }
00109 }
00110
00111
00112 BuildingTypeCountWidget::BuildingTypeCountWidget( PG_Widget* parent, const PG_Point& pos, int width, const BuildingType* BuildingType, const Player& player, int number )
00113 : BuildingTypeBaseWidget( parent,pos, width, BuildingType, player )
00114 {
00115 int col1 = 50;
00116 int lineheight = 20;
00117
00118 int sw = (width - col1 - 10) / 6;
00119
00120 PG_Label* lbl = new PG_Label( this, PG_Rect( col1 + 4 * sw, 0, sw * 2, lineheight*2 ), ASCString::toString(number) );
00121 lbl->SetAlignment( PG_Label::RIGHT );
00122 lbl->SetFontSize( lbl->GetFontSize() + 5 );
00123 }
00124
00125
00126
00127
00128
00129
00130 BuildingTypeSelectionItemFactory :: BuildingTypeSelectionItemFactory( Resources plantResources, const Container& types, const Player& player ) : actplayer(player), original_items( types )
00131 {
00132 restart();
00133 setAvailableResource( plantResources );
00134 };
00135
00136
00137 bool BuildingComp ( const BuildingType* v1, const BuildingType* v2 )
00138 {
00139 int id1 = getUnitSetID(v1);
00140 int id2 = getUnitSetID(v2);
00141 return (id1 < id2) ||
00142 (id1 == id2 && v1->name < v2->name);
00143 };
00144
00145
00146 void BuildingTypeSelectionItemFactory::restart()
00147 {
00148 items = original_items;
00149 sort( items.begin(), items.end(), BuildingComp );
00150 it = items.begin();
00151 };
00152
00153
00154 SelectionWidget* BuildingTypeSelectionItemFactory::spawnNextItem( PG_Widget* parent, const PG_Point& pos )
00155 {
00156 if ( it != items.end() ) {
00157 const BuildingType* v = *(it++);
00158 Resources cost = getCost(v);
00159
00160 int lackingResources = 0;
00161 for ( int r = 0; r < 3; ++r )
00162 if ( plantResources.resource(r) < cost.resource(r))
00163 lackingResources |= 1 << r;
00164 return new BuildingTypeResourceWidget( parent, pos, parent->Width() - 15, v, lackingResources, cost, actplayer );
00165 } else
00166 return NULL;
00167 };
00168
00169 Resources BuildingTypeSelectionItemFactory::getCost( const BuildingType* type )
00170 {
00171 return type->productionCost;
00172 }
00173
00174
00175
00176 void BuildingTypeSelectionItemFactory::itemSelected( const SelectionWidget* widget, bool mouse )
00177 {
00178 if ( !widget )
00179 return;
00180
00181 const BuildingTypeResourceWidget* fw = dynamic_cast<const BuildingTypeResourceWidget*>(widget);
00182 assert( fw );
00183
00184
00185
00186 BuildingTypeSelected( fw->getBuildingType() );
00187 }
00188