Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 5750 was 5750, checked in by bensch, 18 years ago

orxonox/trunk: merged the WorldEntities into the Trunk.
Merged with command:
svn merge branches/world_entities/ trunk/ -r5516:HEAD

conflics from world_entities changed in favor of branches/world_entity
all other conflict in favor of the trunk

File size: 19.1 KB
RevLine 
[3573]1
[4597]2/*
[3573]3   orxonox - the future of 3D-vertical-scrollers
4
5   Copyright (C) 2004 orx
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 2, or (at your option)
10   any later version.
11
[4826]12### File Specific
[3573]13   main-programmer: Patrick Boenzli
[4832]14   co-programmer: Benjamin Grauer
[4885]15
16   2005-07-15: Benjamin Grauer: restructurating the entire Class
[3573]17*/
18
[4885]19#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
20
[4828]21#include "weapon.h"
22
[5355]23#include "fast_factory.h"
[4834]24#include "projectile.h"
25
[5143]26#include "resource_manager.h"
[4894]27#include "class_list.h"
[4834]28#include "load_param.h"
[4828]29#include "state.h"
[4948]30#include "sound_engine.h"
[4885]31#include "animation3d.h"
[4948]32#include "vector.h"
[3573]33
[4892]34////////////////////
35// INITAILISATION //
36// SETTING VALUES //
37////////////////////
[3870]38/**
[4885]39 * standard constructor
40 *
41 * creates a new weapon
[3575]42*/
[5750]43Weapon::Weapon ()
[3620]44{
[4885]45  this->init();
[3620]46}
[3573]47
[3575]48/**
[4885]49 * standard deconstructor
[3575]50*/
[4597]51Weapon::~Weapon ()
[3573]52{
[4885]53  for (int i = 0; i < WS_STATE_COUNT; i++)
[4894]54    if (this->animation[i] && ClassList::exists(animation[i], CL_ANIMATION))  //!< @todo this should check animation3D
[4885]55      delete this->animation[i];
56  for (int i = 0; i < WA_ACTION_COUNT; i++)
[5302]57    if (this->soundBuffers[i] != NULL && ClassList::exists(this->soundBuffers[i], CL_SOUND_BUFFER))
[4885]58      ResourceManager::getInstance()->unload(this->soundBuffers[i]);
[4959]59
60  if (ClassList::exists(this->soundSource, CL_SOUND_SOURCE))
61    delete this->soundSource;
[4885]62}
[4597]63
[4885]64/**
65 * initializes the Weapon with ALL default values
[5498]66 *
67 * This Sets the default values of the Weapon
[4885]68 */
69void Weapon::init()
70{
[5498]71  this->currentState     = WS_INACTIVE;            //< Normaly the Weapon is Inactive
72  this->requestedAction  = WA_NONE;                //< No action is requested by default
73  this->stateDuration    = 0.0;                    //< All the States have zero duration
74  for (int i = 0; i < WS_STATE_COUNT; i++)         //< Every State has:
[4885]75    {
[5498]76      this->times[i] = 0.0;                        //< An infinitesimal duration
77      this->animation[i] = NULL;                   //< No animation
[4885]78    }
79  for (int i = 0; i < WA_ACTION_COUNT; i++)
[5498]80    this->soundBuffers[i] = NULL;                  //< No Sounds
[3888]81
[5498]82  this->soundSource = new SoundSource(this);       //< Every Weapon has exacty one SoundSource.
83  this->emissionPoint.setParent(this);             //< One EmissionPoint, that is a PNode connected to the weapon. You can set this to the exitting point of the Projectiles
[4885]84
[5498]85  this->projectile = CL_NULL;                      //< No Projectile Class is Connected to this weapon
86  this->projectileFactory = NULL;                  //< No Factory generating Projectiles is selected.
[4885]87
[5498]88  this->hideInactive = true;                       //< The Weapon will be hidden if it is inactive (by default)
[4906]89
[5498]90  this->minCharge = 1.0;                           //< The minimum charge the Weapon can hold is 1 unit.
91  this->maxCharge = 1.0;                           //< The maximum charge is also one unit.
[4927]92
[5498]93  this->energyLoaded = .0;                         //< How much energy is loaded in the Gun. (Weapons must be charged befor usage)
94  this->energyLoadedMax = 5.0;                     //< Each Weapon has a Maximum energy that can be charged onto it
95  this->energy = .0;                               //< The secondary Buffer (before we have to reload)
96  this->energyMax = 10.0;                          //< How much energy can be carried
97  this->capability = WTYPE_ALL;                    //< The Weapon has all capabilities @see W_Capability.
[3573]98}
99
[5498]100/**
101 * loads the Parameters of a Weapon
102 * @param root the XML-Element to load the Weapons settings from
103 */
[4972]104void Weapon::loadParams(const TiXmlElement* root)
105{
106  static_cast<WorldEntity*>(this)->loadParams(root);
107
[5671]108  LoadParam(root, "projectile", this, Weapon, setProjectileType)
[4972]109      .describe("Sets the name of the Projectile to load onto the Entity");
110
[5671]111  LoadParam(root, "emission-point", this, Weapon, setEmissionPoint)
[4972]112      .describe("Sets the Point of emission of this weapon");
113
[5671]114  LoadParam(root, "state-duration", this, Weapon, setStateDuration)
[4972]115      .describe("Sets the duration of a given state (1: state-Name; 2: duration in seconds)");
116
[5671]117  LoadParam(root, "action-sound", this, Weapon, setActionSound)
[4972]118      .describe("Sets a given sound to an action (1: action-Name; 2: name of the sound (relative to the Data-Path))");
119}
120
[4947]121/**
122 * sets the Projectile to use for this weapon.
123 * @param projectile The ID of the Projectile to use
[4950]124 * @returns true, if it was sucessfull, false on error
[4947]125 *
[5498]126 * be aware, that this function does not create Factories, as this is job of Projecitle/Bullet-classes.
127 * What it does, is telling the Weapon what Projectiles it can Emit.
[4947]128 */
[5356]129void Weapon::setProjectileType(ClassID projectile)
[4947]130{
131  if (projectile == CL_NULL)
[4972]132    return;
[4947]133  this->projectile = projectile;
134  this->projectileFactory = FastFactory::searchFastFactory(projectile);
135  if (this->projectileFactory == NULL)
[4979]136  {
137    PRINTF(1)("unable to find FastFactory for the Projectile.\n");
[4972]138    return;
[4979]139  }
[4948]140  else
141  {
142    // grabbing Parameters from the Projectile to have them at hand here.
143    Projectile* pj = dynamic_cast<Projectile*>(this->projectileFactory->resurrect());
144    this->minCharge = pj->getEnergyMin();
145    this->maxCharge = pj->getEnergyMax();
146    this->chargeable = pj->isChageable();
[4979]147    this->projectileFactory->kill(pj);
[4948]148  }
[4979]149}
[3573]150
[4891]151/**
[4950]152 * @see bool Weapon::setProjectile(ClassID projectile)
153 * @param projectile the Name of the Projectile.
154 */
[5356]155void Weapon::setProjectileType(const char* projectile)
[4950]156{
157  if (projectile == NULL)
[4972]158    return;
[4950]159  FastFactory* tmpFac = FastFactory::searchFastFactory(projectile);
160  if (tmpFac != NULL)
161  {
[5356]162    this->setProjectileType(tmpFac->getStoredID());
[4950]163  }
[4972]164  else
165  {
[5356]166    PRINTF(1)("Projectile %s does not exist for weapon %s\n", projectile, this->getName());
[4972]167  }
[4950]168}
169
170/**
[5356]171 * prepares Projectiles of the Weapon
[5498]172 * @param count how many Projectiles to create (they will be stored in the ProjectileFactory)
[5356]173 */
174void Weapon::prepareProjectiles(unsigned int count)
175{
[5357]176  if (likely(this->projectileFactory != NULL))
[5356]177    projectileFactory->prepare(count);
178  else
[5357]179    PRINTF(2)("unable to create %d projectile for Weapon %s (%s)\n", count, this->getName(), this->getClassName());
[5356]180}
181
182/**
183 * resurects and returns a Projectile
[5498]184 * @returns a Projectile on success, NULL on error
185 *
186 * errors: 1. (ProjectileFastFactory not Found)
187 *         2. No more Projectiles availiable.
[5356]188 */
189Projectile* Weapon::getProjectile()
190{
[5357]191  if (likely (this->projectileFactory != NULL))
[5356]192    return dynamic_cast<Projectile*>(this->projectileFactory->resurrect());
193  else
194  {
[5498]195    PRINTF(2)("No projectile defined for Weapon %s(%s) can't return any\n", this->getName(), this->getClassName());
[5356]196    return NULL;
197  }
198}
199
200
201/**
[4892]202 * sets the emissionPoint's relative position from the Weapon
203 * @param point the Point relative to the mass-point of the Weapon
204 */
205void Weapon::setEmissionPoint(const Vector& point)
206{
207  this->emissionPoint.setRelCoor(point);
208}
209
210/**
[4891]211 * assigns a Sound-file to an action
212 * @param action the action the sound should be assigned too
213 * @param soundFile the soundFile's relative position to the data-directory (will be looked for by the ResourceManager)
214 */
[4885]215void Weapon::setActionSound(WeaponAction action, const char* soundFile)
216{
217  if (action >= WA_ACTION_COUNT)
218    return;
[4930]219  if (this->soundBuffers[action] != NULL)
220    ResourceManager::getInstance()->unload(this->soundBuffers[action]);
221
[4885]222  else if (soundFile != NULL)
223  {
224    this->soundBuffers[action] = (SoundBuffer*)ResourceManager::getInstance()->load(soundFile, WAV);
225    if (this->soundBuffers[action] != NULL)
226    {
[4967]227      PRINTF(4)("Loaded sound %s to action %s.\n", soundFile, actionToChar(action));
[4885]228    }
229    else
230    {
[5041]231      PRINTF(2)("Failed to load sound %s to %s.\n.", soundFile, actionToChar(action));
[4885]232    }
233  }
234  else
235    this->soundBuffers[action] = NULL;
236}
237
[4893]238/**
[4895]239 * creates/returns an Animation3D for a certain State.
240 * @param state what State should the Animation be created/returned for
241 * @param node the node this Animation should apply to. (NULL is fine if the animation was already created)
242 * @returns The created animation.Animation(), NULL on error (or if the animation does not yet exist).
[4893]243 *
244 * This function does only generate the Animation Object, and if set it will
245 * automatically be executed, when a certain State is reached.
246 * What this does not do, is set keyframes, you have to operate on the returned animation.
247 */
[4895]248Animation3D* Weapon::getAnimation(WeaponState state, PNode* node)
[4893]249{
[4895]250  if (state >= WS_STATE_COUNT) // if the state is not known
[4893]251    return NULL;
252
[4895]253  if (unlikely(this->animation[state] == NULL)) // if the animation does not exist yet create it.
[4893]254  {
[4895]255    if (likely(node != NULL))
256      return this->animation[state] = new Animation3D(node);
257    else
258    {
259      PRINTF(2)("Node not defined for the Creation of the 3D-animation of state %s\n", stateToChar(state));
260      return NULL;
261    }
[4893]262  }
[4895]263  else
264    return this->animation[state];
[4893]265}
266
[4892]267/////////////////
268//  EXECUTION  //
269// GAME ACTION //
270/////////////////
[4597]271/**
[4885]272 * request an action that should be executed,
273 * @param action the next action to take
274 *
275 * This function must be called instead of the actions (like fire/reload...)
276 * to make all the checks needed to have a usefull WeaponSystem.
277 */
278void Weapon::requestAction(WeaponAction action)
279{
[4906]280  if (likely(this->isActive()))
[4885]281  {
[4906]282    if (this->requestedAction != WA_NONE)
283      return;
[5041]284    PRINTF(5)("next action will be %s in %f seconds\n", actionToChar(action), this->stateDuration);
[4885]285    this->requestedAction = action;
286  }
[4906]287  //else
288  else if (unlikely(action == WA_ACTIVATE))
289  {
290    this->currentState = WS_ACTIVATING;
[4926]291    this->requestedAction = WA_ACTIVATE;
[4906]292  }
[4885]293}
[3577]294
[4890]295/**
296 * adds energy to the Weapon
297 * @param energyToAdd The amount of energy
298 * @returns the amount of energy we did not pick up, because the weapon is already full
299 */
300float Weapon::increaseEnergy(float energyToAdd)
301{
302  float maxAddEnergy = this->energyMax - this->energy;
303
304  if (maxAddEnergy >= energyToAdd)
305  {
306    this->energy += energyToAdd;
307    return 0.0;
308  }
309  else
310  {
311    this->energy += maxAddEnergy;
312    return energyToAdd - maxAddEnergy;
313  }
314}
315
[5498]316////////////////////////////////////////////////////////////
317// WEAPON INTERNALS                                       //
318// These are functions, that no other Weapon should over- //
319// write. No class has direct Access to them, as it is    //
320// quite a complicated process, handling a Weapon from    //
321// the outside                                            //
322////////////////////////////////////////////////////////////
[4891]323/**
324 * executes an action, and with it starts a new State.
325 * @return true, if it worked, false otherwise
326 *
327 * This function checks, wheter the possibility of executing an action is valid,
328 * and does all the necessary stuff, to execute them. If an action does not succeed,
329 * it tries to go around it. (ex. shoot->noAmo->reload()->wait until shoot comes again)
330 */
[4885]331bool Weapon::execute()
[3583]332{
[4906]333#if DEBUG > 4
[4885]334  PRINTF(4)("trying to execute action %s\n", actionToChar(this->requestedAction));
335  this->debug();
[4906]336#endif
[4885]337
[4926]338  WeaponAction action = this->requestedAction;
339  this->requestedAction = WA_NONE;
340
341  switch (action)
[4885]342  {
343    case WA_SHOOT:
[4894]344      return this->fireW();
[4885]345      break;
346    case WA_CHARGE:
[4894]347      return this->chargeW();
[4885]348      break;
349    case WA_RELOAD:
[4894]350      return this->reloadW();
[4885]351      break;
352    case WA_DEACTIVATE:
[4894]353      return this->deactivateW();
[4885]354      break;
355    case WA_ACTIVATE:
[4894]356      return this->activateW();
[4885]357      break;
358  }
[3583]359}
[3577]360
[4597]361/**
[4894]362 * checks and activates the Weapon.
363 * @return true on success.
[4892]364 */
365bool Weapon::activateW()
[3583]366{
[4926]367//  if (this->currentState == WS_INACTIVE)
[4892]368  {
369        // play Sound
[4893]370    if (likely(this->soundBuffers[WA_ACTIVATE] != NULL))
[4892]371      this->soundSource->play(this->soundBuffers[WA_ACTIVATE]);
372        // activate
[4895]373    PRINTF(4)("Activating the Weapon %s\n", this->getName());
[4892]374    this->activate();
[4895]375    // setting up for next action
[4926]376    this->enterState(WS_ACTIVATING);
[4892]377  }
[3583]378}
[3577]379
[4597]380/**
[4894]381 * checks and deactivates the Weapon
382 * @return true on success.
[4892]383 */
384bool Weapon::deactivateW()
[3583]385{
[4949]386//  if (this->currentState != WS_INACTIVE)
[4892]387  {
388    PRINTF(4)("Deactivating the Weapon %s\n", this->getName());
389        // play Sound
390    if (this->soundBuffers[WA_DEACTIVATE] != NULL)
391      this->soundSource->play(this->soundBuffers[WA_DEACTIVATE]);
[4926]392    // deactivate
[4892]393    this->deactivate();
[4926]394    this->enterState(WS_DEACTIVATING);
[4892]395  }
[3583]396}
[3577]397
[4892]398/**
[4894]399 * checks and charges the Weapon
400 * @return true on success.
[4892]401 */
402bool Weapon::chargeW()
[4885]403{
[4892]404  if ( this->currentState != WS_INACTIVE && this->energyLoaded >= this->minCharge)
405  {
406        // playing Sound
407    if (this->soundBuffers[WA_CHARGE] != NULL)
408      this->soundSource->play(this->soundBuffers[WA_CHARGE]);
[4893]409
[4892]410        // charge
411    this->charge();
412        // setting up for the next state
[4926]413    this->enterState(WS_CHARGING);
[4892]414  }
415  else // deactivate the Weapon if we do not have enough energy
416  {
417    this->requestAction(WA_RELOAD);
418  }
[4885]419}
[3573]420
[4892]421/**
[4894]422 * checks and fires the Weapon
423 * @return true on success.
[4892]424 */
425bool Weapon::fireW()
[3575]426{
[4892]427     //if (likely(this->currentState != WS_INACTIVE))
428  if (this->minCharge <= this->energyLoaded)
429  {
430          // playing Sound
431    if (this->soundBuffers[WA_SHOOT] != NULL)
432      this->soundSource->play(this->soundBuffers[WA_SHOOT]);
433          // fire
434    this->fire();
435    this->energyLoaded -= this->minCharge;
436          // setting up for the next state
[4926]437    this->enterState(WS_SHOOTING);
[4892]438  }
439  else  // reload if we still have the charge
440  {
441    this->requestAction(WA_RELOAD);
[4930]442    this->execute();
[4892]443  }
444}
445
446/**
[4894]447 * checks and Reloads the Weapon
448 * @return true on success.
[4892]449 */
450bool Weapon::reloadW()
451{
[4885]452  PRINTF(4)("Reloading Weapon %s\n", this->getName());
[4892]453  if (unlikely(this->energy + this->energyLoaded < this->minCharge))
[4885]454  {
455    this->requestAction(WA_DEACTIVATE);
[4930]456    this->execute();
[4892]457    return false;
[4885]458  }
[3573]459
[4885]460  float chargeSize = this->energyLoadedMax - this->energyLoaded;       //!< The energy to be charged
[3573]461
[4892]462  if (this->soundBuffers[WA_RELOAD] != NULL)
463    this->soundSource->play(this->soundBuffers[WA_RELOAD]);
464
[4885]465  if (chargeSize > this->energy)
466  {
467    this->energyLoaded += this->energy;
468    this->energy = 0.0;
[5041]469    PRINT(5)("Energy depleted\n");
[4885]470  }
471  else
472  {
[5041]473    PRINTF(5)("Loaded %f energy into the Guns Buffer\n", chargeSize);
[4885]474    this->energyLoaded += chargeSize;
475    this->energy -= chargeSize;
476  }
[4892]477  this->reload();
[4926]478  this->enterState(WS_RELOADING);
479}
[3575]480
[4926]481/**
482 * enters the requested State, plays back animations updates the timing.
483 * @param state the state to enter.
484 */
485inline void Weapon::enterState(WeaponState state)
486{
[5041]487  PRINTF(4)("ENTERING STATE %s\n", stateToChar(state));
[4926]488  // playing animation if availiable
489  if (likely(this->animation[state] != NULL))
490    this->animation[state]->replay();
491
492  this->stateDuration = this->times[state] + this->stateDuration;
493  this->currentState = state;
[3575]494}
495
[4927]496///////////////////
497//  WORLD-ENTITY //
498// FUNCTIONALITY //
499///////////////////
[3575]500/**
[4885]501 * tick signal for time dependent/driven stuff
[3575]502*/
[4906]503void Weapon::tickW(float dt)
[4885]504{
[4934]505  //printf("%s ", stateToChar(this->currentState));
[4910]506
[4885]507  // setting up the timing properties
508  this->stateDuration -= dt;
[3575]509
[4949]510  if (this->stateDuration <= 0.0)
[4885]511  {
[4949]512    if (unlikely (this->currentState == WS_DEACTIVATING))
[4885]513    {
[4949]514      this->currentState = WS_INACTIVE;
515      return;
516    }
517    else
518      this->currentState = WS_IDLE;
[4906]519
[4949]520    if (this->requestedAction != WA_NONE)
521    {
522      this->stateDuration = -dt;
523      this->execute();
[4885]524    }
525  }
[4906]526  tick(dt);
[4885]527}
528
[3575]529/**
[4885]530 *  this will draw the weapon
[3575]531*/
[5500]532void Weapon::draw () const
[3575]533{}
534
535
536
537
[3576]538
[4885]539//////////////////////
540// HELPER FUNCTIONS //
541//////////////////////
[3576]542/**
[4891]543 * checks wether all the Weapons functions are valid, and if it is possible to go to action with it.
[5498]544 * @todo IMPLEMENT the Weapons Check
[4891]545 */
546bool Weapon::check() const
547{
548  bool retVal = true;
549
[4947]550//  if (this->projectile == NULL)
[4891]551  {
[5041]552    PRINTF(1)("There was no projectile assigned to the Weapon.\n");
[4891]553    retVal = false;
554  }
555
556
557
558
559  return retVal;
560}
561
562/**
[4885]563 * some nice debugging information about this Weapon
564 */
565void Weapon::debug() const
566{
[5041]567  PRINT(3)("Weapon-Debug %s, state: %s, nextAction: %s\n", this->getName(), Weapon::stateToChar(this->currentState), Weapon::actionToChar(requestedAction));
[4885]568  PRINT(3)("Energy: max: %f; current: %f;  loadedMax: %f; loadedCurrent: %f; chargeMin: %f, chargeMax %f\n",
569            this->energyMax, this->energy, this->energyLoadedMax, this->energyLoaded, this->minCharge, this->maxCharge);
[4967]570
571
[4885]572}
[3575]573
[5498]574////////////////////////////////////////////////////////
575// static Definitions (transormators for readability) //
576////////////////////////////////////////////////////////
[4885]577/**
578 * Converts a String into an Action.
579 * @param action the String input holding the Action.
580 * @return The Action if known, WA_NONE otherwise.
581 */
582WeaponAction Weapon::charToAction(const char* action)
583{
584  if (!strcmp(action, "none"))
585    return WA_NONE;
586  else if (!strcmp(action, "shoot"))
587    return WA_SHOOT;
588  else if (!strcmp(action, "charge"))
589    return WA_CHARGE;
590  else if (!strcmp(action, "reload"))
591    return WA_RELOAD;
592  else if (!strcmp(action, "acitvate"))
593    return WA_ACTIVATE;
594  else if (!strcmp(action, "deactivate"))
595    return WA_DEACTIVATE;
596  else if (!strcmp(action, "special1"))
597    return WA_SPECIAL1;
598  else
599    {
600      PRINTF(2)("action %s could not be identified.\n", action);
601      return WA_NONE;
602    }
603}
[3575]604
605/**
[4885]606 * converts an action into a String
607 * @param action the action to convert
608 * @return a String matching the name of the action
609 */
610const char* Weapon::actionToChar(WeaponAction action)
611{
612  switch (action)
613  {
614    case WA_SHOOT:
615      return "shoot";
616      break;
617    case WA_CHARGE:
618      return "charge";
619      break;
620    case WA_RELOAD:
621      return "reload";
622      break;
623    case WA_ACTIVATE:
624      return "activate";
625      break;
626    case WA_DEACTIVATE:
627      return "deactivate";
628      break;
629    case WA_SPECIAL1:
630      return "special1";
631      break;
632    default:
633      return "none";
634      break;
635  }
636}
[3577]637
638/**
[4885]639 * Converts a String into a State.
640 * @param state the String input holding the State.
641 * @return The State if known, WS_NONE otherwise.
642 */
643WeaponState Weapon::charToState(const char* state)
644{
645  if (!strcmp(state, "none"))
646    return WS_NONE;
647  else if (!strcmp(state, "shooting"))
648    return WS_SHOOTING;
649  else if (!strcmp(state, "charging"))
650    return WS_CHARGING;
651  else if (!strcmp(state, "reloading"))
652    return WS_RELOADING;
653  else if (!strcmp(state, "activating"))
654    return WS_ACTIVATING;
655  else if (!strcmp(state, "deactivating"))
656    return WS_DEACTIVATING;
657  else if (!strcmp(state, "inactive"))
658    return WS_INACTIVE;
659  else if (!strcmp(state, "idle"))
660    return WS_IDLE;
661  else
662    {
663      PRINTF(2)("state %s could not be identified.\n", state);
664      return WS_NONE;
665    }
666}
[3583]667
668/**
[4885]669 * converts a State into a String
670 * @param state the state to convert
671 * @return a String matching the name of the state
672 */
673const char* Weapon::stateToChar(WeaponState state)
674{
675  switch (state)
676  {
677    case WS_SHOOTING:
678      return "shooting";
679      break;
680    case WS_CHARGING:
681      return "charging";
682      break;
683    case WS_RELOADING:
684      return "reloading";
685      break;
686    case WS_ACTIVATING:
687      return "activating";
688      break;
689    case WS_DEACTIVATING:
690      return "deactivating";
691      break;
692    case WS_IDLE:
693      return "idle";
694      break;
[4906]695    case WS_INACTIVE:
696      return "inactive";
697      break;
[4885]698    default:
699      return "none";
700      break;
701  }
702}
Note: See TracBrowser for help on using the repository browser.