Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10771 was 10771, checked in by nicolasc, 17 years ago

huge diff
cleaned the individual weapons, moved stuff to weapon.{cc,h}
and some minor fixes which popped up then and when

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