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

containercontrols.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           cargodialog.cpp  -  description
00003                              -------------------
00004     begin                : Tue Oct 24 2000
00005     copyright            : (C) 2000 by Martin Bickel
00006     email                : bickel@asc-hq.org
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include "containercontrols.h"
00019 #include "unitctrl.h"
00020 #include "gamemap.h"
00021 #include "replay.h"
00022 #include "mapdisplayinterface.h"
00023 #include "itemrepository.h"
00024 
00025 
00026 const GameMap* ContainerConstControls::getMap() const
00027 {
00028    return container->getMap();
00029 }
00030 
00031 
00032 GameMap* ContainerControls::getMap()
00033 {
00034    return container->getMap();
00035 }
00036 
00037 const Player& ContainerConstControls::getPlayer() const
00038 {
00039    return getMap()->player[ getMap()->actplayer ];
00040 }
00041 
00042 
00043 Player& ContainerControls::getPlayer()
00044 {
00045    return getMap()->player[ getMap()->actplayer ];
00046 }
00047 
00048 int ContainerControls::getPlayerNum()
00049 {
00050    return getMap()->actplayer;
00051 }
00052 
00053 
00054 bool ContainerConstControls::unitProductionAvailable() const
00055 {
00056    if ( container->getOwner() == container->getMap()->actplayer )
00057       if ( container->vehiclesLoaded() < container->baseType->maxLoadableUnits )
00058          if ( container->baseType->hasFunction( ContainerBaseType::InternalVehicleProduction ))
00059            return true;
00060 
00061    return false;
00062 }
00063 
00064 int  ContainerConstControls::unitProductionPrerequisites( const Vehicletype* type ) const
00065 {
00066    int l = 0;
00067    Resources cost = container->getProductionCost( type );
00068    if ( getPlayer().research.vehicletypeavailable ( type ) || !getMap()->getgameparameter( cgp_produceOnlyResearchedStuffInternally ) ) {
00069       for ( int r = 0; r < resourceTypeNum; r++ )
00070          if ( container->getAvailableResource( cost.resource(r), r ) < cost.resource(r) )
00071             l |= 1 << r;
00072    } else
00073       l |= 1 << 10;
00074 
00075    if ( !container->vehicleUnloadable( type ) && !container->baseType->hasFunction( ContainerBaseType::ProduceNonLeavableUnits ))
00076       l |= 1 << 11;
00077       
00078    return l;
00079 }
00080 
00081 
00082 Vehicle* ContainerControls::produceUnit( const Vehicletype* type, bool fillWithAmmo, bool fillWithResources )
00083 {
00084    if ( !unitProductionAvailable() )
00085       return NULL;
00086    
00087    if ( unitProductionPrerequisites( type ))
00088       return NULL;
00089 
00090    
00091    Vehicle* vehicle = new Vehicle ( type, getMap(), getPlayerNum() );
00092   
00093    logtoreplayinfo ( rpl_produceunit, type->id , getPlayerNum() * 8, container->getPosition().x, container->getPosition().y, 0, vehicle->networkid );
00094 
00095    vehicle->setnewposition( container->getPosition() );
00096 
00097    if ( getMap()->getgameparameter(cgp_bi3_training) >= 1 ) {
00098       int cnt = 0;
00099 
00100       for ( Player::BuildingList::iterator bi = actmap->player[actmap->actplayer].buildingList.begin(); bi != actmap->player[actmap->actplayer].buildingList.end(); bi++ )
00101          if ( (*bi)->typ->hasFunction( ContainerBaseType::TrainingCenter  ) )
00102             cnt++;
00103 
00104       vehicle->experience += cnt * actmap->getgameparameter(cgp_bi3_training);
00105       if ( vehicle->experience > maxunitexperience )
00106          vehicle->experience = maxunitexperience;
00107    }
00108 
00109    container->getResource( container->getProductionCost( type ), false );
00110 
00111    container->addToCargo( vehicle );
00112 
00113    if ( fillWithAmmo ) 
00114       refillAmmo( vehicle );
00115    
00116    if( fillWithResources )
00117       refillResources( vehicle );
00118 
00119    vehicle->setMovement(0);
00120    vehicle->setAttacked();
00121 
00122    return vehicle;
00123 }
00124 
00125 
00126 Vehicle* ContainerControls::produceUnitHypothetically( const Vehicletype* type )
00127 {
00128    if ( !unitProductionAvailable() )
00129       return NULL;
00130    
00131    if ( unitProductionPrerequisites( type ))
00132       return NULL;
00133 
00134    
00135    Vehicle* vehicle = new Vehicle ( type, getMap(), getPlayerNum() );
00136    vehicle->setnewposition( container->getPosition() );
00137 
00138    if ( getMap()->getgameparameter(cgp_bi3_training) >= 1 ) {
00139       int cnt = 0;
00140 
00141       for ( Player::BuildingList::iterator bi = actmap->player[actmap->actplayer].buildingList.begin(); bi != actmap->player[actmap->actplayer].buildingList.end(); bi++ )
00142          if ( (*bi)->typ->hasFunction( ContainerBaseType::TrainingCenter  ) )
00143             cnt++;
00144 
00145       vehicle->experience += cnt * actmap->getgameparameter(cgp_bi3_training);
00146       if ( vehicle->experience > maxunitexperience )
00147          vehicle->experience = maxunitexperience;
00148    }
00149    return vehicle;
00150 }
00151 
00152 
00153 
00154 VehicleMovement*   ContainerControls :: movement (  Vehicle* eht, bool simpleMode )
00155 {
00156    VehicleMovement* vehicleMovement = new VehicleMovement ( &getDefaultMapDisplay(), NULL );
00157    int mode = 0;
00158    if ( simpleMode )
00159       mode |= VehicleMovement::DisableHeightChange;
00160 
00161    int status = vehicleMovement->execute ( eht, -1, -1, 0, -1, mode );
00162 
00163    if ( status > 0 )
00164       return vehicleMovement;
00165    else {
00166       delete vehicleMovement;
00167       return NULL;
00168    }
00169 }
00170 
00171 
00172 
00173 
00174 int  ContainerControls :: ammoProducable ( int weaptype, int num )
00175 {
00176    if ( container->baseType->hasFunction( ContainerBaseType::AmmoProduction ) ) {
00177       Resources needed = Resources( cwaffenproduktionskosten[weaptype][0] * num, cwaffenproduktionskosten[weaptype][1] * num, cwaffenproduktionskosten[weaptype][2] * num );
00178       Resources avail = container->getResource( needed, true );
00179 
00180       int perc = 100;
00181       for ( int r = 0; r < 3; ++r )
00182          if ( needed.resource(r) > 0 )
00183           perc = min ( 100 * avail.resource(r) / needed.resource(r), perc);
00184 
00185       if ( perc < 0 )
00186          perc = 0;
00187 
00188       return num * perc / 100;
00189    } else {
00190       return 0;
00191    }
00192 }
00193 
00194 
00195 int ContainerControls ::  produceAmmo ( int weaptype, int num )
00196 {
00197    int n = ammoProducable( weaptype, num );
00198    container->getResource ( Resources( cwaffenproduktionskosten[weaptype][0] * n, cwaffenproduktionskosten[weaptype][1] * n, cwaffenproduktionskosten[weaptype][2] * n ), false );
00199    container->putAmmo ( weaptype, n, false );
00200 
00201    logtoreplayinfo ( rpl_produceAmmo, container->getPosition().x, container->getPosition().y, weaptype, n );
00202    return n;
00203 }
00204 
00205 
00206 
00207 int    ContainerControls :: getammunition ( int weapontype, int num, bool abbuchen, bool produceifrequired )
00208 {
00209    int got = container->getAmmo( weapontype, num, !abbuchen );
00210    if ( got < num && container->baseType->hasFunction( ContainerBaseType::AmmoProduction ) && produceifrequired ) {
00211       if ( abbuchen ) {
00212          produceAmmo ( weapontype, num - got );
00213          got += container->getAmmo( weapontype, num - got, !abbuchen );
00214       } else
00215          got += ammoProducable( weapontype, num - got );
00216    }
00217    return got;
00218 }
00219 
00220 bool   ContainerControls :: ammotypeavail ( int type )
00221 {
00222    return true;
00223 }
00224 
00225 
00226 
00227 void  ContainerControls :: fillResource (Vehicle* eht, int resourcetype, int newamount)
00228 {
00229    int oldamount = eht->getResource(maxint, resourcetype, true);
00230    int storable = eht->putResource(newamount - oldamount, resourcetype, true);
00231 
00232    eht->putResource( container->getResource ( storable, resourcetype, false ), resourcetype, false );
00233 
00234    logtoreplayinfo ( rpl_refuel2, eht->xpos, eht->ypos, eht->networkid, int(1000+resourcetype), eht->getTank().resource(resourcetype), oldamount );
00235    logtoreplayinfo ( rpl_refuel3, container->getIdentification(), int(1000+resourcetype), eht->getTank().resource(resourcetype) - oldamount );
00236 };
00237 
00238 
00239 
00240 void  ContainerControls :: fillAmmo (Vehicle* eht, int weapon, int newa )
00241 {
00242    if ( eht->typ->weapons.weapon[ weapon ].requiresAmmo() ) {
00243       if ( newa > eht->typ->weapons.weapon[ weapon ].count )
00244          newa = eht->typ->weapons.weapon[ weapon ].count;
00245 
00246       if ( newa > eht->ammo[weapon] )
00247          eht->ammo[weapon]  +=  getammunition ( eht->typ->weapons.weapon[ weapon ].getScalarWeaponType() , newa - eht->ammo[weapon], 1, true ); // CGameOptions::Instance()->container.autoproduceammunition
00248       else {
00249          container->putAmmo ( eht->typ->weapons.weapon[ weapon ].getScalarWeaponType() , eht->ammo[weapon]  - newa, 1 );
00250          eht->ammo[weapon] = newa;
00251       }
00252    }
00253    logtoreplayinfo ( rpl_refuel, eht->xpos, eht->ypos, eht->networkid, weapon, newa );
00254 
00255 };
00256 
00257 
00258 
00259 void ContainerControls :: refillAmmo ( Vehicle* eht )
00260 {
00261    for (int i = 0; i < eht->typ->weapons.count; i++)
00262       if ( eht->typ->weapons.weapon[ i ].requiresAmmo() )
00263          fillAmmo ( eht, i, maxint );
00264 }
00265 
00266 void ContainerControls :: refillResources ( Vehicle* veh )
00267 {
00268    fillResource ( veh, 1, maxint );
00269    fillResource ( veh, 2, maxint );
00270 }
00271 
00272 void  ContainerControls :: refilleverything ( Vehicle* eht )
00273 {
00274    refillResources( eht );
00275    refillAmmo( eht );
00276 }
00277 
00278 void  ContainerControls :: emptyeverything ( Vehicle* eht )
00279 {
00280    fillResource ( eht, 1, 0 );
00281    fillResource ( eht, 2, 0 );
00282    for (int i = 0; i < eht->typ->weapons.count; i++)
00283       if ( eht->typ->weapons.weapon[ i ].requiresAmmo() )
00284          fillAmmo ( eht, i, 0 );
00285 /*
00286    for ( int i = 0; i < 32; i++ )
00287    if ( eht->loading[i] )
00288    emptyeverything ( eht->loading[i] );
00289 */         
00290 }
00291 
00292 
00293 
00294 Resources ContainerControls :: calcDestructionOutput( Vehicle* veh )
00295 {
00296     int   output;
00297     if ( container->baseType->hasFunction( ContainerBaseType::RecycleUnits ) )
00298        output = recyclingoutput;
00299     else
00300        output = destructoutput;
00301    
00302     Resources res;
00303 
00304     for ( ContainerBase::Cargo::const_iterator i = veh->getCargo().begin(); i != veh->getCargo().end(); i++)
00305        if ( *i )
00306           res += calcDestructionOutput ( *i );
00307    
00308     res.material += veh->typ->productionCost.material * (100 - veh->damage/2 ) / 100 / output;
00309     return res;
00310 }
00311 
00312 
00313 void ContainerControls :: destructUnit( Vehicle* veh )
00314 {
00315    Resources res = calcDestructionOutput ( veh );
00316    emptyeverything ( veh );
00317 
00318    logtoreplayinfo ( rpl_recycleUnit, container->getIdentification(), veh->networkid );
00319 
00320    container->putResource ( res.material, Resources::Material, false );
00321    container->removeUnitFromCargo( veh );
00322    delete veh;
00323 }
00324 
00325 
00326 
00327 bool ContainerControls::unitTrainingAvailable( Vehicle* veh )
00328 {
00329    GameMap* actmap = container->getMap();
00330    if ( actmap->getgameparameter( cgp_bi3_training ) )
00331       return false;
00332 
00333    if ( veh->experience < actmap->getgameparameter ( cgp_maxtrainingexperience ) )
00334       if ( !veh->attacked ) 
00335          if (  container->baseType->hasFunction( ContainerBaseType::TrainingCenter )) {
00336             int num = 0;
00337             int numsh = 0;
00338             for (int i = 0; i < veh->typ->weapons.count; i++ )
00339                if ( veh->typ->weapons.weapon[i].shootable() )
00340                   if ( veh->ammo[i] )
00341                      numsh++;
00342                   else
00343                      num++;
00344 
00345             if ( num == 0  &&  numsh > 0 )
00346                return true;
00347          }
00348          
00349    return false;
00350 }
00351 
00352 
00353 void ContainerControls::trainUnit( Vehicle* veh )
00354 {
00355    GameMap* actmap = container->getMap();
00356    if ( unitTrainingAvailable ( veh ) ) {
00357       veh->experience+= actmap->getgameparameter( cgp_trainingIncrement );
00358       for (int i = 0; i < veh->typ->weapons.count; i++ )
00359          if ( veh->typ->weapons.weapon[i].shootable() )
00360             veh->ammo[i]--;
00361 
00362       if ( veh->experience > actmap->getgameparameter ( cgp_maxtrainingexperience ) )
00363          veh->experience = actmap->getgameparameter ( cgp_maxtrainingexperience );
00364 
00365       veh->attacked = 1;
00366       veh->setMovement ( 0 );
00367       logtoreplayinfo ( rpl_trainunit, container->getPosition().x, container->getPosition().y, veh->experience, veh->networkid );
00368    }
00369 };
00370 
00371 
00372 Resources ContainerControls :: buildProductionLineResourcesNeeded( const Vehicletype* veh )
00373 {
00374    return veh->productionCost * productionLineConstructionCostFactor;
00375 }
00376 
00377 
00378 int ContainerControls :: buildProductionLine ( const Vehicletype* veh  )
00379 {
00380    if ( container->baseType->hasFunction(ContainerBaseType::NoProductionCustomization))
00381       return -505;
00382    
00383    if ( find( container->getProduction().begin(), container->getProduction().end(), veh ) != container->getProduction().end() )
00384       return -503;
00385    
00386    if ( container->getResource( buildProductionLineResourcesNeeded(veh), 1 ) < buildProductionLineResourcesNeeded(veh))
00387       return -500;
00388 
00389    container->getResource( buildProductionLineResourcesNeeded(veh), 0 );
00390    container->addProductionLine( veh );
00391 
00392    logtoreplayinfo ( rpl_buildProdLine, container->getIdentification(), veh->id );
00393 
00394    return 0;
00395 }
00396 
00397 
00398 Resources ContainerControls :: removeProductionLineResourcesNeeded( const Vehicletype* veh )
00399 {
00400    return veh->productionCost * productionLineRemovalCostFactor;
00401 }
00402 
00403 
00404 int ContainerControls :: removeProductionLine ( const Vehicletype* veh  )
00405 {
00406    if ( container->baseType->hasFunction(ContainerBaseType::NoProductionCustomization))
00407       return -505;
00408    
00409    if ( find( container->getProduction().begin(), container->getProduction().end(), veh ) == container->getProduction().end() )
00410       return -502;
00411    
00412    if ( container->getResource( removeProductionLineResourcesNeeded(veh), 1 ) < removeProductionLineResourcesNeeded(veh))
00413       return -500;
00414 
00415    container->getResource( removeProductionLineResourcesNeeded(veh), 0 );
00416    container->deleteProductionLine( veh );
00417 
00418    logtoreplayinfo( rpl_removeProdLine, container->getIdentification(), veh->id );
00419    return 0;
00420 }
00421 
00422 
00423 vector<const Vehicletype*> ContainerControls :: productionLinesBuyable()
00424 {
00425 
00426    vector<const Vehicletype*>  list;
00427    
00428    if ( container->baseType->hasFunction(ContainerBaseType::NoProductionCustomization))
00429       return list;
00430 
00431    Resources r = container->getResource( Resources(maxint, maxint, maxint), 1 );
00432    
00433    for ( int i = 0; i < vehicleTypeRepository.getNum(); ++i ) {
00434       Vehicletype* veh = actmap->getvehicletype_bypos ( i );
00435       if ( veh ) {
00436          bool found = find( container->getProduction().begin(), container->getProduction().end(), veh ) != container->getProduction().end();
00437          if ( container->baseType->vehicleFit ( veh ) && !found )
00438             if ( container->vehicleUnloadable(veh) || container->baseType->hasFunction( ContainerBaseType::ProduceNonLeavableUnits ))
00439                if ( veh->techDependency.available ( container->getMap()->getCurrentPlayer().research ))
00440                   if ( container->baseType->vehicleCategoriesProduceable & (1 << veh->movemalustyp))
00441                      list.push_back( veh );
00442       }
00443    }
00444    return list;
00445 }
00446 
00447 
00448 
00449 bool ContainerControls :: moveUnitUpAvail( const Vehicle* veh )
00450 {
00451    ContainerBase* carr = veh->getCarrier();
00452    if ( carr ) {
00453       ContainerBase* carr2 = carr->getCarrier();
00454       if ( carr2 )
00455          return carr2->vehicleFit( veh );
00456    }
00457    return false;
00458 }
00459 
00460 bool ContainerControls :: moveUnitUp( Vehicle* veh )
00461 {
00462    if ( !veh )
00463       return false;
00464    
00465    if ( !moveUnitUpAvail( veh ) )
00466       return false;
00467    
00468    ContainerBase* source = veh->getCarrier();
00469    if ( source ) {
00470       ContainerBase* target = source->getCarrier();
00471       if ( target  ) {
00472          source->removeUnitFromCargo( veh, false );
00473          target->addToCargo( veh );
00474          
00475          logtoreplayinfo ( rpl_moveUnitUp, target->getPosition().x, target->getPosition().y, veh->networkid );
00476          return true;
00477       }
00478    }
00479    return false;
00480 }
00481 
00482 
00483 bool ContainerControls::moveUnitDownAvail( const Vehicle* movingUnit )
00484 {
00485    return moveUnitDownTargets( movingUnit ).size() > 0;
00486 }
00487 
00488 bool ContainerControls::moveUnitDownAvail( const Vehicle* movingUnit, const Vehicle* newTransport )
00489 {
00490    return newTransport->vehicleFit( movingUnit );  
00491 }
00492 
00493 
00494 vector<Vehicle*> ContainerControls::moveUnitDownTargets( const Vehicle* movingUnit )
00495 {
00496    vector<Vehicle*> targets;
00497    
00498    if ( !container )
00499       return targets;
00500    
00501    for ( ContainerBase::Cargo::const_iterator i = container->getCargo().begin(); i != container->getCargo().end(); ++i )
00502       if ( *i != movingUnit && *i )
00503          if ( moveUnitDownAvail ( movingUnit, *i ))
00504             targets.push_back( *i );
00505 
00506    return targets;
00507 }
00508 
00509 
00510 bool ContainerControls::moveUnitDown( Vehicle* veh, Vehicle* newTransport )
00511 {
00512    if ( !container || !veh || !newTransport )
00513       return false;
00514 
00515    if ( !newTransport->vehicleFit( veh ))
00516       return false;
00517 
00518    container->removeUnitFromCargo( veh );
00519    newTransport->addToCargo( veh );
00520    
00521    logtoreplayinfo ( rpl_moveUnitUpDown, container->getPosition().x, container->getPosition().y, 0, newTransport->networkid, veh->networkid );
00522    return true;
00523 }

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