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

mapfield.cpp

Go to the documentation of this file.
00001 
00005 /***************************************************************************
00006                           mapfield.cpp  -  description
00007                              -------------------
00008     begin                : Tue May 21 2005
00009     copyright            : (C) 2000 by Martin Bickel
00010     email                : bickel@asc-hq.org
00011  ***************************************************************************/
00012 
00013 /***************************************************************************
00014  *                                                                         *
00015  *   This program is free software; you can redistribute it and/or modify  *
00016  *   it under the terms of the GNU General Public License as published by  *
00017  *   the Free Software Foundation; either version 2 of the License, or     *
00018  *   (at your option) any later version.                                   *
00019  *                                                                         *
00020  ***************************************************************************/
00021 
00022 #include <algorithm>
00023 #include <ctime>
00024 #include <cmath>
00025 
00026 #include "global.h"
00027 #include "typen.h"
00028 #include "vehicletype.h"
00029 #include "buildingtype.h"
00030 #include "spfst.h"
00031 
00032 
00033 
00034 tfield :: tfield ( GameMap* gamemap_ )
00035 {
00036   init();
00037   setMap( gamemap_ );
00038 }
00039 
00040 tfield :: tfield (  )
00041 {
00042   init();
00043 }
00044 
00045 
00046 void tfield::init ()
00047 {
00048    bdt.set ( 0 );
00049    typ = NULL;
00050    vehicle = NULL;
00051    building = NULL;
00052    a.temp = 0;
00053    a.temp2 = 0;
00054    temp3 = 0;
00055    temp4 = 0;
00056    visible = 0;
00057    fuel = 0;
00058    material = 0;
00059    resourceview = NULL;
00060    connection = 0;
00061    gamemap = NULL;
00062    viewbonus = 0;
00063 }
00064 
00065 
00066 void tfield::Resourceview::setview( int player, int material, int fuel )
00067 {
00068    visible |= 1 << player;
00069    materialvisible[player] = material;
00070    fuelvisible[player] = fuel;
00071 }
00072 
00073 void tfield::Resourceview::resetview( int player )
00074 {
00075    visible &= ~(1<<player);
00076 }
00077 
00078 
00079 void tfield::endRound( int turn )
00080 {
00081    bool recalc = false;
00082    for ( ObjectContainer::iterator i = objects.begin(); i != objects.end(); ) {
00083       if ( AgeableItem::age( *i )) {
00084          i = objects.erase(i);
00085          recalc = true;
00086       } else
00087          ++i;
00088    }
00089    // remove_if( objects.begin(), objects.end(), Object::age );
00090 
00091    for ( MineContainer::iterator i = mines.begin(); i != mines.end(); ) {
00092       if ( AgeableItem::age( *i )) {
00093          i = mines.erase(i);
00094          recalc = true;
00095       } else
00096          ++i;
00097    }
00098    // remove_if( mines.begin(), mines.end(), Object::age );
00099 
00100    if ( recalc )
00101       setparams();
00102 }
00103 
00104 
00105 void tfield::operator= ( const tfield& f )
00106 {
00107    typ = f.typ;
00108    fuel = f.fuel;
00109    material = f.material;
00110    visible = f.visible;
00111    tempw = f.tempw;
00112    temp3 = f.temp3;
00113    temp4 = f.temp4;
00114    vehicle = f.vehicle;
00115    building = f.building;
00116    if ( f.resourceview ) {
00117       resourceview = new Resourceview;
00118       *resourceview = *f.resourceview;
00119    } else
00120       resourceview = NULL;
00121    mines = f.mines;
00122    objects = f.objects;
00123    connection = f.connection;
00124    bdt = f.bdt;
00125    for ( int i = 0; i < 8; i++ )
00126       view[i] = f.view[i];
00127 }
00128 
00129 
00130 
00131 int tfield :: mineattacks ( const Vehicle* veh )
00132 {
00133    int i = 1;
00134    for ( MineContainer::iterator m = mines.begin(); m != mines.end(); m++, i++ )
00135       if ( m->attacksunit ( veh ))
00136          return i;
00137 
00138    return 0;
00139 }
00140 
00141 Mine& tfield::getMine ( int n )
00142 {
00143   int c = 0;
00144   MineContainer::iterator i;
00145   for ( i = mines.begin(); c < n; i++,c++ );
00146   return *i;
00147 }
00148 
00149 bool  tfield :: addobject( const ObjectType* obj, int dir, bool force )
00150 {
00151    if ( !obj )
00152       return false;
00153 
00154    Object* i = checkforobject ( obj );
00155    if ( !i ) {
00156      int buildable = obj->buildable ( this );
00157      if ( !buildable )
00158           if ( force )
00159              buildable = 1;
00160 
00161      if ( buildable ) {
00162          Object o ( obj );
00163          if ( dir != -1 )
00164             o.dir = dir;
00165          else
00166             o.dir = 0;
00167 
00168          objects.push_back ( o );
00169 
00170          if ( dir == -1 )
00171             calculateobject( getx(), gety(), true, obj, gamemap );
00172 
00173          sortobjects();
00174          setparams();
00175          return true;
00176      } else
00177         return false;
00178      
00179    } else {
00180       if ( dir != -1 )
00181          i->dir |= dir;
00182 
00183       i->lifetimer = obj->lifetime;
00184       sortobjects();
00185       return true;
00186    }
00187 }
00188 
00189 
00190 void tfield :: removeobject( const ObjectType* obj, bool force)
00191 {
00192    if ( !force && building )
00193       return;
00194 
00195    #ifndef karteneditor
00196    if ( !force )
00197       if ( vehicle )
00198          if ( vehicle->color != gamemap->actplayer << 3)
00199            return;
00200    #endif
00201 
00202    if ( !obj ) {
00203       if ( objects.size() ) {
00204          obj = objects.rbegin()->typ;
00205          objects.pop_back();
00206       }
00207    } else
00208       for ( ObjectContainer::iterator o = objects.begin(); o != objects.end(); )
00209          if ( o->typ == obj )
00210             o = objects.erase( o );
00211          else
00212             o++;
00213 
00214    setparams();
00215    if ( obj )
00216       calculateobject( getx(), gety(), true, obj );
00217 }
00218 
00219 void tfield :: deleteeverything ( void )
00220 {
00221    if ( vehicle ) {
00222       delete vehicle;
00223       vehicle = NULL;
00224    }
00225 
00226    if ( building ) {
00227       delete building;
00228       building = NULL;
00229    }
00230 
00231    setparams();
00232 }
00233 
00234 
00235 bool tfield :: unitHere ( const Vehicle* veh )
00236 {
00237    if ( vehicle == veh )
00238       return true;
00239 
00240    if ( vehicle && veh && vehicle->networkid == veh->networkid )
00241       return true;
00242    return false;
00243 }
00244 
00245 ContainerBase* tfield :: getContainer()
00246 {
00247    if ( vehicle )
00248       return vehicle;
00249    else
00250       return building;
00251 }
00252 
00253 
00254 int tfield :: getweather ( void )
00255 {
00256    if ( !typ )
00257       return 0;
00258    for ( int w = 0; w < cwettertypennum; w++ )
00259       if ( typ == typ->terraintype->weather[w] )
00260          return w;
00261    return -1;
00262 }
00263 
00264 void tfield :: setweather ( int weather )
00265 {
00266      if (typ->terraintype->weather[ weather ] ) {
00267         typ = typ->terraintype->weather[ weather ];
00268         setparams();
00269      } else {
00270         if ( weather == 2 )
00271            setweather(1);
00272         else
00273            if ( weather == 5 )
00274               setweather(4);
00275            else
00276               if (weather==4)
00277                  setweather(3);
00278               else {
00279                  typ = typ->terraintype->weather[ 0 ];
00280                  setparams();
00281               }
00282      }
00283 }
00284 
00285 void tfield::setVisibility ( VisibilityStates valtoset, int actplayer ) 
00286 {
00287       int newval = (valtoset ^ 3) << ( 2 * actplayer );
00288       int oneval = 3 << ( 2 * actplayer );
00289 
00290       visible |= oneval;
00291       visible ^= newval;
00292 };
00293 
00294 void tfield::resetView( GameMap* gamemap, int playersToReset )
00295 {
00296    int mask = 0;
00297    for ( int i = 0; i < gamemap->getPlayerCount(); ++i )
00298       if ( !(playersToReset & (1 << i)))
00299          mask |= 3 << (2*i);
00300 
00301    int l = 0;
00302    for ( int y = 0; y < gamemap->ysize; ++y )
00303       for ( int x = 0; x < gamemap->xsize; ++x ) {
00304          tfield& fld = gamemap->field[l++];
00305          fld.visible &= mask;
00306       }
00307         
00308 }
00309 
00310 
00311 
00312 bool compareObjectHeight ( const Object& o1, const Object& o2 )
00313 {
00314    return o1.typ->imageHeight < o2.typ->imageHeight;
00315 }
00316 
00317 void tfield :: sortobjects ( void )
00318 {
00319    sort ( objects.begin(), objects.end(), compareObjectHeight );
00320 }
00321 
00322 bool  tfield :: putmine( int col, int typ, int strength )
00323 {
00324    if ( mineowner() >= 0  && mineowner() != col )
00325       return false;
00326 
00327    if ( mines.size() >= gamemap->getgameparameter ( cgp_maxminesonfield ))
00328       return false;
00329 
00330    MineTypes mt =  MineTypes(typ);
00331    Mine mymine ( mt, strength, col, gamemap );
00332    mines.push_back ( mymine );
00333    return true;
00334 }
00335 
00336 int tfield :: mineowner( void )
00337 {
00338    if ( mines.empty() )
00339       return -1;
00340    else
00341       return mines.begin()->player;
00342 }
00343 
00344 
00345 void tfield :: removemine( int num )
00346 { 
00347    if ( num == -1 )
00348       num = mines.size() - 1;
00349 
00350    int i = 0;
00351    for ( MineContainer::iterator m = mines.begin(); m != mines.end(); i++)
00352       if ( i == num )
00353          m = mines.erase ( m );
00354       else
00355           m++;
00356 }
00357 
00358 
00359 int tfield :: getx( void )
00360 {
00361    int n = this - gamemap->field;
00362    return n % gamemap->xsize;
00363 }
00364 
00365 int tfield :: gety( void )
00366 {
00367    int n = this - gamemap->field;
00368    return n / gamemap->xsize;
00369 }
00370 
00371 
00372 int tfield :: getattackbonus ( void )
00373 {
00374    int a = typ->attackbonus;
00375    for ( ObjectContainer::iterator o = objects.begin(); o != objects.end(); o++ ) {
00376       if ( o->typ->attackbonus_abs != -1 )
00377          a = o->typ->attackbonus_abs;
00378       else
00379          a += o->typ->attackbonus_plus;
00380    }
00381 
00382    if ( a > -8 )
00383       return a;
00384    else
00385       return -7;
00386 }
00387 
00388 int tfield :: getdefensebonus ( void )
00389 {
00390    int a = typ->defensebonus;
00391    for ( ObjectContainer::iterator o = objects.begin(); o != objects.end(); o++ ) {
00392       if ( o->typ->defensebonus_abs != -1 )
00393          a = o->typ->defensebonus_abs;
00394       else
00395          a += o->typ->defensebonus_plus;
00396    }
00397 
00398    if ( a > -8 )
00399       return a;
00400    else
00401       return -7;
00402 }
00403 
00404 ASCString tfield :: getName()
00405 {
00406    ASCString a = typ->terraintype->name;
00407    for ( ObjectContainer::iterator o = objects.begin(); o != objects.end(); o++ ) {
00408       if ( o->typ->namingMethod == ObjectType::ReplaceTerrain )
00409          a = o->typ->getName();
00410       else
00411          if ( o->typ->namingMethod == ObjectType::AddToTerrain )
00412             a += ", " + o->typ->getName();
00413    }
00414    
00415    return a;
00416 }
00417 
00418 
00419 int tfield :: getjamming ( void )
00420 {
00421    int a = typ->basicjamming;
00422    for ( ObjectContainer::iterator o = objects.begin(); o != objects.end(); o++ ) {
00423       if ( o->typ->basicjamming_abs >= 0 )
00424          a = o->typ->basicjamming_abs;
00425       else
00426          a += o->typ->basicjamming_plus;
00427    }
00428    if ( a > 0 )
00429       return a;
00430    else
00431       return 0;
00432 }
00433 
00434 int tfield :: getmovemalus ( const Vehicle* veh )
00435 {
00436    int mnum = mines.size();
00437    if ( mnum ) {
00438       int movemalus = __movemalus.at(veh->typ->movemalustyp);
00439       int col = mineowner();
00440       if ( veh->color == col*8 )
00441          movemalus += movemalus * mine_movemalus_increase * mnum / 100;
00442 
00443       if ( movemalus < minmalq )
00444          fatalError ( "invalid movemalus for terraintype ID %d used on field %d / %d" , typ->terraintype->id, getx(), gety() );
00445 
00446       return movemalus;
00447    } else {
00448       int mm = __movemalus.at(veh->typ->movemalustyp);
00449       if ( mm < minmalq )
00450          fatalError ( "invalid movemalus for terraintype ID %d used on field %d / %d" , typ->terraintype->id, getx(), gety() );
00451       return mm;
00452    }
00453 }
00454 
00455 int tfield :: getmovemalus ( int type )
00456 {
00457   return __movemalus.at(type);
00458 }
00459 
00460 void tfield :: setparams ( void )
00461 {
00462    int i;
00463    bdt = typ->art;
00464 
00465    for ( i = 0; i < cmovemalitypenum; i++ )   {
00466       __movemalus.at(i) = typ->move_malus[i];
00467       if ( __movemalus[i] < minmalq )
00468          fatalError ( "invalid movemalus for terraintype ID %d used on field %d / %d" , typ->terraintype->id, getx(), gety() );
00469    }
00470 
00471    viewbonus = 0;
00472 
00473    for ( ObjectContainer::iterator o = objects.begin(); o != objects.end(); o++ ) {
00474       if ( gamemap->getgameparameter ( cgp_objectsDestroyedByTerrain ))
00475          if ( o->typ->getFieldModification(getweather()).terrainaccess.accessible( bdt ) == -1 ) {
00476             objects.erase(o);
00477             setparams();
00478             return;
00479          }
00480 
00481       bdt  &=  o->typ->getFieldModification(getweather()).terrain_and;
00482       bdt  |=  o->typ->getFieldModification(getweather()).terrain_or;
00483 
00484       for ( i = 0; i < cmovemalitypenum; i++ ) {
00485          __movemalus[i] += o->typ->getFieldModification(getweather()).movemalus_plus[i];
00486          if ( (o->typ->getFieldModification(getweather()).movemalus_abs[i] != 0) && (o->typ->getFieldModification(getweather()).movemalus_abs[i] != -1) )
00487             __movemalus[i] = o->typ->getFieldModification(getweather()).movemalus_abs[i];
00488          if ( __movemalus[i] < minmalq )
00489             __movemalus[i] = minmalq;
00490       }
00491 
00492       viewbonus += o->typ->viewbonus_plus;
00493       if ( o->typ->viewbonus_abs != -1 )
00494          viewbonus = o->typ->viewbonus_plus;
00495    }
00496 
00497    if ( building ) 
00498       if ( this == building->getField( building->typ->entry ))
00499          bdt |= getTerrainBitType(cbbuildingentry);
00500    
00501 }
00502 
00503 Object* tfield :: checkforobject ( const ObjectType*  o )
00504 {
00505    for ( ObjectContainer::iterator i = objects.begin(); i != objects.end(); i++ )
00506       if ( i->typ == o )
00507          return &(*i);
00508 
00509    return NULL;
00510 }
00511 
00512 
00513 tfield::Resourceview :: Resourceview ( void )
00514 {
00515    visible = 0;
00516    memset ( &fuelvisible, 0, sizeof ( fuelvisible ));
00517    memset ( &materialvisible, 0, sizeof ( materialvisible ));
00518 }
00519 
00520 
00521 int tfield :: getMemoryFootprint() const
00522 {
00523    int size = sizeof(*this);
00524    return size;
00525 }
00526 
00527 
00528 tfield :: ~tfield()
00529 {
00530    if ( resourceview ) {
00531       delete resourceview;
00532       resourceview = NULL;
00533    }
00534 }
00535 
00536 

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