Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

edselfnt.cpp

Go to the documentation of this file.
00001 
00005 /*
00006     This file is part of Advanced Strategic Command; http://www.asc-hq.de
00007     Copyright (C) 1994-1999  Martin Bickel  and  Marc Schellenberger
00008 
00009     This program is free software; you can redistribute it and/or modify
00010     it under the terms of the GNU General Public License as published by
00011     the Free Software Foundation; either version 2 of the License, or
00012     (at your option) any later version.
00013 
00014     This program is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017     GNU General Public License for more details.
00018 
00019     You should have received a copy of the GNU General Public License
00020     along with this program; see the file COPYING. If not, write to the 
00021     Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
00022     Boston, MA  02111-1307  USA
00023 */
00024 
00025 
00026 #include "vehicletype.h"
00027 #include "buildingtype.h"
00028 
00029 #include "edmisc.h"
00030 #include "edselfnt.h"
00031 #include "mapdisplay.h"
00032 #include "itemrepository.h"
00033 #include "edglobal.h"
00034 
00035 #include "graphics/blitter.h"
00036 #include "paradialog.h"
00037 
00038 #include "dialogs/vehicletypeselector.h"
00039 #include "unitset.h"
00040 
00041 SigC::Signal0<void> filtersChangedSignal;
00042 
00043 
00044 
00045 
00046 
00047 bool buildingComp( const BuildingType* v1, const BuildingType* v2 )
00048 {
00049    int id1 = getUnitSetID(v1);
00050    int id2 = getUnitSetID(v2);
00051    return (id1 <  id2) ||
00052           (id1 == id2 && v1->name < v2->name);
00053 }
00054 
00055 bool objectComp( const ObjectType* v1, const ObjectType* v2 )
00056 {
00057    return v1->name < v2->name;
00058 }
00059 
00060 bool terrainComp( const TerrainType* v1, const TerrainType* v2 )
00061 {
00062    if (  v1->weather[0] && v2->weather[0] )
00063       return v1->weather[0]->art.to_ulong()  < v2->weather[0]->art.to_ulong();
00064    else
00065       return v1->name < v2->name;
00066 }
00067 
00068 bool mineComp( const MineType* v1, const MineType* v2 )
00069 {
00070    return v1->id < v2->id;
00071 }
00072 
00073 
00074 void sortItems( vector<Vehicletype*>& vec )
00075 {
00076    sort( vec.begin(), vec.end(), vehicleComp );
00077 }
00078 
00079 void sortItems( vector<BuildingType*>& vec )
00080 {
00081    sort( vec.begin(), vec.end(), buildingComp );
00082 }
00083 
00084 void sortItems( vector<ObjectType*>& vec )
00085 {
00086    sort( vec.begin(), vec.end(), objectComp );
00087 }
00088 
00089 void sortItems( vector<TerrainType*>& vec )
00090 {
00091    sort( vec.begin(), vec.end(), terrainComp );
00092 }
00093 
00094 void sortItems( vector<MineType*>& vec )
00095 {
00096    sort( vec.begin(), vec.end(), mineComp );
00097 }
00098 
00099 
00100 void MapComponent::displayClip( PG_Widget* parent, SDL_Surface * surface, const PG_Rect & src, const PG_Rect & dst ) const
00101 {
00102    if ( !getClippingSurface().valid() )
00103       getClippingSurface() = Surface::createSurface( displayWidth() + 10, displayHeight() + fontHeight + 10, 32, 0 );
00104       
00105    getClippingSurface().Fill(0);   
00106    display( getClippingSurface(), SPoint( 0, 0 ) );
00107    
00108    static PG_ThemeWidget* fontProvidingWidget = NULL;
00109    if ( !fontProvidingWidget  )
00110       fontProvidingWidget = new PG_ThemeWidget( NULL, PG_Rect::null , false, "MapedItemSelector" );
00111       
00112    /*
00113    SDL_Rect      blitRect;
00114    blitRect.x = 0;
00115    blitRect.y = displayHeight() + 2;
00116    blitRect.w = displayWidth();
00117    blitRect.h = displayHeight() - blitRect.y;
00118 
00119    PG_FontEngine::RenderText( getClippingSurface().getBaseSurface(), blitRect, blitRect.x, blitRect.y+fontProvidingWidget ->GetFontAscender(), getItemType()->getName(), fontProvidingWidget ->GetFont() );
00120    */
00121 
00122    PG_Draw::BlitSurface( getClippingSurface().getBaseSurface(), src, surface, dst);
00123 
00124    int x = dst.x;
00125    int y = dst.y + displayHeight() + fontProvidingWidget ->GetFontAscender() - src.y;
00126    
00127    PG_FontEngine::RenderText( surface, dst, x, y, getItemType()->getName(), fontProvidingWidget ->GetFont() );
00128 }
00129 
00130 
00131 
00132 
00133 // template<class Vehicletype> Surface BasicItem<Vehicletype>::clippingSurface;
00134 int VehicleItem::place( const MapCoordinate& mc ) const
00135 {
00136    tfield* fld = actmap->getField(mc);
00137    if ( !fld )
00138       return -1;
00139 
00140    const Vehicletype* veh = item;
00141    
00142    if ( !veh )
00143       return -2;
00144      
00145    if ( selection.getPlayer()  == 8 )
00146       return -3;
00147 
00148    bool accessible = veh->terrainaccess.accessible ( fld->bdt );
00149    if ( veh->height >= chtieffliegend )
00150          accessible = true;
00151 
00152    if ( fld->building  || ( !accessible && !actmap->getgameparameter( cgp_movefrominvalidfields)) ) 
00153       return -3;
00154    
00155    
00156    if ( fld->vehicle ) {
00157       if ( fld->vehicle->typ != veh ) {
00158          delete fld->vehicle;
00159          fld->vehicle = NULL;
00160       } else {
00161          fld->vehicle->convert( selection.getPlayer()  );
00162          return 1;
00163       }
00164    }
00165    fld->vehicle = new Vehicle ( veh, actmap, selection.getPlayer()  );
00166    fld->vehicle->setnewposition ( mc );
00167    fld->vehicle->fillMagically();
00168    
00169    for ( int i = 0; i < 9; ++i ) {
00170       if ( fld->vehicle->typ->height & (1 << i )) {
00171          fld->vehicle->height = 1 << i;
00172          if ( terrainaccessible( fld, fld->vehicle ) == 2 ) //  || actmap->getgameparameter( cgp_movefrominvalidfields)
00173             break;
00174       }
00175       if ( i == 8 ) { // no height found
00176          delete fld->vehicle;
00177          fld->vehicle = NULL;
00178          return -3;
00179       }   
00180    }
00181    fld->vehicle->resetMovement();
00182    return 1;
00183    
00184 }
00185 
00186 
00187 Surface BuildingItem::clippingSurface;
00188 Surface BuildingItem::fullSizeImage;
00189 int BuildingItem::place( const MapCoordinate& mc ) const
00190 {
00191    int f = 0;
00192    for ( int x = 0; x < 4; x++ )
00193       for ( int y = 0; y < 6; y++ )
00194          if ( bld->fieldExists ( BuildingType::LocalCoordinate(x, y) )) {
00195             MapCoordinate mc = bld->getFieldCoordinate ( actmap->getCursor() , BuildingType::LocalCoordinate (x, y) );
00196             if ( !actmap->getField (mc) )
00197                return -1;
00198 
00199             if ( bld->terrainaccess.accessible ( actmap->getField (mc)->bdt ) <= 0 )
00200                f++;
00201          }
00202    if ( f ) {
00203       if (choice_dlg("Invalid terrain for building !","~i~gnore","~c~ancel") == 2)
00204          return -1 ;
00205    }      
00206 
00207    putbuilding( actmap->getCursor(), selection.getPlayer()  * 8, bld, bld->construction_steps );
00208    return 0;
00209 }
00210 
00211 void BuildingItem::display( Surface& s, const SPoint& pos ) const 
00212 { 
00213    if ( !fullSizeImage.valid() )
00214       fullSizeImage = Surface::createSurface( displayWidth()*2 + 10, displayHeight()*2 + 30, 32, 0 );
00215    fullSizeImage.FillTransparent();
00216    if ( actmap )
00217       bld->paint ( fullSizeImage, SPoint(0,0), actmap->getPlayer( selection.getPlayer()).getPlayerColor() ); 
00218    else
00219       bld->paint ( fullSizeImage, SPoint(0,0) ); 
00220    
00221    MegaBlitter<colorDepth,colorDepth,ColorTransform_None,ColorMerger_AlphaOverwrite,SourcePixelSelector_DirectZoom,TargetPixelSelector_Valid> blitter;
00222    blitter.setZoom( 0.5 );
00223    blitter.blit( fullSizeImage, s, pos );
00224 }
00225 
00226 
00227 
00228 // template<> Surface BasicItem<ObjectType>::clippingSurface;
00229 int ObjectItem::place( const MapCoordinate& mc ) const
00230 {
00231    if ( !actmap->getField(mc)->addobject( item ) )
00232       if ( SDL_GetKeyState(NULL)[SDLK_LCTRL] || SDL_GetKeyState(NULL)[SDLK_RCTRL] || choice_dlg("object cannot be built here\n(bypass this dialog by pressing <ctrl>)","~c~ancel","~i~gnore") == 2)
00233          actmap->getField(mc)->addobject( item, -1, true );
00234 
00235    return 0;
00236 }
00237 
00238 
00239 bool ObjectItem::remove ( const MapCoordinate& mc ) const
00240 {
00241    if ( item && actmap->getField(mc)->checkforobject(item) ) {
00242       actmap->getField(mc)->removeobject ( item );
00243       return true;
00244    }
00245    return false;
00246 
00247 }
00248 
00249 
00250 template<typename T> Surface BasicItem<T>::clippingSurface;
00251 int TerrainItem::place( const MapCoordinate& mc ) const
00252 {
00253    tfield* fld = actmap->getField(mc);
00254    fld->typ = item->weather[0]; 
00255    fld->setweather( selection.getWeather() );
00256    fld->setparams();
00257    for ( int d = 0; d < 6; ++d ) {
00258       MapCoordinate pos = getNeighbouringFieldCoordinate( mc, d );
00259       tfield* fld = actmap->getField( pos );
00260       if ( fld ) 
00261          for ( tfield::ObjectContainer::iterator i = fld->objects.begin(); i != fld->objects.end(); ++i )
00262             calculateobject( pos, false, i->typ, actmap );
00263    }
00264    return 0;
00265 }
00266 
00267 
00268 int MineItem::place( const MapCoordinate& mc ) const
00269 {
00270    actmap->getField(mc)->putmine( selection.getPlayer(), item->id, MineBasePunch[item->id-1] );
00271    return 0;
00272 }
00273 
00274 
00275 
00276 
00277 
00278 
00279 
00280 
00281 
00282 
00283 
00284 
00285 
00286 
00287 
00288 
00289 
00290 
00291 
00292 
00293 
00294 class CargoItemFactory: public MapItemTypeWidgetFactory<MapItemTypeWidget< Vehicletype > > {
00295       typedef MapItemTypeWidgetFactory<MapItemTypeWidget< Vehicletype > > Parent;
00296       typedef MapItemTypeWidget< Vehicletype > WidgetType;
00297        ContainerBase* container;
00298    protected:
00299       bool isFiltered( const ItemType& item ) {
00300          if ( Parent::isFiltered( item ))
00301             return true;
00302       
00303          if ( !container->baseType->vehicleFit( &item ))
00304             return true;
00305               
00306          bool result = true;
00307          Vehicle* unit = new Vehicle ( &item, actmap, container->getOwner() );
00308          if ( container->vehicleFit ( unit ))
00309             result = false;
00310          delete unit;
00311          return result;
00312       };
00313 
00314    public:
00315       CargoItemFactory(  ContainerBase* container_ )  : Parent(vehicleTypeRepository), container( container_ ) {};
00316       
00317       void itemSelected( const SelectionWidget* widget, bool mouse )
00318       {
00319          if ( !widget )
00320             return;
00321             
00322          const WidgetType* mapItemWidget = dynamic_cast<const WidgetType*>(widget);
00323          assert( mapItemWidget );
00324          if ( mapItemWidget->getItem() ) {
00325             Vehicle* unit = new Vehicle ( mapItemWidget->getItem(), actmap, container->getOwner() );
00326             unit->fillMagically();
00327             unit->setnewposition ( container->getPosition() );
00328             unit->tank.material = 0;
00329             unit->tank.fuel = 0;
00330             if ( container->vehicleFit ( unit )) {
00331                unit->tank.material = unit->getStorageCapacity().material;
00332                unit->tank.fuel = unit->getStorageCapacity().fuel;
00333       
00334                if ( !container->vehicleFit ( unit )) {
00335                   unit->tank.material = 0;
00336                   unit->tank.fuel = 0;
00337                   displaymessage("Warning:\nThe unit you just set could not be loaded with full material and fuel\nPlease set these values manually",1);
00338                }
00339                container->addToCargo( unit );
00340       
00341             } else {
00342                delete unit;
00343                displaymessage("The unit could not be loaded !",1);
00344             }
00345          }
00346       }
00347      
00348 };
00349 
00350 
00351 void addCargo( ContainerBase* container )
00352 {
00353    ItemSelectorWindow isw( NULL, PG_Rect( 100, 100, 280, 600), "cargo", new CargoItemFactory( container ) );
00354    isw.Show();
00355    isw.RunModal();
00356 }
00357 
00358 
00359 
00360 
00361 
00362 class ProductionItemFactory: public MapItemTypeWidgetFactory<MapItemTypeWidget< Vehicletype > > {
00363       typedef MapItemTypeWidgetFactory<MapItemTypeWidget< Vehicletype > > Parent;
00364       typedef MapItemTypeWidget< Vehicletype > WidgetType;
00365       ContainerBase* container;
00366       const Vehicletype* selectedItem;
00367    protected:
00368       bool isFiltered( const ItemType& item ) {
00369          if ( Parent::isFiltered( item ))
00370             return true;
00371       
00372          if ( !container->baseType->vehicleFit( &item ))
00373             return true;
00374          
00375          if ( !(container->baseType->vehicleCategoriesProduceable & (1 << item.movemalustyp)))
00376             return true;
00377 
00378          return false;
00379       };
00380 
00381    public:
00382       ProductionItemFactory(  ContainerBase* container_ )  : Parent(vehicleTypeRepository), container( container_ ), selectedItem(NULL) {};
00383       
00384 
00385       void itemMarked  ( const SelectionWidget* widget )
00386       {
00387          if ( !widget )
00388             return;
00389             
00390          const WidgetType* mapItemWidget = dynamic_cast<const WidgetType*>(widget);
00391          assert( mapItemWidget );
00392          const Vehicletype* type = mapItemWidget->getItem();
00393          if ( type ) {
00394             selectedItem = type;
00395          }
00396       };
00397       
00398       void itemSelected( const SelectionWidget* widget, bool mouse )
00399       {
00400          itemMarked( widget );
00401       }
00402       
00403       const Vehicletype* getSelectedVehicleType()
00404       {
00405          return selectedItem;
00406       }
00407      
00408 };
00409 
00410 
00411 class AvailableProductionItemFactory: public SelectionItemFactory, public SigC::Object  {
00412    private:
00413       const ContainerBase* container;
00414       const Vehicletype* selectedItem;
00415    protected:
00416       ContainerBase::Production::const_iterator it;
00417       ContainerBase::Production& production;
00418    public:
00419       AvailableProductionItemFactory(  ContainerBase* container_, ContainerBase::Production& prod )  : container( container_ ), selectedItem(NULL), production( prod )
00420       {
00421          restart();
00422       };
00423       
00424       void restart()
00425       {
00426          // sort( items.begin(), items.end(), VehicleComp );
00427          it = production.begin();
00428       }
00429       
00430       SelectionWidget* spawnNextItem( PG_Widget* parent, const PG_Point& pos )
00431       {
00432          if ( it != production.end() ) {
00433             const Vehicletype* v = *(it++);
00434             return new VehicleTypeBaseWidget( parent, pos, parent->Width() - 15, v, actmap->getCurrentPlayer() );
00435          } else
00436             return NULL;
00437       };
00438       
00439       void itemMarked  ( const SelectionWidget* widget )
00440       {
00441          if ( !widget )
00442             return;
00443             
00444          const VehicleTypeBaseWidget* mapItemWidget = dynamic_cast<const VehicleTypeBaseWidget*>(widget);
00445          assert( mapItemWidget );
00446          const Vehicletype* type = mapItemWidget->getVehicletype();
00447          if ( type ) {
00448             selectedItem = type;
00449          }
00450       }
00451       
00452       
00453       void itemSelected( const SelectionWidget* widget, bool mouse )
00454       {
00455          itemMarked( widget );
00456       }
00457 
00458       const Vehicletype* getSelectedVehicleType()
00459       {
00460          return selectedItem;
00461       }
00462             
00463 };
00464 
00465 
00466 
00467 class ProductionEditorWindow : public ASC_PG_Dialog {
00468    private:
00469       ProductionItemFactory* allTypesFactory;
00470       ItemSelectorWidget* allTypes;
00471       
00472       AvailableProductionItemFactory* productionFactory;
00473       ItemSelectorWidget* productionWidget;
00474       
00475 
00476       ContainerBase* container;
00477 
00478       ContainerBase::Production production;
00479       
00480 
00481       bool ok()
00482       {
00483          container->setProductionLines( production );
00484          QuitModal();
00485          return true;
00486       }
00487 
00488       bool addOne()
00489       {
00490          const Vehicletype* v = allTypesFactory->getSelectedVehicleType();
00491          if ( !v )
00492             return false;
00493          
00494          if ( find( production.begin(), production.end(), v ) == production.end() ) {
00495             production.push_back( v );
00496             productionWidget->reLoad( true );
00497             return true;
00498          }
00499          return false;
00500       }
00501       
00502       bool removeOne()
00503       {
00504          const Vehicletype* v = productionFactory->getSelectedVehicleType();
00505          if ( !v )
00506             return false;
00507 
00508          ContainerBase::Production::iterator i = find( production.begin(), production.end(), v );
00509          if ( i != production.end() ) {
00510             production.erase( i );
00511             productionWidget->reLoad( true );
00512             return true;
00513          }
00514          return false;
00515       }
00516 
00517       
00518    public:
00519       ProductionEditorWindow ( ContainerBase* container ) : ASC_PG_Dialog ( NULL, PG_Rect( 20,20, 700, 550 ), "Unit Production" )
00520       {
00521          this->container = container;
00522          production = container->getProduction();
00523          
00524          const int centerSpace = 80;
00525          const int border  = 10;
00526          
00527          allTypesFactory = new ProductionItemFactory( container );
00528          allTypes = new ItemSelectorWidget( this, PG_Rect( border, 50, (my_width- centerSpace) / 2 - 2 * border, my_height - 100 ), allTypesFactory );
00529 
00530          productionFactory = new AvailableProductionItemFactory( container, production );
00531          productionWidget = new ItemSelectorWidget( this, PG_Rect( (my_width + centerSpace) / 2 + border, 50, (my_width- centerSpace) / 2 - 2 * border, my_height - 100 ), productionFactory);
00532 
00533 
00534          
00535          PG_Button* addB = new PG_Button( this, PG_Rect( (my_width - centerSpace) / 2, 100, centerSpace, 30 ), "->" );
00536          addB->sigClick.connect( SigC::slot( *this, &ProductionEditorWindow::addOne ));
00537          
00538          PG_Button* removeB = new PG_Button( this, PG_Rect( (my_width - centerSpace) / 2, 140, centerSpace, 30 ), "<-" );
00539          removeB->sigClick.connect( SigC::slot( *this, &ProductionEditorWindow::removeOne ));
00540 
00541          
00542          PG_Button* ok = new PG_Button( this, PG_Rect( my_width - 100, my_height - 40, 90, 30 ), "OK" );
00543          ok->sigClick.connect( SigC::slot( *this, &ProductionEditorWindow::ok ));
00544       };
00545 
00546 };
00547       
00548 
00549 void editProduction( ContainerBase* container )
00550 {
00551    ProductionEditorWindow pew ( container );
00552    pew.Show();
00553    pew.RunModal();
00554 }
00555 

Generated on Tue Jun 24 01:27:41 2008 for Advanced Strategic Command by  doxygen 1.4.2