Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/blink/src/world_entities/weapons/weapon.cc @ 10667

Last change on this file since 10667 was 10443, checked in by patrick, 18 years ago

weapon now added to the main model

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