1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367
|
/***************************************************************************
containerbase.h - description
-------------------
begin : Fri Sep 29 2000
copyright : (C) 2000 by Martin Bickel
email : bickel@asc-hq.org
***************************************************************************/
/*! \file containerbase.h
\brief The base class for buildings and vehicles
*/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef containerbaseH
#define containerbaseH
#include <sigc++/sigc++.h>
#include "typen.h"
#include "containerbasetype.h"
#include "graphics/surface.h"
class Vehicle;
class Player;
/** \brief The parent class of Vehicle and Building;
The name Container originates from Battle Isle, where everything that could load units
was a container
*/
class ContainerBase {
friend class ConvertContainer;
friend class ChangeContainerProperty;
protected:
/** the percantage that this container has already been repaired this turn.
Currently only used for Buildings - and only buildings serialize this property to disk!
The maximum percentage may be limited by a gameparameter
*/
int repairedThisTurn;
//! the map that this container is placed on
GameMap* gamemap;
/** if this container is transported inside a carrier, this is carrier
\note Only vehicles can be transported, building can't */
ContainerBase* cargoParent;
/** displays an image of this container on the surface. The different shaders
(like semi-transparency for submerged stuff) is processed here
\param src The source surface, which is an image of the ContainerBase
\param dest The destination surface, onto which the src image is painted
\param pos The position within dest at which src is painted
\param dir Rotation of the image. Valid range is 0..5, resuling in 0�, 60� 120�, etc
\param shaded If true then the image will not be displayed in color, but in greyscale
\param shadowDist The offset of the shadow of the unit in pixels.
Shadowdist will be added to the x and y coordinates if the position,
resulting in the shadow being in the lower right of the image
0 = no shadow will be drawn
If -1, the shadowDist will be calculated depending on the container's
current height */
void paintField ( const Surface& src, Surface& dest, SPoint pos, int dir, bool shaded, int shadowDist = -1 ) const;
ContainerBase ( const ContainerBaseType* bt, GameMap* map, int player );
public:
virtual bool isBuilding() const = 0;
//! the type descriping all non-instance specific properties of the container
const ContainerBaseType* baseType;
/** returns an image for the Container.
\note Buildings have a size of several fields. The image returned here is therefore not suited
to be painted on the map, as map-painting is done on a per-field basis */
virtual Surface getImage() const = 0;
typedef vector<const Vehicletype*> Production;
const Production& getProduction() const;
Resources getProductionCost( const Vehicletype* unit ) const;
void deleteProductionLine( const Vehicletype* type );
void deleteAllProductionLines();
void addProductionLine( const Vehicletype* type );
void setProductionLines( const Production& production );
private:
mutable Production productionCache;
protected:
Production internalUnitProduction;
public:
//! @name Cargo related functions
//@{
typedef vector<Vehicle*> Cargo;
protected:
Cargo cargo;
private:
//! removes all holes ( = NULL-Pointers) from the vector)
void compactCargo();
public:
const Cargo& getCargo() const { return cargo; };
int getCargoCount() const { return cargo.size(); };
/** returns the cargo slot with index i
Warning: the cargo may contain NULL items. This was deliberately, to allow easier navigation
when the user moves items successivly out of a carrier
*/
Vehicle* getCargo( int i );
//! removes ALL units from cargo
void clearCargo();
SigC::Signal0<void> cargoChanged;
virtual int getArmor() const = 0;
//! a name given by the user or the map creator
ASCString name;
/** adds the unit to the cargo
\param veh the unit to add
\param position specifies a specific cargo slot.
-1 assigns slot automatically. The automatic mode should be used in almost all cases */
void addToCargo( Vehicle* veh, int position = -1 );
//! removes the given unit from the container. \return true if the unit was found, false otherwise
bool removeUnitFromCargo( Vehicle* veh, bool recursive = false );
bool removeUnitFromCargo( int nwid, bool recursive = false );
//! returns the number of loaded units
int vehiclesLoaded ( void ) const;
//! if this is a unit and it is inside a building or transport, returns the transport. NULL otherwise.
ContainerBase* getCarrier() const;
//! searches for a the unit in carrier and optionally all inner carriers
Vehicle* findUnit ( int nwid, bool recursive = true ) const;
/** can the vehicle be loaded. If uheight is passed, it is assumed that vehicle is at
the height 'uheight' and not the actual level of height
*/
bool vehicleLoadable ( const Vehicle* vehicle, int uheight = -1, const bool* attacked = NULL ) const;
/** checks the unloading of a unit type
\param vehicleType the vehicletype for which the unloading is checked
\param carrierHeight assume the carrier ( = this) was on this height (numerical: 0 - 7). If -1, use current height
\return the levels of height on which this unit can be unloaded; or 0 if no unloading is possible
*/
int vehicleUnloadable ( const Vehicletype* vehicleType, int carrierHeight = -1 ) const;
//! returns the unloading system
const ContainerBaseType::TransportationIO* vehicleUnloadSystem ( const Vehicletype* vehicle, int height );
//! returns the levels of height on which this unit can be transfered by docking; or 0 if no unloading is possible
int vehicleDocking ( const Vehicle* vehicle, bool out ) const;
/** Does the vehicle fit into the container? This does not include checking if it can reach the entry
*/
bool vehicleFit ( const Vehicle* vehicle ) const;
//! weight of all loaded units
int cargoWeight() const;
//! returns the nesting depth of the cargo. The unit standing on the field is 0, its cargo is 1, the cargo's cargo 2 ...
int cargoNestingDepth();
private:
//! checks if this vehicle can carry this additional weight and recursively checks all outer vehicle (in case of nested carriers)
bool canCarryWeight( int additionalWeight, const Vehicle* vehicle ) const;
//@}
public:
//! Damage. 0 is no damage, when damage reaches 100 the container is destroyed
int damage;
/** The owner of the container. For historical reasons, this is actually 8 times the player numer
Use getOwner() instead of directly accesing this variable */
int color;
//! returns the number of the player this vehicle/building belongs to
int getOwner() const { return color >> 3; };
//! returns the player this vehicle/building belongs to
Player& getOwningPlayer() const;
//! this is a low level functions that changes the registration in the map. It's called by convert(int,bool)
virtual void registerForNewOwner( int player ) = 0;
virtual void write ( tnstream& stream, bool includeLoadedUnits = true ) const = 0;
virtual void read ( tnstream& stream ) = 0;
//! registers the containers view (=radar) on the map
virtual void addview ( void ) = 0;
//! removes the containers view (=radar) on the map
virtual void removeview ( void ) = 0;
//! @name Resource related functions
//@{
/** scope: 0 = local
1 = resource network
2 = global in all buildings
3 = map wide pool( used only internally! )
*/
virtual int putResource ( int amount, int resourcetype, bool queryonly, int scope = 1, int player = -1 ) = 0;
virtual int getResource ( int amount, int resourcetype, bool queryonly, int scope = 1, int player = -1 ) = 0;
virtual int getAvailableResource ( int amount, int resourcetype, int scope = 1 ) const = 0;
Resources putResource ( const Resources& res, bool queryonly, int scope = 1, int player = -1 );
Resources getResource ( const Resources& res, bool queryonly, int scope = 1, int player = -1 );
Resources getResource ( const Resources& res ) const;
//! returns the resource that the building consumes for its operation.
Resources getResourceUsage ( );
Resources getResourcePlus ( );
//! returns the local storage capacity for the given resource, which depends on the resource mode of the map. \see GameMap::_resourcemode
Resources getStorageCapacity() const;
//! returns the amount of resources that the net which the building is connected to produces each turn
Resources netResourcePlus( ) const;
//! the Resources that are produced each turn
Resources plus;
//! the maximum amount of Resources that the building can produce each turn in the ASC resource mode ; see also #bi_resourceplus
Resources maxplus;
//! the maximum amount of Resources that the building can produce each turn in the BI resource mode ; see also #maxplus
Resources bi_resourceplus;
//@}
//! @name Repairing related functions
//@{
/** when a ContainerBase is repair by this ContainerBase, the default cost
can be customized with this matrix.
\note This effects both reparing another ContainerBase as well as self-repsir */
virtual const ResourceMatrix& getRepairEfficiency() const = 0;
//! is called after a repair is performed. Vehicles use this to reduce their experience.
virtual void postRepair ( int oldDamage ) = 0;
//! checks whether the item can be repaired provided that it is in range
virtual bool canRepair( const ContainerBase* item ) const = 0;
/** returns the maximum amount of damage that the given item can be repaired
\return a value in the range 0 .. item->damage */
int getMaxRepair ( const ContainerBase* item ) const;
int getMaxRepair ( const ContainerBase* item, int newDamage, Resources& cost, bool ignoreCost = false ) const;
int repairItem ( ContainerBase* item, int newDamage = 0 );
//! returns the amount of damate that can still be repaired this turn
virtual int repairableDamage() const = 0;
//@}
GameMap* getMap ( ) const { return gamemap; };
virtual int getIdentification() const = 0;
//! returns the bitmapped level of height. Only one bit will be set, of course
virtual int getHeight() const = 0;
virtual ASCString getName ( ) const = 0;
virtual void setName ( const ASCString& name );
virtual int getAmmo( int type, int num, bool queryOnly ) = 0;
virtual int getAmmo( int type, int num ) const = 0;
virtual int putAmmo( int type, int num, bool queryOnly ) = 0;
virtual int maxAmmo( int type ) const = 0 ;
SigC::Signal0<void> conquered;
SigC::Signal0<void> destroyed;
static SigC::Signal1<void,ContainerBase*> anyContainerDestroyed;
static SigC::Signal1<void,ContainerBase*> anyContainerConquered;
static int calcShadowDist( int binaryHeight );
//! the current amount of research that the building conducts every turn
int researchpoints;
int maxresearchpoints;
//! hook that is called when a player ends his turn
virtual void endOwnTurn( void );
//! hook that is called when any player (including owner) ends turn
virtual void endAnyTurn( void );
//! hook that is called the next round begins ( active player switching from player8 to player1 )
virtual void endRound ( void );
int view;
class Work {
public:
virtual bool finished() = 0;
virtual bool run() = 0;
virtual Resources getPlus() = 0;
virtual Resources getUsage() = 0;
virtual ~Work() {};
};
class WorkClassFactory {
public:
virtual bool available( const ContainerBase* cnt ) = 0;
virtual Work* produce( ContainerBase* cnt, bool queryOnly ) = 0;
virtual ~WorkClassFactory() {};
};
static bool registerWorkClassFactory( WorkClassFactory* wcf, bool ASCmode = true );
private:
typedef list<WorkClassFactory*> WorkerClassList;
static WorkerClassList* workClassFactoriesASC;
static WorkerClassList* workClassFactoriesBI;
public:
Work* spawnWorkClasses( bool justQuery );
virtual MapCoordinate3D getPosition ( ) const = 0;
virtual ~ContainerBase();
virtual vector<MapCoordinate> getCoveredFields() = 0;
};
class TemporaryContainerStorage {
ContainerBase* cb;
tmemorystreambuf buf;
bool _storeCargo;
public:
TemporaryContainerStorage ( ContainerBase* _cb, bool storeCargo = false );
void restore();
};
#endif
|