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
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
[9869]23#include "loading/fast_factory.h"
[6434]24#include "world_entities/projectiles/projectile.h"
[4834]25
[7350]26#include "util/loading/factory.h"
[7193]27#include "util/loading/load_param.h"
[4828]28#include "state.h"
[4885]29#include "animation3d.h"
[3573]30
[5930]31#include "sound_source.h"
32#include "sound_buffer.h"
[9869]33#include "resource_sound_buffer.h"
[5930]34
[8976]35#include "elements/glgui_energywidget.h"
[6438]36
[9869]37ObjectListDefinition(Weapon);
[7350]38
[4892]39////////////////////
40// INITAILISATION //
41// SETTING VALUES //
42////////////////////
[3870]43/**
[4885]44 * standard constructor
45 *
46 * creates a new weapon
[3575]47*/
[5750]48Weapon::Weapon ()
[3620]49{
[4885]50  this->init();
[3620]51}
[3573]52
[3575]53/**
[4885]54 * standard deconstructor
[3575]55*/
[4597]56Weapon::~Weapon ()
[3573]57{
[4885]58  for (int i = 0; i < WS_STATE_COUNT; i++)
[9869]59    if (this->animation[i] && Animation::objectList().exists(animation[i]))  //!< @todo this should check animation3D
[4885]60      delete this->animation[i];
[4959]61
[9869]62  if (OrxSound::SoundSource::objectList().exists(this->soundSource))
[4959]63    delete this->soundSource;
[4885]64}
[4597]65
[4885]66/**
[7350]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 */
[9869]71Weapon* Weapon::createWeapon(const ClassID& weaponID)
[7350]72{
73  BaseObject* createdObject = Factory::fabricate(weaponID);
74  if (createdObject != NULL)
75  {
[9869]76    if (createdObject->isA(Weapon::staticClassID()))
[7350]77      return dynamic_cast<Weapon*>(createdObject);
78    else
79    {
80      delete createdObject;
81      return NULL;
82    }
83  }
[8316]84  return NULL;
[7350]85}
86
[9869]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
[7350]104/**
[4885]105 * initializes the Weapon with ALL default values
[5498]106 *
107 * This Sets the default values of the Weapon
[4885]108 */
109void Weapon::init()
110{
[9869]111  this->registerObject(this, Weapon::_objectList);
[5498]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:
[6438]116  {
117    this->times[i] = 0.0;                        //< An infinitesimal duration
118    this->animation[i] = NULL;                   //< No animation
119  }
[3888]120
[10140]121  this->soundSource = new OrxSound::SoundSource(this);       //< Every Weapon has exacty one SoundSource
[4885]122
[10140]123  this->barrels = 1;
124  this->segs = 1;
125
[10152]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
[10140]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
[6920]138  this->defaultTarget = NULL;                      //< Nothing is Targeted by default.
[6756]139
[9869]140  this->projectile = NullClass::staticClassID();         //< No Projectile Class is Connected to this weapon
[5498]141  this->projectileFactory = NULL;                  //< No Factory generating Projectiles is selected.
[4885]142
[5498]143  this->hideInactive = true;                       //< The Weapon will be hidden if it is inactive (by default)
[4906]144
[5498]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.
[4927]147
[6671]148  this->energy = 10;                               //< The secondary Buffer (before we have to reload)
[5498]149  this->energyMax = 10.0;                          //< How much energy can be carried
150  this->capability = WTYPE_ALL;                    //< The Weapon has all capabilities @see W_Capability.
[6438]151
152  this->energyWidget = NULL;
[6695]153
154  // set this object to be synchronized over network
155  //this->setSynchronized(true);
[3573]156}
157
[5498]158/**
[10152]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/**
[5498]199 * loads the Parameters of a Weapon
200 * @param root the XML-Element to load the Weapons settings from
201 */
[4972]202void Weapon::loadParams(const TiXmlElement* root)
203{
[6512]204  WorldEntity::loadParams(root);
[4972]205
[7102]206  LoadParam(root, "projectile", this, Weapon, setProjectileTypeC)
[6438]207  .describe("Sets the name of the Projectile to load onto the Entity");
[10140]208/*
[5671]209  LoadParam(root, "emission-point", this, Weapon, setEmissionPoint)
[10140]210  .describe("Sets the Point of emission of this weapon (1: EmmsionVector; 2: EmissionPoint)");*/
[4972]211
[5671]212  LoadParam(root, "state-duration", this, Weapon, setStateDuration)
[6438]213  .describe("Sets the duration of a given state (1: state-Name; 2: duration in seconds)");
[4972]214
[5671]215  LoadParam(root, "action-sound", this, Weapon, setActionSound)
[6438]216  .describe("Sets a given sound to an action (1: action-Name; 2: name of the sound (relative to the Data-Path))");
[4972]217}
218
[6728]219
[4947]220/**
221 * sets the Projectile to use for this weapon.
222 * @param projectile The ID of the Projectile to use
[4950]223 * @returns true, if it was sucessfull, false on error
[4947]224 *
[5498]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.
[4947]227 */
[9869]228void Weapon::setProjectileType(const ClassID& projectile)
[4947]229{
230  this->projectile = projectile;
231  this->projectileFactory = FastFactory::searchFastFactory(projectile);
232  if (this->projectileFactory == NULL)
[4979]233  {
234    PRINTF(1)("unable to find FastFactory for the Projectile.\n");
[4972]235    return;
[4979]236  }
[4948]237  else
238  {
239    // grabbing Parameters from the Projectile to have them at hand here.
240    Projectile* pj = dynamic_cast<Projectile*>(this->projectileFactory->resurrect());
[6431]241    this->minCharge = pj->getMinEnergy();
[6700]242    this->maxCharge = pj->getHealthMax();
[4948]243    this->chargeable = pj->isChageable();
[4979]244    this->projectileFactory->kill(pj);
[4948]245  }
[4979]246}
[3573]247
[6728]248
[4891]249/**
[4950]250 * @see bool Weapon::setProjectile(ClassID projectile)
251 * @param projectile the Name of the Projectile.
252 */
[7221]253void Weapon::setProjectileTypeC(const std::string& projectile)
[4950]254{
255  FastFactory* tmpFac = FastFactory::searchFastFactory(projectile);
256  if (tmpFac != NULL)
257  {
[5356]258    this->setProjectileType(tmpFac->getStoredID());
[4950]259  }
[4972]260  else
261  {
[9406]262    PRINTF(1)("Projectile %s does not exist for weapon %s\n", projectile.c_str(), this->getCName());
[4972]263  }
[4950]264}
265
[6728]266
[4950]267/**
[5356]268 * prepares Projectiles of the Weapon
[5498]269 * @param count how many Projectiles to create (they will be stored in the ProjectileFactory)
[5356]270 */
271void Weapon::prepareProjectiles(unsigned int count)
272{
[5357]273  if (likely(this->projectileFactory != NULL))
[5356]274    projectileFactory->prepare(count);
275  else
[9406]276    PRINTF(2)("unable to create %d projectile for Weapon %s::%s\n", count, this->getClassCName(), this->getCName());
[5356]277}
278
[6728]279
[5356]280/**
281 * resurects and returns a Projectile
[5498]282 * @returns a Projectile on success, NULL on error
283 *
284 * errors: 1. (ProjectileFastFactory not Found)
285 *         2. No more Projectiles availiable.
[5356]286 */
287Projectile* Weapon::getProjectile()
288{
[5357]289  if (likely (this->projectileFactory != NULL))
[6142]290  {
291    Projectile* pj = dynamic_cast<Projectile*>(this->projectileFactory->resurrect());
292    pj->toList((OM_LIST)(this->getOMListNumber()+1));
293    return pj;
294  }
[5356]295  else
296  {
[9406]297    PRINTF(2)("No projectile defined for Weapon %s(%s) can't return any\n", this->getCName(), this->getClassCName());
[5356]298    return NULL;
299  }
300}
301
302
303/**
[4892]304 * sets the emissionPoint's relative position from the Weapon
305 * @param point the Point relative to the mass-point of the Weapon
306 */
[10140]307void Weapon::setEmissionPoint(const Vector& point, int barrel)
308{
309  this->emissionPoint[barrel]->setRelCoor(point);
310}
311
[4892]312void Weapon::setEmissionPoint(const Vector& point)
313{
[10140]314  this->emissionPoint[0]->setRelCoor(point);
[4892]315}
316
317/**
[4891]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 */
[7221]322void Weapon::setActionSound(WeaponAction action, const std::string& soundFile)
[4885]323{
324  if (action >= WA_ACTION_COUNT)
325    return;
[4930]326
[7221]327  else if (!soundFile.empty())
[4885]328  {
[9869]329    this->soundBuffers[action] = OrxSound::ResourceSoundBuffer(soundFile);
330    if (this->soundBuffers[action].loaded())
[4885]331    {
[7221]332      PRINTF(4)("Loaded sound %s to action %s.\n", soundFile.c_str(), actionToChar(action));
[4885]333    }
334    else
335    {
[7221]336      PRINTF(2)("Failed to load sound %s to %s.\n.", soundFile.c_str(), actionToChar(action));
[4885]337    }
338  }
339  else
[9869]340    this->soundBuffers[action] = OrxSound::SoundBuffer();
[4885]341}
342
[6728]343
[4893]344/**
[4895]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).
[4893]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 */
[4895]354Animation3D* Weapon::getAnimation(WeaponState state, PNode* node)
[4893]355{
[4895]356  if (state >= WS_STATE_COUNT) // if the state is not known
[4893]357    return NULL;
358
[4895]359  if (unlikely(this->animation[state] == NULL)) // if the animation does not exist yet create it.
[4893]360  {
[4895]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    }
[4893]368  }
[4895]369  else
370    return this->animation[state];
[4893]371}
372
[10152]373Animation3D* Weapon::getAnimation(int barrel, int seg, PNode* node)
[10136]374{
[10152]375  if (barrel >= this->getBarrels() || seg >= this->getSegs()) // if the state is not known
[10136]376    return NULL;
377
[10152]378  if (unlikely(this->shootAnim[barrel][seg] == NULL)) // if the animation does not exist yet create it.
[10136]379  {
380    if (likely(node != NULL))
[10152]381      return this->shootAnim[barrel][seg] = new Animation3D(node);
[10136]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
[10152]389    return this->shootAnim[barrel][seg];
[10136]390}
391
[7779]392OrxGui::GLGuiWidget* Weapon::getEnergyWidget()
[6438]393{
394  if (this->energyWidget == NULL)
395  {
[8977]396    this->energyWidget = new OrxGui::GLGuiEnergyWidget();
[9406]397    this->energyWidget->setDisplayedName(this->getClassCName());
[6438]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
[4892]414/////////////////
415//  EXECUTION  //
416// GAME ACTION //
417/////////////////
[4597]418/**
[4885]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{
[4906]427  if (likely(this->isActive()))
[4885]428  {
[10037]429    /** Disabled for releaseFire() from WM*/
[10121]430    if (this->requestedAction != WA_NONE)
431      return;
[5041]432    PRINTF(5)("next action will be %s in %f seconds\n", actionToChar(action), this->stateDuration);
[4885]433    this->requestedAction = action;
434  }
[4906]435  //else
436  else if (unlikely(action == WA_ACTIVATE))
437  {
438    this->currentState = WS_ACTIVATING;
[4926]439    this->requestedAction = WA_ACTIVATE;
[4906]440  }
[4885]441}
[3577]442
[6728]443
[4890]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;
[9966]456    this->updateWidgets();
[4890]457    return 0.0;
458  }
459  else
460  {
461    this->energy += maxAddEnergy;
[9966]462    this->updateWidgets();
[4890]463    return energyToAdd - maxAddEnergy;
464  }
[9966]465 
[4890]466}
467
[6728]468
[5498]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////////////////////////////////////////////////////////////
[4891]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 */
[4885]484bool Weapon::execute()
[3583]485{
[7729]486#if DEBUG_LEVEL > 4
[4885]487  PRINTF(4)("trying to execute action %s\n", actionToChar(this->requestedAction));
488  this->debug();
[4906]489#endif
[4885]490
[4926]491  WeaponAction action = this->requestedAction;
492  this->requestedAction = WA_NONE;
493
494  switch (action)
[4885]495  {
[7350]496    case WA_SHOOT:
[9869]497    return this->fireW();
498    break;
[7350]499    case WA_CHARGE:
[9869]500    return this->chargeW();
501    break;
[7350]502    case WA_RELOAD:
[9869]503    return this->reloadW();
504    break;
[7350]505    case WA_DEACTIVATE:
[9869]506    return this->deactivateW();
507    break;
[7350]508    case WA_ACTIVATE:
[9869]509    return this->activateW();
510    break;
[8316]511    default:
[10121]512    PRINTF(5)("Action %s Not Implemented yet \n", Weapon::actionToChar(action));
[9869]513    return false;
[4885]514  }
[3583]515}
[3577]516
[4597]517/**
[4894]518 * checks and activates the Weapon.
519 * @return true on success.
[4892]520 */
521bool Weapon::activateW()
[3583]522{
[6438]523  //  if (this->currentState == WS_INACTIVE)
[4892]524  {
[6433]525    // play Sound
[9869]526    if (likely(this->soundBuffers[WA_ACTIVATE].loaded()))
[4892]527      this->soundSource->play(this->soundBuffers[WA_ACTIVATE]);
[6444]528    this->updateWidgets();
[6438]529    // activate
[9406]530    PRINTF(4)("Activating the Weapon %s\n", this->getCName());
[4892]531    this->activate();
[4895]532    // setting up for next action
[4926]533    this->enterState(WS_ACTIVATING);
[4892]534  }
[8316]535  return true;
[3583]536}
[3577]537
[4597]538/**
[4894]539 * checks and deactivates the Weapon
540 * @return true on success.
[4892]541 */
542bool Weapon::deactivateW()
[3583]543{
[6438]544  //  if (this->currentState != WS_INACTIVE)
[4892]545  {
[9406]546    PRINTF(4)("Deactivating the Weapon %s\n", this->getCName());
[6438]547    // play Sound
[9869]548    if (this->soundBuffers[WA_DEACTIVATE].loaded())
[4892]549      this->soundSource->play(this->soundBuffers[WA_DEACTIVATE]);
[4926]550    // deactivate
[4892]551    this->deactivate();
[4926]552    this->enterState(WS_DEACTIVATING);
[4892]553  }
[8316]554
555  return true;
[3583]556}
[3577]557
[4892]558/**
[4894]559 * checks and charges the Weapon
560 * @return true on success.
[4892]561 */
562bool Weapon::chargeW()
[4885]563{
[6671]564  if ( this->currentState != WS_INACTIVE && this->energy >= this->minCharge)
[4892]565  {
[6438]566    // playing Sound
[9869]567    if (this->soundBuffers[WA_CHARGE].loaded())
[4892]568      this->soundSource->play(this->soundBuffers[WA_CHARGE]);
[4893]569
[6438]570    // charge
[4892]571    this->charge();
[6438]572    // setting up for the next state
[4926]573    this->enterState(WS_CHARGING);
[4892]574  }
575  else // deactivate the Weapon if we do not have enough energy
576  {
577    this->requestAction(WA_RELOAD);
578  }
[8316]579  return true;
[4885]580}
[3573]581
[4892]582/**
[4894]583 * checks and fires the Weapon
584 * @return true on success.
[4892]585 */
586bool Weapon::fireW()
[3575]587{
[6438]588  //if (likely(this->currentState != WS_INACTIVE))
[6671]589  if (this->minCharge <= this->energy)
[4892]590  {
[6438]591    // playing Sound
[9869]592    if (this->soundBuffers[WA_SHOOT].loaded())
[4892]593      this->soundSource->play(this->soundBuffers[WA_SHOOT]);
[6438]594    // fire
[6671]595    this->energy -= this->minCharge;
[4892]596    this->fire();
[6438]597    // setting up for the next state
[4926]598    this->enterState(WS_SHOOTING);
[10030]599    this->updateWidgets();
[4892]600  }
601  else  // reload if we still have the charge
602  {
603    this->requestAction(WA_RELOAD);
[4930]604    this->execute();
[4892]605  }
[8316]606  return true;
[4892]607}
608
609/**
[4894]610 * checks and Reloads the Weapon
611 * @return true on success.
[4892]612 */
613bool Weapon::reloadW()
614{
[9406]615  PRINTF(4)("Reloading Weapon %s\n", this->getCName());
[9869]616  if (!this->ammoContainer.isNull() &&
[7350]617      unlikely(this->energy + this->ammoContainer->getStoredEnergy() < this->minCharge))
[4885]618  {
[9998]619    //this->requestAction(WA_DEACTIVATE);
[4930]620    this->execute();
[4892]621    return false;
[4885]622  }
[3573]623
624
[9869]625  if (this->soundBuffers[WA_RELOAD].loaded())
[4892]626    this->soundSource->play(this->soundBuffers[WA_RELOAD]);
627
[9869]628  if (!this->ammoContainer.isNull())
[6671]629    this->ammoContainer->fillWeapon(this);
[4885]630  else
631  {
[6671]632    this->energy = this->energyMax;
[4885]633  }
[6444]634  this->updateWidgets();
[4892]635  this->reload();
[4926]636  this->enterState(WS_RELOADING);
[8316]637
638  return true;
[4926]639}
[3575]640
[4926]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{
[5041]647  PRINTF(4)("ENTERING STATE %s\n", stateToChar(state));
[4926]648  // playing animation if availiable
649  if (likely(this->animation[state] != NULL))
650    this->animation[state]->replay();
651
[6728]652  this->stateDuration += this->times[state];
[4926]653  this->currentState = state;
[3575]654}
655
[4927]656///////////////////
657//  WORLD-ENTITY //
658// FUNCTIONALITY //
659///////////////////
[3575]660/**
[4885]661 * tick signal for time dependent/driven stuff
[3575]662*/
[6736]663bool Weapon::tickW(float dt)
[4885]664{
[4934]665  //printf("%s ", stateToChar(this->currentState));
[4910]666
[4885]667  // setting up the timing properties
668  this->stateDuration -= dt;
[3575]669
[4949]670  if (this->stateDuration <= 0.0)
[4885]671  {
[4949]672    if (unlikely (this->currentState == WS_DEACTIVATING))
[4885]673    {
[4949]674      this->currentState = WS_INACTIVE;
[6736]675      return false;
[4949]676    }
677    else
678      this->currentState = WS_IDLE;
[4906]679
[4949]680    if (this->requestedAction != WA_NONE)
681    {
682      this->stateDuration = -dt;
683      this->execute();
[4885]684    }
685  }
[6736]686  return true;
[4885]687}
688
[3575]689
690
691
[4885]692//////////////////////
693// HELPER FUNCTIONS //
694//////////////////////
[3576]695/**
[4891]696 * checks wether all the Weapons functions are valid, and if it is possible to go to action with it.
[5498]697 * @todo IMPLEMENT the Weapons Check
[4891]698 */
699bool Weapon::check() const
700{
701  bool retVal = true;
702
[6438]703  //  if (this->projectile == NULL)
[4891]704  {
[5041]705    PRINTF(1)("There was no projectile assigned to the Weapon.\n");
[4891]706    retVal = false;
707  }
708
709
710
711
712  return retVal;
713}
714
715/**
[4885]716 * some nice debugging information about this Weapon
717 */
718void Weapon::debug() const
719{
[9406]720  PRINT(0)("Weapon-Debug %s, state: %s (duration: %fs), nextAction: %s\n", this->getCName(), Weapon::stateToChar(this->currentState), this->stateDuration, Weapon::actionToChar(requestedAction));
[6671]721  PRINT(0)("Energy: max: %f; current: %f; chargeMin: %f, chargeMax %f\n",
722           this->energyMax, this->energy, this->minCharge, this->maxCharge);
[4967]723
724
[4885]725}
[3575]726
[5498]727////////////////////////////////////////////////////////
728// static Definitions (transormators for readability) //
729////////////////////////////////////////////////////////
[4885]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 */
[7221]735WeaponAction Weapon::charToAction(const std::string& action)
[4885]736{
[7221]737  if (action == "none")
[4885]738    return WA_NONE;
[7221]739  else if (action == "shoot")
[4885]740    return WA_SHOOT;
[7221]741  else if (action == "charge")
[4885]742    return WA_CHARGE;
[7221]743  else if (action == "reload")
[4885]744    return WA_RELOAD;
[7221]745  else if (action == "acitvate")
[4885]746    return WA_ACTIVATE;
[7221]747  else if (action == "deactivate")
[4885]748    return WA_DEACTIVATE;
[7221]749  else if (action == "special1")
[4885]750    return WA_SPECIAL1;
751  else
[6438]752  {
[7221]753    PRINTF(2)("action %s could not be identified.\n", action.c_str());
[6438]754    return WA_NONE;
755  }
[4885]756}
[3575]757
758/**
[4885]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  {
[7350]767    case WA_SHOOT:
[9869]768    return "shoot";
769    break;
[7350]770    case WA_CHARGE:
[9869]771    return "charge";
772    break;
[7350]773    case WA_RELOAD:
[9869]774    return "reload";
775    break;
[7350]776    case WA_ACTIVATE:
[9869]777    return "activate";
778    break;
[7350]779    case WA_DEACTIVATE:
[9869]780    return "deactivate";
781    break;
[7350]782    case WA_SPECIAL1:
[9869]783    return "special1";
784    break;
[7350]785    default:
[9869]786    return "none";
787    break;
[4885]788  }
789}
[3577]790
791/**
[4885]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 */
[7221]796WeaponState Weapon::charToState(const std::string& state)
[4885]797{
[7221]798  if (state == "none")
[4885]799    return WS_NONE;
[7221]800  else if (state == "shooting")
[4885]801    return WS_SHOOTING;
[7221]802  else if (state == "charging")
[4885]803    return WS_CHARGING;
[7221]804  else if (state == "reloading")
[4885]805    return WS_RELOADING;
[7221]806  else if (state == "activating")
[4885]807    return WS_ACTIVATING;
[7221]808  else if (state == "deactivating")
[4885]809    return WS_DEACTIVATING;
[7221]810  else if (state == "inactive")
[4885]811    return WS_INACTIVE;
[7221]812  else if (state == "idle")
[4885]813    return WS_IDLE;
814  else
[6438]815  {
[7221]816    PRINTF(2)("state %s could not be identified.\n", state.c_str());
[6438]817    return WS_NONE;
818  }
[4885]819}
[3583]820
821/**
[4885]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  {
[7350]830    case WS_SHOOTING:
[9869]831    return "shooting";
832    break;
[7350]833    case WS_CHARGING:
[9869]834    return "charging";
835    break;
[7350]836    case WS_RELOADING:
[9869]837    return "reloading";
838    break;
[7350]839    case WS_ACTIVATING:
[9869]840    return "activating";
841    break;
[7350]842    case WS_DEACTIVATING:
[9869]843    return "deactivating";
844    break;
[7350]845    case WS_IDLE:
[9869]846    return "idle";
847    break;
[7350]848    case WS_INACTIVE:
[9869]849    return "inactive";
850    break;
[7350]851    default:
[9869]852    return "none";
853    break;
[4885]854  }
855}
Note: See TracBrowser for help on using the repository browser.