Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/objectmanager/src/world_entities/weapons/weapon.cc @ 6123

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

orxonox/branches/objectmanager: all the WorldEntities regigister/unregister ath the ObjectManager as they should

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