Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/presentation/src/world_entities/weapons/weapon.cc

Last change on this file was 10772, checked in by nicolasc, 18 years ago

some minor cleanup

File size: 22.1 KB
RevLine 
[3573]1
[4597]2/*
[3573]3   orxonox - the future of 3D-vertical-scrollers
4
5   Copyright (C) 2004 orx
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 2, or (at your option)
10   any later version.
11
[4826]12### File Specific
[3573]13   main-programmer: Patrick Boenzli
[10772]14   co-programmer: Benjamin Grauer, Nicolas Schlumberger
[4885]15
16   2005-07-15: Benjamin Grauer: restructurating the entire Class
[3573]17*/
18
[4885]19#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
20
[4828]21#include "weapon.h"
22
[9869]23#include "loading/fast_factory.h"
[6434]24#include "world_entities/projectiles/projectile.h"
[4834]25
[7350]26#include "util/loading/factory.h"
[7193]27#include "util/loading/load_param.h"
[4828]28#include "state.h"
[4885]29#include "animation3d.h"
[3573]30
[5930]31#include "sound_source.h"
32#include "sound_buffer.h"
[9869]33#include "resource_sound_buffer.h"
[5930]34
[10368]35#include "elements/glgui_energywidgetvertical.h"
[6438]36
[9869]37ObjectListDefinition(Weapon);
[7350]38
[4892]39////////////////////
40// INITAILISATION //
41// SETTING VALUES //
42////////////////////
[3870]43/**
[4885]44 * standard constructor
45 *
46 * creates a new weapon
[3575]47*/
[5750]48Weapon::Weapon ()
[3620]49{
[4885]50  this->init();
[3620]51}
[3573]52
[3575]53/**
[4885]54 * standard deconstructor
[3575]55*/
[4597]56Weapon::~Weapon ()
[3573]57{
[4885]58  for (int i = 0; i < WS_STATE_COUNT; i++)
[9869]59    if (this->animation[i] && Animation::objectList().exists(animation[i]))  //!< @todo this should check animation3D
[4885]60      delete this->animation[i];
[4959]61
[9869]62  if (OrxSound::SoundSource::objectList().exists(this->soundSource))
[4959]63    delete this->soundSource;
[10771]64
[10772]65//!< PNode must not be deleted, gc takes care of.
[10771]66//   for (int i = 0; i < MAX_BARRELS; i++)
67//   {
68//    delete [] this->shootAnim[i];
69//    delete [] this->objComp[i];
70//   }
71//   delete [] this->emissionPoint;
72//   delete [] this->shootAnim;
73//   delete [] this->objComp;
74
[4885]75}
[4597]76
[4885]77/**
[7350]78 * @brief creates a new Weapon of type weaponID and returns it.
79 * @param weaponID the WeaponID type to create.
80 * @returns the newly created Weapon.
81 */
[9869]82Weapon* Weapon::createWeapon(const ClassID& weaponID)
[7350]83{
84  BaseObject* createdObject = Factory::fabricate(weaponID);
85  if (createdObject != NULL)
86  {
[9869]87    if (createdObject->isA(Weapon::staticClassID()))
[7350]88      return dynamic_cast<Weapon*>(createdObject);
89    else
90    {
91      delete createdObject;
92      return NULL;
93    }
94  }
[8316]95  return NULL;
[7350]96}
97
[9869]98Weapon* Weapon::createWeapon(const std::string& weaponName)
99{
100  BaseObject* createdObject = Factory::fabricate(weaponName);
101  if (createdObject != NULL)
102  {
103    if (createdObject->isA(Weapon::staticClassID()))
104      return dynamic_cast<Weapon*>(createdObject);
105    else
106    {
107      delete createdObject;
108      return NULL;
109    }
110  }
111  return NULL;
112}
113
114
[7350]115/**
[4885]116 * initializes the Weapon with ALL default values
[5498]117 *
118 * This Sets the default values of the Weapon
[4885]119 */
120void Weapon::init()
121{
[9869]122  this->registerObject(this, Weapon::_objectList);
[5498]123  this->currentState     = WS_INACTIVE;            //< Normaly the Weapon is Inactive
124  this->requestedAction  = WA_NONE;                //< No action is requested by default
125  this->stateDuration    = 0.0;                    //< All the States have zero duration
126  for (int i = 0; i < WS_STATE_COUNT; i++)         //< Every State has:
[6438]127  {
128    this->times[i] = 0.0;                        //< An infinitesimal duration
129    this->animation[i] = NULL;                   //< No animation
130  }
[3888]131
[10368]132  this->soundSource = new OrxSound::SoundSource(this);       //< Every Weapon has exacty one SoundSource
[4885]133
[10771]134  this->barrels = 1;  // just to have an initial value
[10772]135  this->segs = 0;     // by default there are no movable parts
136  this->activeBarrel = 0; //array wize, 0 means first barrel
[10368]137
[10443]138  this->preferedSide = -1;
139  this->preferedSlot = -1;
[10771]140  this->side = -1;
[10443]141
[10771]142  //!< forward initialisation of animation and emissionpoints
143  for (int i = 0; i < MAX_BARRELS; i++){
[10368]144    this->emissionPoint[i] = new PNode;
[10698]145    this->emissionPoint[i]->setParent(this);  //Parenting emissionPoint to Weapons
[10368]146    this->emissionPoint[i]->setName("EmissionPoint");
147    this->emissionPoint[i]->addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
[10771]148    for(int j = 0; j < MAX_SEGMENTS; j++)
149    {
150      this->objComp[i][j] = new PNode;
151      this->shootAnim[i][j] = new Animation3D(this->objComp[i][j]);
152      this->shootAnim[i][j]->setInfinity(ANIM_INF_CONSTANT);
153    }
[10368]154  }
155
[6920]156  this->defaultTarget = NULL;                      //< Nothing is Targeted by default.
[6756]157
[9869]158  this->projectile = NullClass::staticClassID();         //< No Projectile Class is Connected to this weapon
[5498]159  this->projectileFactory = NULL;                  //< No Factory generating Projectiles is selected.
[4885]160
[5498]161  this->hideInactive = true;                       //< The Weapon will be hidden if it is inactive (by default)
[4906]162
[5498]163  this->minCharge = 1.0;                           //< The minimum charge the Weapon can hold is 1 unit.
164  this->maxCharge = 1.0;                           //< The maximum charge is also one unit.
[4927]165
[10772]166  this->energy = 10.0;                             //< The secondary Buffer (before we have to reload)
[5498]167  this->energyMax = 10.0;                          //< How much energy can be carried
168  this->capability = WTYPE_ALL;                    //< The Weapon has all capabilities @see W_Capability.
[6438]169
170  this->energyWidget = NULL;
[10772]171  isEnergyWidgetInitialized = false;               // FIXME, needs to be cleaned
[6695]172
173  // set this object to be synchronized over network
174  //this->setSynchronized(true);
[3573]175}
176
[5498]177/**
178 * loads the Parameters of a Weapon
179 * @param root the XML-Element to load the Weapons settings from
180 */
[4972]181void Weapon::loadParams(const TiXmlElement* root)
182{
[6512]183  WorldEntity::loadParams(root);
[4972]184
[7102]185  LoadParam(root, "projectile", this, Weapon, setProjectileTypeC)
[6438]186  .describe("Sets the name of the Projectile to load onto the Entity");
[10443]187
188  LoadParam(root, "energy", this, Weapon, setEnergyMax)
189  .describe("number of shoots/ energy whatever");
190
191  LoadParam(root, "slot", this, Weapon, setPreferedSlot)
192  .describe("slot this weapon will be added");
[4972]193
[5671]194  LoadParam(root, "state-duration", this, Weapon, setStateDuration)
[6438]195  .describe("Sets the duration of a given state (1: state-Name; 2: duration in seconds)");
[4972]196
[5671]197  LoadParam(root, "action-sound", this, Weapon, setActionSound)
[6438]198  .describe("Sets a given sound to an action (1: action-Name; 2: name of the sound (relative to the Data-Path))");
[4972]199}
200
[6728]201
[4947]202/**
203 * sets the Projectile to use for this weapon.
204 * @param projectile The ID of the Projectile to use
[4950]205 * @returns true, if it was sucessfull, false on error
[4947]206 *
[5498]207 * be aware, that this function does not create Factories, as this is job of Projecitle/Bullet-classes.
208 * What it does, is telling the Weapon what Projectiles it can Emit.
[4947]209 */
[9869]210void Weapon::setProjectileType(const ClassID& projectile)
[4947]211{
212  this->projectile = projectile;
213  this->projectileFactory = FastFactory::searchFastFactory(projectile);
214  if (this->projectileFactory == NULL)
[4979]215  {
216    PRINTF(1)("unable to find FastFactory for the Projectile.\n");
[4972]217    return;
[4979]218  }
[4948]219  else
220  {
221    // grabbing Parameters from the Projectile to have them at hand here.
222    Projectile* pj = dynamic_cast<Projectile*>(this->projectileFactory->resurrect());
[6431]223    this->minCharge = pj->getMinEnergy();
[6700]224    this->maxCharge = pj->getHealthMax();
[4948]225    this->chargeable = pj->isChageable();
[4979]226    this->projectileFactory->kill(pj);
[4948]227  }
[4979]228}
[3573]229
[6728]230
[4891]231/**
[4950]232 * @see bool Weapon::setProjectile(ClassID projectile)
233 * @param projectile the Name of the Projectile.
234 */
[7221]235void Weapon::setProjectileTypeC(const std::string& projectile)
[4950]236{
237  FastFactory* tmpFac = FastFactory::searchFastFactory(projectile);
238  if (tmpFac != NULL)
239  {
[5356]240    this->setProjectileType(tmpFac->getStoredID());
[4950]241  }
[4972]242  else
243  {
[9406]244    PRINTF(1)("Projectile %s does not exist for weapon %s\n", projectile.c_str(), this->getCName());
[4972]245  }
[4950]246}
247
[6728]248
[4950]249/**
[5356]250 * prepares Projectiles of the Weapon
[5498]251 * @param count how many Projectiles to create (they will be stored in the ProjectileFactory)
[5356]252 */
253void Weapon::prepareProjectiles(unsigned int count)
254{
[5357]255  if (likely(this->projectileFactory != NULL))
[5356]256    projectileFactory->prepare(count);
257  else
[9406]258    PRINTF(2)("unable to create %d projectile for Weapon %s::%s\n", count, this->getClassCName(), this->getCName());
[5356]259}
260
[6728]261
[5356]262/**
263 * resurects and returns a Projectile
[5498]264 * @returns a Projectile on success, NULL on error
265 *
266 * errors: 1. (ProjectileFastFactory not Found)
267 *         2. No more Projectiles availiable.
[5356]268 */
269Projectile* Weapon::getProjectile()
270{
[5357]271  if (likely (this->projectileFactory != NULL))
[6142]272  {
273    Projectile* pj = dynamic_cast<Projectile*>(this->projectileFactory->resurrect());
274    pj->toList((OM_LIST)(this->getOMListNumber()+1));
275    return pj;
276  }
[5356]277  else
278  {
[9406]279    PRINTF(2)("No projectile defined for Weapon %s(%s) can't return any\n", this->getCName(), this->getClassCName());
[5356]280    return NULL;
281  }
282}
283
284
285/**
[4892]286 * sets the emissionPoint's relative position from the Weapon
287 * @param point the Point relative to the mass-point of the Weapon
[10771]288 * @param barrel (optional) define a specific barrel, default = 0
[4892]289 */
[10368]290void Weapon::setEmissionPoint(const Vector& point, int barrel)
291{
292  this->emissionPoint[barrel]->setRelCoor(point);
293}
294
[10771]295// void Weapon::setEmissionPoint(const Vector& point)
296// {
297//   this->emissionPoint[0]->setRelCoor(point);
298// }
[4892]299
300/**
[4891]301 * assigns a Sound-file to an action
302 * @param action the action the sound should be assigned too
303 * @param soundFile the soundFile's relative position to the data-directory (will be looked for by the ResourceManager)
304 */
[7221]305void Weapon::setActionSound(WeaponAction action, const std::string& soundFile)
[4885]306{
307  if (action >= WA_ACTION_COUNT)
308    return;
[4930]309
[7221]310  else if (!soundFile.empty())
[4885]311  {
[9869]312    this->soundBuffers[action] = OrxSound::ResourceSoundBuffer(soundFile);
313    if (this->soundBuffers[action].loaded())
[4885]314    {
[7221]315      PRINTF(4)("Loaded sound %s to action %s.\n", soundFile.c_str(), actionToChar(action));
[4885]316    }
317    else
318    {
[7221]319      PRINTF(2)("Failed to load sound %s to %s.\n.", soundFile.c_str(), actionToChar(action));
[4885]320    }
321  }
322  else
[9869]323    this->soundBuffers[action] = OrxSound::SoundBuffer();
[4885]324}
325
[6728]326
[4893]327/**
[4895]328 * creates/returns an Animation3D for a certain State.
329 * @param state what State should the Animation be created/returned for
330 * @param node the node this Animation should apply to. (NULL is fine if the animation was already created)
331 * @returns The created animation.Animation(), NULL on error (or if the animation does not yet exist).
[4893]332 *
333 * This function does only generate the Animation Object, and if set it will
334 * automatically be executed, when a certain State is reached.
335 * What this does not do, is set keyframes, you have to operate on the returned animation.
336 */
[4895]337Animation3D* Weapon::getAnimation(WeaponState state, PNode* node)
[4893]338{
[4895]339  if (state >= WS_STATE_COUNT) // if the state is not known
[4893]340    return NULL;
341
[4895]342  if (unlikely(this->animation[state] == NULL)) // if the animation does not exist yet create it.
[4893]343  {
[4895]344    if (likely(node != NULL))
345      return this->animation[state] = new Animation3D(node);
346    else
347    {
348      PRINTF(2)("Node not defined for the Creation of the 3D-animation of state %s\n", stateToChar(state));
349      return NULL;
350    }
[4893]351  }
[4895]352  else
353    return this->animation[state];
[4893]354}
355
[10368]356Animation3D* Weapon::getAnimation(int barrel, int seg, PNode* node)
357{
358  if (barrel >= this->getBarrels() || seg >= this->getSegs()) // if the state is not known
359    return NULL;
360
361  if (unlikely(this->shootAnim[barrel][seg] == NULL)) // if the animation does not exist yet create it.
362  {
363    if (likely(node != NULL))
364      return this->shootAnim[barrel][seg] = new Animation3D(node);
365    else
366    {
367//       PRINTF(2)("Node not defined for the Creation of the 3D-animation of state %s\n", stateToChar(state));
368      return NULL;
369    }
370  }
371  else
372    return this->shootAnim[barrel][seg];
373}
374
[7779]375OrxGui::GLGuiWidget* Weapon::getEnergyWidget()
[6438]376{
[10368]377  if ( this->energyWidget == NULL)
[6438]378  {
[10368]379    this->energyWidget = new OrxGui::GLGuiEnergyWidgetVertical();
380    //this->energyWidget->setDisplayedName(this->getClassCName());
[6438]381    this->energyWidget->setSize2D( 20, 100);
382    this->energyWidget->setMaximum(this->getEnergyMax());
383    this->energyWidget->setValue(this->getEnergy());
384  }
385  return this->energyWidget;
386}
387
388void Weapon::updateWidgets()
389{
390  if (this->energyWidget != NULL)
391  {
392    this->energyWidget->setMaximum(this->energyMax);
393    this->energyWidget->setValue(this->energy);
394  }
395}
396
[4892]397/////////////////
398//  EXECUTION  //
399// GAME ACTION //
400/////////////////
[4597]401/**
[4885]402 * request an action that should be executed,
403 * @param action the next action to take
404 *
405 * This function must be called instead of the actions (like fire/reload...)
406 * to make all the checks needed to have a usefull WeaponSystem.
407 */
408void Weapon::requestAction(WeaponAction action)
409{
[4906]410  if (likely(this->isActive()))
[4885]411  {
[10368]412    /** Disabled for releaseFire() from WM*/
[4906]413    if (this->requestedAction != WA_NONE)
414      return;
[10529]415    PRINTF(5)("%s: next action will be %s in %f seconds\n", this->getCName(), actionToChar(action), this->stateDuration);
[4885]416    this->requestedAction = action;
417  }
[4906]418  //else
419  else if (unlikely(action == WA_ACTIVATE))
420  {
421    this->currentState = WS_ACTIVATING;
[4926]422    this->requestedAction = WA_ACTIVATE;
[4906]423  }
[4885]424}
[3577]425
[6728]426
[4890]427/**
428 * adds energy to the Weapon
429 * @param energyToAdd The amount of energy
430 * @returns the amount of energy we did not pick up, because the weapon is already full
431 */
432float Weapon::increaseEnergy(float energyToAdd)
433{
434  float maxAddEnergy = this->energyMax - this->energy;
435
436  if (maxAddEnergy >= energyToAdd)
437  {
438    this->energy += energyToAdd;
[10368]439    this->updateWidgets();
[4890]440    return 0.0;
441  }
442  else
443  {
444    this->energy += maxAddEnergy;
[10368]445    this->updateWidgets();
[4890]446    return energyToAdd - maxAddEnergy;
447  }
[10443]448
[4890]449}
450
[6728]451
[5498]452////////////////////////////////////////////////////////////
453// WEAPON INTERNALS                                       //
454// These are functions, that no other Weapon should over- //
455// write. No class has direct Access to them, as it is    //
456// quite a complicated process, handling a Weapon from    //
457// the outside                                            //
458////////////////////////////////////////////////////////////
[4891]459/**
460 * executes an action, and with it starts a new State.
461 * @return true, if it worked, false otherwise
462 *
463 * This function checks, wheter the possibility of executing an action is valid,
464 * and does all the necessary stuff, to execute them. If an action does not succeed,
465 * it tries to go around it. (ex. shoot->noAmo->reload()->wait until shoot comes again)
466 */
[4885]467bool Weapon::execute()
[3583]468{
[7729]469#if DEBUG_LEVEL > 4
[4885]470  PRINTF(4)("trying to execute action %s\n", actionToChar(this->requestedAction));
471  this->debug();
[4906]472#endif
[4885]473
[4926]474  WeaponAction action = this->requestedAction;
475  this->requestedAction = WA_NONE;
476
477  switch (action)
[4885]478  {
[7350]479    case WA_SHOOT:
[9869]480    return this->fireW();
481    break;
[7350]482    case WA_CHARGE:
[9869]483    return this->chargeW();
484    break;
[7350]485    case WA_RELOAD:
[9869]486    return this->reloadW();
487    break;
[7350]488    case WA_DEACTIVATE:
[9869]489    return this->deactivateW();
490    break;
[7350]491    case WA_ACTIVATE:
[9869]492    return this->activateW();
493    break;
[8316]494    default:
[10368]495    PRINTF(5)("Action %s Not Implemented yet \n", Weapon::actionToChar(action));
[9869]496    return false;
[4885]497  }
[3583]498}
[3577]499
[4597]500/**
[4894]501 * checks and activates the Weapon.
502 * @return true on success.
[4892]503 */
504bool Weapon::activateW()
[3583]505{
[6438]506  //  if (this->currentState == WS_INACTIVE)
[4892]507  {
[6433]508    // play Sound
[9869]509    if (likely(this->soundBuffers[WA_ACTIVATE].loaded()))
[4892]510      this->soundSource->play(this->soundBuffers[WA_ACTIVATE]);
[6444]511    this->updateWidgets();
[6438]512    // activate
[9406]513    PRINTF(4)("Activating the Weapon %s\n", this->getCName());
[4892]514    this->activate();
[4895]515    // setting up for next action
[4926]516    this->enterState(WS_ACTIVATING);
[4892]517  }
[8316]518  return true;
[3583]519}
[3577]520
[4597]521/**
[4894]522 * checks and deactivates the Weapon
523 * @return true on success.
[4892]524 */
525bool Weapon::deactivateW()
[3583]526{
[6438]527  //  if (this->currentState != WS_INACTIVE)
[4892]528  {
[9406]529    PRINTF(4)("Deactivating the Weapon %s\n", this->getCName());
[6438]530    // play Sound
[9869]531    if (this->soundBuffers[WA_DEACTIVATE].loaded())
[4892]532      this->soundSource->play(this->soundBuffers[WA_DEACTIVATE]);
[4926]533    // deactivate
[4892]534    this->deactivate();
[4926]535    this->enterState(WS_DEACTIVATING);
[4892]536  }
[8316]537
538  return true;
[3583]539}
[3577]540
[4892]541/**
[4894]542 * checks and charges the Weapon
543 * @return true on success.
[4892]544 */
545bool Weapon::chargeW()
[4885]546{
[6671]547  if ( this->currentState != WS_INACTIVE && this->energy >= this->minCharge)
[4892]548  {
[6438]549    // playing Sound
[9869]550    if (this->soundBuffers[WA_CHARGE].loaded())
[4892]551      this->soundSource->play(this->soundBuffers[WA_CHARGE]);
[4893]552
[6438]553    // charge
[4892]554    this->charge();
[6438]555    // setting up for the next state
[4926]556    this->enterState(WS_CHARGING);
[4892]557  }
558  else // deactivate the Weapon if we do not have enough energy
559  {
560    this->requestAction(WA_RELOAD);
561  }
[8316]562  return true;
[4885]563}
[3573]564
[4892]565/**
[4894]566 * checks and fires the Weapon
567 * @return true on success.
[4892]568 */
569bool Weapon::fireW()
[3575]570{
[10368]571//   printf("fireW Weapon\n");
[6438]572  //if (likely(this->currentState != WS_INACTIVE))
[6671]573  if (this->minCharge <= this->energy)
[4892]574  {
[6438]575    // playing Sound
[9869]576    if (this->soundBuffers[WA_SHOOT].loaded())
[4892]577      this->soundSource->play(this->soundBuffers[WA_SHOOT]);
[6438]578    // fire
[6671]579    this->energy -= this->minCharge;
[4892]580    this->fire();
[6438]581    // setting up for the next state
[4926]582    this->enterState(WS_SHOOTING);
[10368]583    this->updateWidgets();
[4892]584  }
585  else  // reload if we still have the charge
586  {
587    this->requestAction(WA_RELOAD);
[4930]588    this->execute();
[4892]589  }
[8316]590  return true;
[4892]591}
592
593/**
[4894]594 * checks and Reloads the Weapon
595 * @return true on success.
[4892]596 */
597bool Weapon::reloadW()
598{
[9406]599  PRINTF(4)("Reloading Weapon %s\n", this->getCName());
[9869]600  if (!this->ammoContainer.isNull() &&
[7350]601      unlikely(this->energy + this->ammoContainer->getStoredEnergy() < this->minCharge))
[4885]602  {
[10368]603    //this->requestAction(WA_DEACTIVATE);
[4930]604    this->execute();
[4892]605    return false;
[4885]606  }
[3573]607
608
[9869]609  if (this->soundBuffers[WA_RELOAD].loaded())
[4892]610    this->soundSource->play(this->soundBuffers[WA_RELOAD]);
611
[9869]612  if (!this->ammoContainer.isNull())
[6671]613    this->ammoContainer->fillWeapon(this);
[4885]614  else
615  {
[6671]616    this->energy = this->energyMax;
[4885]617  }
[6444]618  this->updateWidgets();
[4892]619  this->reload();
[4926]620  this->enterState(WS_RELOADING);
[8316]621
622  return true;
[4926]623}
[3575]624
[4926]625/**
626 * enters the requested State, plays back animations updates the timing.
627 * @param state the state to enter.
628 */
629inline void Weapon::enterState(WeaponState state)
630{
[5041]631  PRINTF(4)("ENTERING STATE %s\n", stateToChar(state));
[4926]632  // playing animation if availiable
633  if (likely(this->animation[state] != NULL))
634    this->animation[state]->replay();
635
[6728]636  this->stateDuration += this->times[state];
[4926]637  this->currentState = state;
[3575]638}
639
[4927]640///////////////////
641//  WORLD-ENTITY //
642// FUNCTIONALITY //
643///////////////////
[3575]644/**
[4885]645 * tick signal for time dependent/driven stuff
[3575]646*/
[6736]647bool Weapon::tickW(float dt)
[4885]648{
[4934]649  //printf("%s ", stateToChar(this->currentState));
[4910]650
[4885]651  // setting up the timing properties
652  this->stateDuration -= dt;
[3575]653
[4949]654  if (this->stateDuration <= 0.0)
[4885]655  {
[4949]656    if (unlikely (this->currentState == WS_DEACTIVATING))
[4885]657    {
[4949]658      this->currentState = WS_INACTIVE;
[6736]659      return false;
[4949]660    }
661    else
662      this->currentState = WS_IDLE;
[4906]663
[4949]664    if (this->requestedAction != WA_NONE)
665    {
666      this->stateDuration = -dt;
667      this->execute();
[4885]668    }
669  }
[6736]670  return true;
[4885]671}
672
[3575]673
674
675
[4885]676//////////////////////
677// HELPER FUNCTIONS //
678//////////////////////
[3576]679/**
[4891]680 * checks wether all the Weapons functions are valid, and if it is possible to go to action with it.
[5498]681 * @todo IMPLEMENT the Weapons Check
[4891]682 */
683bool Weapon::check() const
684{
685  bool retVal = true;
686
[6438]687  //  if (this->projectile == NULL)
[4891]688  {
[5041]689    PRINTF(1)("There was no projectile assigned to the Weapon.\n");
[4891]690    retVal = false;
691  }
692
693
694
695
696  return retVal;
697}
698
699/**
[4885]700 * some nice debugging information about this Weapon
701 */
702void Weapon::debug() const
703{
[9406]704  PRINT(0)("Weapon-Debug %s, state: %s (duration: %fs), nextAction: %s\n", this->getCName(), Weapon::stateToChar(this->currentState), this->stateDuration, Weapon::actionToChar(requestedAction));
[6671]705  PRINT(0)("Energy: max: %f; current: %f; chargeMin: %f, chargeMax %f\n",
706           this->energyMax, this->energy, this->minCharge, this->maxCharge);
[4967]707
708
[4885]709}
[3575]710
[5498]711////////////////////////////////////////////////////////
712// static Definitions (transormators for readability) //
713////////////////////////////////////////////////////////
[4885]714/**
715 * Converts a String into an Action.
716 * @param action the String input holding the Action.
717 * @return The Action if known, WA_NONE otherwise.
718 */
[7221]719WeaponAction Weapon::charToAction(const std::string& action)
[4885]720{
[7221]721  if (action == "none")
[4885]722    return WA_NONE;
[7221]723  else if (action == "shoot")
[4885]724    return WA_SHOOT;
[7221]725  else if (action == "charge")
[4885]726    return WA_CHARGE;
[7221]727  else if (action == "reload")
[4885]728    return WA_RELOAD;
[7221]729  else if (action == "acitvate")
[4885]730    return WA_ACTIVATE;
[7221]731  else if (action == "deactivate")
[4885]732    return WA_DEACTIVATE;
[7221]733  else if (action == "special1")
[4885]734    return WA_SPECIAL1;
735  else
[6438]736  {
[7221]737    PRINTF(2)("action %s could not be identified.\n", action.c_str());
[6438]738    return WA_NONE;
739  }
[4885]740}
[3575]741
742/**
[4885]743 * converts an action into a String
744 * @param action the action to convert
745 * @return a String matching the name of the action
746 */
747const char* Weapon::actionToChar(WeaponAction action)
748{
749  switch (action)
750  {
[7350]751    case WA_SHOOT:
[9869]752    return "shoot";
753    break;
[7350]754    case WA_CHARGE:
[9869]755    return "charge";
756    break;
[7350]757    case WA_RELOAD:
[9869]758    return "reload";
759    break;
[7350]760    case WA_ACTIVATE:
[9869]761    return "activate";
762    break;
[7350]763    case WA_DEACTIVATE:
[9869]764    return "deactivate";
765    break;
[7350]766    case WA_SPECIAL1:
[9869]767    return "special1";
768    break;
[7350]769    default:
[9869]770    return "none";
771    break;
[4885]772  }
773}
[3577]774
775/**
[4885]776 * Converts a String into a State.
777 * @param state the String input holding the State.
778 * @return The State if known, WS_NONE otherwise.
779 */
[7221]780WeaponState Weapon::charToState(const std::string& state)
[4885]781{
[7221]782  if (state == "none")
[4885]783    return WS_NONE;
[7221]784  else if (state == "shooting")
[4885]785    return WS_SHOOTING;
[7221]786  else if (state == "charging")
[4885]787    return WS_CHARGING;
[7221]788  else if (state == "reloading")
[4885]789    return WS_RELOADING;
[7221]790  else if (state == "activating")
[4885]791    return WS_ACTIVATING;
[7221]792  else if (state == "deactivating")
[4885]793    return WS_DEACTIVATING;
[7221]794  else if (state == "inactive")
[4885]795    return WS_INACTIVE;
[7221]796  else if (state == "idle")
[4885]797    return WS_IDLE;
798  else
[6438]799  {
[7221]800    PRINTF(2)("state %s could not be identified.\n", state.c_str());
[6438]801    return WS_NONE;
802  }
[4885]803}
[3583]804
805/**
[4885]806 * converts a State into a String
807 * @param state the state to convert
808 * @return a String matching the name of the state
809 */
810const char* Weapon::stateToChar(WeaponState state)
811{
812  switch (state)
813  {
[7350]814    case WS_SHOOTING:
[9869]815    return "shooting";
816    break;
[7350]817    case WS_CHARGING:
[9869]818    return "charging";
819    break;
[7350]820    case WS_RELOADING:
[9869]821    return "reloading";
822    break;
[7350]823    case WS_ACTIVATING:
[9869]824    return "activating";
825    break;
[7350]826    case WS_DEACTIVATING:
[9869]827    return "deactivating";
828    break;
[7350]829    case WS_IDLE:
[9869]830    return "idle";
831    break;
[7350]832    case WS_INACTIVE:
[9869]833    return "inactive";
834    break;
[7350]835    default:
[9869]836    return "none";
837    break;
[4885]838  }
839}
Note: See TracBrowser for help on using the repository browser.