Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/playability/src/world_entities/weapons/weapon.cc @ 10152

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

finished animation on heavy blaster, started light blaster
code needs some cleanup

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