Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

some minor cleanup

File size: 22.1 KB
Line 
1
2/*
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
12### File Specific
13   main-programmer: Patrick Boenzli
14   co-programmer: Benjamin Grauer, Nicolas Schlumberger
15
16   2005-07-15: Benjamin Grauer: restructurating the entire Class
17*/
18
19#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
20
21#include "weapon.h"
22
23#include "loading/fast_factory.h"
24#include "world_entities/projectiles/projectile.h"
25
26#include "util/loading/factory.h"
27#include "util/loading/load_param.h"
28#include "state.h"
29#include "animation3d.h"
30
31#include "sound_source.h"
32#include "sound_buffer.h"
33#include "resource_sound_buffer.h"
34
35#include "elements/glgui_energywidgetvertical.h"
36
37ObjectListDefinition(Weapon);
38
39////////////////////
40// INITAILISATION //
41// SETTING VALUES //
42////////////////////
43/**
44 * standard constructor
45 *
46 * creates a new weapon
47*/
48Weapon::Weapon ()
49{
50  this->init();
51}
52
53/**
54 * standard deconstructor
55*/
56Weapon::~Weapon ()
57{
58  for (int i = 0; i < WS_STATE_COUNT; i++)
59    if (this->animation[i] && Animation::objectList().exists(animation[i]))  //!< @todo this should check animation3D
60      delete this->animation[i];
61
62  if (OrxSound::SoundSource::objectList().exists(this->soundSource))
63    delete this->soundSource;
64
65//!< PNode must not be deleted, gc takes care of.
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
75}
76
77/**
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 */
82Weapon* Weapon::createWeapon(const ClassID& weaponID)
83{
84  BaseObject* createdObject = Factory::fabricate(weaponID);
85  if (createdObject != NULL)
86  {
87    if (createdObject->isA(Weapon::staticClassID()))
88      return dynamic_cast<Weapon*>(createdObject);
89    else
90    {
91      delete createdObject;
92      return NULL;
93    }
94  }
95  return NULL;
96}
97
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
115/**
116 * initializes the Weapon with ALL default values
117 *
118 * This Sets the default values of the Weapon
119 */
120void Weapon::init()
121{
122  this->registerObject(this, Weapon::_objectList);
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:
127  {
128    this->times[i] = 0.0;                        //< An infinitesimal duration
129    this->animation[i] = NULL;                   //< No animation
130  }
131
132  this->soundSource = new OrxSound::SoundSource(this);       //< Every Weapon has exacty one SoundSource
133
134  this->barrels = 1;  // just to have an initial value
135  this->segs = 0;     // by default there are no movable parts
136  this->activeBarrel = 0; //array wize, 0 means first barrel
137
138  this->preferedSide = -1;
139  this->preferedSlot = -1;
140  this->side = -1;
141
142  //!< forward initialisation of animation and emissionpoints
143  for (int i = 0; i < MAX_BARRELS; i++){
144    this->emissionPoint[i] = new PNode;
145    this->emissionPoint[i]->setParent(this);  //Parenting emissionPoint to Weapons
146    this->emissionPoint[i]->setName("EmissionPoint");
147    this->emissionPoint[i]->addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
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    }
154  }
155
156  this->defaultTarget = NULL;                      //< Nothing is Targeted by default.
157
158  this->projectile = NullClass::staticClassID();         //< No Projectile Class is Connected to this weapon
159  this->projectileFactory = NULL;                  //< No Factory generating Projectiles is selected.
160
161  this->hideInactive = true;                       //< The Weapon will be hidden if it is inactive (by default)
162
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.
165
166  this->energy = 10.0;                             //< The secondary Buffer (before we have to reload)
167  this->energyMax = 10.0;                          //< How much energy can be carried
168  this->capability = WTYPE_ALL;                    //< The Weapon has all capabilities @see W_Capability.
169
170  this->energyWidget = NULL;
171  isEnergyWidgetInitialized = false;               // FIXME, needs to be cleaned
172
173  // set this object to be synchronized over network
174  //this->setSynchronized(true);
175}
176
177/**
178 * loads the Parameters of a Weapon
179 * @param root the XML-Element to load the Weapons settings from
180 */
181void Weapon::loadParams(const TiXmlElement* root)
182{
183  WorldEntity::loadParams(root);
184
185  LoadParam(root, "projectile", this, Weapon, setProjectileTypeC)
186  .describe("Sets the name of the Projectile to load onto the Entity");
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");
193
194  LoadParam(root, "state-duration", this, Weapon, setStateDuration)
195  .describe("Sets the duration of a given state (1: state-Name; 2: duration in seconds)");
196
197  LoadParam(root, "action-sound", this, Weapon, setActionSound)
198  .describe("Sets a given sound to an action (1: action-Name; 2: name of the sound (relative to the Data-Path))");
199}
200
201
202/**
203 * sets the Projectile to use for this weapon.
204 * @param projectile The ID of the Projectile to use
205 * @returns true, if it was sucessfull, false on error
206 *
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.
209 */
210void Weapon::setProjectileType(const ClassID& projectile)
211{
212  this->projectile = projectile;
213  this->projectileFactory = FastFactory::searchFastFactory(projectile);
214  if (this->projectileFactory == NULL)
215  {
216    PRINTF(1)("unable to find FastFactory for the Projectile.\n");
217    return;
218  }
219  else
220  {
221    // grabbing Parameters from the Projectile to have them at hand here.
222    Projectile* pj = dynamic_cast<Projectile*>(this->projectileFactory->resurrect());
223    this->minCharge = pj->getMinEnergy();
224    this->maxCharge = pj->getHealthMax();
225    this->chargeable = pj->isChageable();
226    this->projectileFactory->kill(pj);
227  }
228}
229
230
231/**
232 * @see bool Weapon::setProjectile(ClassID projectile)
233 * @param projectile the Name of the Projectile.
234 */
235void Weapon::setProjectileTypeC(const std::string& projectile)
236{
237  FastFactory* tmpFac = FastFactory::searchFastFactory(projectile);
238  if (tmpFac != NULL)
239  {
240    this->setProjectileType(tmpFac->getStoredID());
241  }
242  else
243  {
244    PRINTF(1)("Projectile %s does not exist for weapon %s\n", projectile.c_str(), this->getCName());
245  }
246}
247
248
249/**
250 * prepares Projectiles of the Weapon
251 * @param count how many Projectiles to create (they will be stored in the ProjectileFactory)
252 */
253void Weapon::prepareProjectiles(unsigned int count)
254{
255  if (likely(this->projectileFactory != NULL))
256    projectileFactory->prepare(count);
257  else
258    PRINTF(2)("unable to create %d projectile for Weapon %s::%s\n", count, this->getClassCName(), this->getCName());
259}
260
261
262/**
263 * resurects and returns a Projectile
264 * @returns a Projectile on success, NULL on error
265 *
266 * errors: 1. (ProjectileFastFactory not Found)
267 *         2. No more Projectiles availiable.
268 */
269Projectile* Weapon::getProjectile()
270{
271  if (likely (this->projectileFactory != NULL))
272  {
273    Projectile* pj = dynamic_cast<Projectile*>(this->projectileFactory->resurrect());
274    pj->toList((OM_LIST)(this->getOMListNumber()+1));
275    return pj;
276  }
277  else
278  {
279    PRINTF(2)("No projectile defined for Weapon %s(%s) can't return any\n", this->getCName(), this->getClassCName());
280    return NULL;
281  }
282}
283
284
285/**
286 * sets the emissionPoint's relative position from the Weapon
287 * @param point the Point relative to the mass-point of the Weapon
288 * @param barrel (optional) define a specific barrel, default = 0
289 */
290void Weapon::setEmissionPoint(const Vector& point, int barrel)
291{
292  this->emissionPoint[barrel]->setRelCoor(point);
293}
294
295// void Weapon::setEmissionPoint(const Vector& point)
296// {
297//   this->emissionPoint[0]->setRelCoor(point);
298// }
299
300/**
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 */
305void Weapon::setActionSound(WeaponAction action, const std::string& soundFile)
306{
307  if (action >= WA_ACTION_COUNT)
308    return;
309
310  else if (!soundFile.empty())
311  {
312    this->soundBuffers[action] = OrxSound::ResourceSoundBuffer(soundFile);
313    if (this->soundBuffers[action].loaded())
314    {
315      PRINTF(4)("Loaded sound %s to action %s.\n", soundFile.c_str(), actionToChar(action));
316    }
317    else
318    {
319      PRINTF(2)("Failed to load sound %s to %s.\n.", soundFile.c_str(), actionToChar(action));
320    }
321  }
322  else
323    this->soundBuffers[action] = OrxSound::SoundBuffer();
324}
325
326
327/**
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).
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 */
337Animation3D* Weapon::getAnimation(WeaponState state, PNode* node)
338{
339  if (state >= WS_STATE_COUNT) // if the state is not known
340    return NULL;
341
342  if (unlikely(this->animation[state] == NULL)) // if the animation does not exist yet create it.
343  {
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    }
351  }
352  else
353    return this->animation[state];
354}
355
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
375OrxGui::GLGuiWidget* Weapon::getEnergyWidget()
376{
377  if ( this->energyWidget == NULL)
378  {
379    this->energyWidget = new OrxGui::GLGuiEnergyWidgetVertical();
380    //this->energyWidget->setDisplayedName(this->getClassCName());
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
397/////////////////
398//  EXECUTION  //
399// GAME ACTION //
400/////////////////
401/**
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{
410  if (likely(this->isActive()))
411  {
412    /** Disabled for releaseFire() from WM*/
413    if (this->requestedAction != WA_NONE)
414      return;
415    PRINTF(5)("%s: next action will be %s in %f seconds\n", this->getCName(), actionToChar(action), this->stateDuration);
416    this->requestedAction = action;
417  }
418  //else
419  else if (unlikely(action == WA_ACTIVATE))
420  {
421    this->currentState = WS_ACTIVATING;
422    this->requestedAction = WA_ACTIVATE;
423  }
424}
425
426
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;
439    this->updateWidgets();
440    return 0.0;
441  }
442  else
443  {
444    this->energy += maxAddEnergy;
445    this->updateWidgets();
446    return energyToAdd - maxAddEnergy;
447  }
448
449}
450
451
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////////////////////////////////////////////////////////////
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 */
467bool Weapon::execute()
468{
469#if DEBUG_LEVEL > 4
470  PRINTF(4)("trying to execute action %s\n", actionToChar(this->requestedAction));
471  this->debug();
472#endif
473
474  WeaponAction action = this->requestedAction;
475  this->requestedAction = WA_NONE;
476
477  switch (action)
478  {
479    case WA_SHOOT:
480    return this->fireW();
481    break;
482    case WA_CHARGE:
483    return this->chargeW();
484    break;
485    case WA_RELOAD:
486    return this->reloadW();
487    break;
488    case WA_DEACTIVATE:
489    return this->deactivateW();
490    break;
491    case WA_ACTIVATE:
492    return this->activateW();
493    break;
494    default:
495    PRINTF(5)("Action %s Not Implemented yet \n", Weapon::actionToChar(action));
496    return false;
497  }
498}
499
500/**
501 * checks and activates the Weapon.
502 * @return true on success.
503 */
504bool Weapon::activateW()
505{
506  //  if (this->currentState == WS_INACTIVE)
507  {
508    // play Sound
509    if (likely(this->soundBuffers[WA_ACTIVATE].loaded()))
510      this->soundSource->play(this->soundBuffers[WA_ACTIVATE]);
511    this->updateWidgets();
512    // activate
513    PRINTF(4)("Activating the Weapon %s\n", this->getCName());
514    this->activate();
515    // setting up for next action
516    this->enterState(WS_ACTIVATING);
517  }
518  return true;
519}
520
521/**
522 * checks and deactivates the Weapon
523 * @return true on success.
524 */
525bool Weapon::deactivateW()
526{
527  //  if (this->currentState != WS_INACTIVE)
528  {
529    PRINTF(4)("Deactivating the Weapon %s\n", this->getCName());
530    // play Sound
531    if (this->soundBuffers[WA_DEACTIVATE].loaded())
532      this->soundSource->play(this->soundBuffers[WA_DEACTIVATE]);
533    // deactivate
534    this->deactivate();
535    this->enterState(WS_DEACTIVATING);
536  }
537
538  return true;
539}
540
541/**
542 * checks and charges the Weapon
543 * @return true on success.
544 */
545bool Weapon::chargeW()
546{
547  if ( this->currentState != WS_INACTIVE && this->energy >= this->minCharge)
548  {
549    // playing Sound
550    if (this->soundBuffers[WA_CHARGE].loaded())
551      this->soundSource->play(this->soundBuffers[WA_CHARGE]);
552
553    // charge
554    this->charge();
555    // setting up for the next state
556    this->enterState(WS_CHARGING);
557  }
558  else // deactivate the Weapon if we do not have enough energy
559  {
560    this->requestAction(WA_RELOAD);
561  }
562  return true;
563}
564
565/**
566 * checks and fires the Weapon
567 * @return true on success.
568 */
569bool Weapon::fireW()
570{
571//   printf("fireW Weapon\n");
572  //if (likely(this->currentState != WS_INACTIVE))
573  if (this->minCharge <= this->energy)
574  {
575    // playing Sound
576    if (this->soundBuffers[WA_SHOOT].loaded())
577      this->soundSource->play(this->soundBuffers[WA_SHOOT]);
578    // fire
579    this->energy -= this->minCharge;
580    this->fire();
581    // setting up for the next state
582    this->enterState(WS_SHOOTING);
583    this->updateWidgets();
584  }
585  else  // reload if we still have the charge
586  {
587    this->requestAction(WA_RELOAD);
588    this->execute();
589  }
590  return true;
591}
592
593/**
594 * checks and Reloads the Weapon
595 * @return true on success.
596 */
597bool Weapon::reloadW()
598{
599  PRINTF(4)("Reloading Weapon %s\n", this->getCName());
600  if (!this->ammoContainer.isNull() &&
601      unlikely(this->energy + this->ammoContainer->getStoredEnergy() < this->minCharge))
602  {
603    //this->requestAction(WA_DEACTIVATE);
604    this->execute();
605    return false;
606  }
607
608
609  if (this->soundBuffers[WA_RELOAD].loaded())
610    this->soundSource->play(this->soundBuffers[WA_RELOAD]);
611
612  if (!this->ammoContainer.isNull())
613    this->ammoContainer->fillWeapon(this);
614  else
615  {
616    this->energy = this->energyMax;
617  }
618  this->updateWidgets();
619  this->reload();
620  this->enterState(WS_RELOADING);
621
622  return true;
623}
624
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{
631  PRINTF(4)("ENTERING STATE %s\n", stateToChar(state));
632  // playing animation if availiable
633  if (likely(this->animation[state] != NULL))
634    this->animation[state]->replay();
635
636  this->stateDuration += this->times[state];
637  this->currentState = state;
638}
639
640///////////////////
641//  WORLD-ENTITY //
642// FUNCTIONALITY //
643///////////////////
644/**
645 * tick signal for time dependent/driven stuff
646*/
647bool Weapon::tickW(float dt)
648{
649  //printf("%s ", stateToChar(this->currentState));
650
651  // setting up the timing properties
652  this->stateDuration -= dt;
653
654  if (this->stateDuration <= 0.0)
655  {
656    if (unlikely (this->currentState == WS_DEACTIVATING))
657    {
658      this->currentState = WS_INACTIVE;
659      return false;
660    }
661    else
662      this->currentState = WS_IDLE;
663
664    if (this->requestedAction != WA_NONE)
665    {
666      this->stateDuration = -dt;
667      this->execute();
668    }
669  }
670  return true;
671}
672
673
674
675
676//////////////////////
677// HELPER FUNCTIONS //
678//////////////////////
679/**
680 * checks wether all the Weapons functions are valid, and if it is possible to go to action with it.
681 * @todo IMPLEMENT the Weapons Check
682 */
683bool Weapon::check() const
684{
685  bool retVal = true;
686
687  //  if (this->projectile == NULL)
688  {
689    PRINTF(1)("There was no projectile assigned to the Weapon.\n");
690    retVal = false;
691  }
692
693
694
695
696  return retVal;
697}
698
699/**
700 * some nice debugging information about this Weapon
701 */
702void Weapon::debug() const
703{
704  PRINT(0)("Weapon-Debug %s, state: %s (duration: %fs), nextAction: %s\n", this->getCName(), Weapon::stateToChar(this->currentState), this->stateDuration, Weapon::actionToChar(requestedAction));
705  PRINT(0)("Energy: max: %f; current: %f; chargeMin: %f, chargeMax %f\n",
706           this->energyMax, this->energy, this->minCharge, this->maxCharge);
707
708
709}
710
711////////////////////////////////////////////////////////
712// static Definitions (transormators for readability) //
713////////////////////////////////////////////////////////
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 */
719WeaponAction Weapon::charToAction(const std::string& action)
720{
721  if (action == "none")
722    return WA_NONE;
723  else if (action == "shoot")
724    return WA_SHOOT;
725  else if (action == "charge")
726    return WA_CHARGE;
727  else if (action == "reload")
728    return WA_RELOAD;
729  else if (action == "acitvate")
730    return WA_ACTIVATE;
731  else if (action == "deactivate")
732    return WA_DEACTIVATE;
733  else if (action == "special1")
734    return WA_SPECIAL1;
735  else
736  {
737    PRINTF(2)("action %s could not be identified.\n", action.c_str());
738    return WA_NONE;
739  }
740}
741
742/**
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  {
751    case WA_SHOOT:
752    return "shoot";
753    break;
754    case WA_CHARGE:
755    return "charge";
756    break;
757    case WA_RELOAD:
758    return "reload";
759    break;
760    case WA_ACTIVATE:
761    return "activate";
762    break;
763    case WA_DEACTIVATE:
764    return "deactivate";
765    break;
766    case WA_SPECIAL1:
767    return "special1";
768    break;
769    default:
770    return "none";
771    break;
772  }
773}
774
775/**
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 */
780WeaponState Weapon::charToState(const std::string& state)
781{
782  if (state == "none")
783    return WS_NONE;
784  else if (state == "shooting")
785    return WS_SHOOTING;
786  else if (state == "charging")
787    return WS_CHARGING;
788  else if (state == "reloading")
789    return WS_RELOADING;
790  else if (state == "activating")
791    return WS_ACTIVATING;
792  else if (state == "deactivating")
793    return WS_DEACTIVATING;
794  else if (state == "inactive")
795    return WS_INACTIVE;
796  else if (state == "idle")
797    return WS_IDLE;
798  else
799  {
800    PRINTF(2)("state %s could not be identified.\n", state.c_str());
801    return WS_NONE;
802  }
803}
804
805/**
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  {
814    case WS_SHOOTING:
815    return "shooting";
816    break;
817    case WS_CHARGING:
818    return "charging";
819    break;
820    case WS_RELOADING:
821    return "reloading";
822    break;
823    case WS_ACTIVATING:
824    return "activating";
825    break;
826    case WS_DEACTIVATING:
827    return "deactivating";
828    break;
829    case WS_IDLE:
830    return "idle";
831    break;
832    case WS_INACTIVE:
833    return "inactive";
834    break;
835    default:
836    return "none";
837    break;
838  }
839}
Note: See TracBrowser for help on using the repository browser.