Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/world_entities/weapons/weapon.cc @ 10573

Last change on this file since 10573 was 10529, checked in by patrick, 18 years ago

rotatoin for particle systems

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