Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

rotatoin for particle systems

File size: 22.8 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
[10368]35#include "elements/glgui_energywidgetvertical.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
[10368]121  this->soundSource = new OrxSound::SoundSource(this);       //< Every Weapon has exacty one SoundSource
[4885]122
[10368]123  this->barrels = 1;
124  this->segs = 1;
125
[10443]126  this->preferedSide = -1;
127  this->preferedSlot = -1;
128
[10368]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
[6920]141  this->defaultTarget = NULL;                      //< Nothing is Targeted by default.
[6756]142
[9869]143  this->projectile = NullClass::staticClassID();         //< No Projectile Class is Connected to this weapon
[5498]144  this->projectileFactory = NULL;                  //< No Factory generating Projectiles is selected.
[4885]145
[5498]146  this->hideInactive = true;                       //< The Weapon will be hidden if it is inactive (by default)
[4906]147
[5498]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.
[4927]150
[6671]151  this->energy = 10;                               //< The secondary Buffer (before we have to reload)
[5498]152  this->energyMax = 10.0;                          //< How much energy can be carried
153  this->capability = WTYPE_ALL;                    //< The Weapon has all capabilities @see W_Capability.
[6438]154
155  this->energyWidget = NULL;
[10516]156  isEnergyWidgetInitialized = false;
[6695]157
158  // set this object to be synchronized over network
159  //this->setSynchronized(true);
[3573]160}
161
[5498]162/**
[10368]163 * needed, if there are more than one barrel or segments
164 */
[10443]165void Weapon::init2()
[10368]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/**
[5498]203 * loads the Parameters of a Weapon
204 * @param root the XML-Element to load the Weapons settings from
205 */
[4972]206void Weapon::loadParams(const TiXmlElement* root)
207{
[6512]208  WorldEntity::loadParams(root);
[4972]209
[7102]210  LoadParam(root, "projectile", this, Weapon, setProjectileTypeC)
[6438]211  .describe("Sets the name of the Projectile to load onto the Entity");
[10443]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");
[10368]218/*
[5671]219  LoadParam(root, "emission-point", this, Weapon, setEmissionPoint)
[10368]220  .describe("Sets the Point of emission of this weapon (1: EmmsionVector; 2: EmissionPoint)");*/
[4972]221
[5671]222  LoadParam(root, "state-duration", this, Weapon, setStateDuration)
[6438]223  .describe("Sets the duration of a given state (1: state-Name; 2: duration in seconds)");
[4972]224
[5671]225  LoadParam(root, "action-sound", this, Weapon, setActionSound)
[6438]226  .describe("Sets a given sound to an action (1: action-Name; 2: name of the sound (relative to the Data-Path))");
[4972]227}
228
[6728]229
[4947]230/**
231 * sets the Projectile to use for this weapon.
232 * @param projectile The ID of the Projectile to use
[4950]233 * @returns true, if it was sucessfull, false on error
[4947]234 *
[5498]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.
[4947]237 */
[9869]238void Weapon::setProjectileType(const ClassID& projectile)
[4947]239{
240  this->projectile = projectile;
241  this->projectileFactory = FastFactory::searchFastFactory(projectile);
242  if (this->projectileFactory == NULL)
[4979]243  {
244    PRINTF(1)("unable to find FastFactory for the Projectile.\n");
[4972]245    return;
[4979]246  }
[4948]247  else
248  {
249    // grabbing Parameters from the Projectile to have them at hand here.
250    Projectile* pj = dynamic_cast<Projectile*>(this->projectileFactory->resurrect());
[6431]251    this->minCharge = pj->getMinEnergy();
[6700]252    this->maxCharge = pj->getHealthMax();
[4948]253    this->chargeable = pj->isChageable();
[4979]254    this->projectileFactory->kill(pj);
[4948]255  }
[4979]256}
[3573]257
[6728]258
[4891]259/**
[4950]260 * @see bool Weapon::setProjectile(ClassID projectile)
261 * @param projectile the Name of the Projectile.
262 */
[7221]263void Weapon::setProjectileTypeC(const std::string& projectile)
[4950]264{
265  FastFactory* tmpFac = FastFactory::searchFastFactory(projectile);
266  if (tmpFac != NULL)
267  {
[5356]268    this->setProjectileType(tmpFac->getStoredID());
[4950]269  }
[4972]270  else
271  {
[9406]272    PRINTF(1)("Projectile %s does not exist for weapon %s\n", projectile.c_str(), this->getCName());
[4972]273  }
[4950]274}
275
[6728]276
[4950]277/**
[5356]278 * prepares Projectiles of the Weapon
[5498]279 * @param count how many Projectiles to create (they will be stored in the ProjectileFactory)
[5356]280 */
281void Weapon::prepareProjectiles(unsigned int count)
282{
[5357]283  if (likely(this->projectileFactory != NULL))
[5356]284    projectileFactory->prepare(count);
285  else
[9406]286    PRINTF(2)("unable to create %d projectile for Weapon %s::%s\n", count, this->getClassCName(), this->getCName());
[5356]287}
288
[6728]289
[5356]290/**
291 * resurects and returns a Projectile
[5498]292 * @returns a Projectile on success, NULL on error
293 *
294 * errors: 1. (ProjectileFastFactory not Found)
295 *         2. No more Projectiles availiable.
[5356]296 */
297Projectile* Weapon::getProjectile()
298{
[5357]299  if (likely (this->projectileFactory != NULL))
[6142]300  {
301    Projectile* pj = dynamic_cast<Projectile*>(this->projectileFactory->resurrect());
302    pj->toList((OM_LIST)(this->getOMListNumber()+1));
303    return pj;
304  }
[5356]305  else
306  {
[9406]307    PRINTF(2)("No projectile defined for Weapon %s(%s) can't return any\n", this->getCName(), this->getClassCName());
[5356]308    return NULL;
309  }
310}
311
312
313/**
[4892]314 * sets the emissionPoint's relative position from the Weapon
315 * @param point the Point relative to the mass-point of the Weapon
316 */
[10368]317void Weapon::setEmissionPoint(const Vector& point, int barrel)
318{
319  this->emissionPoint[barrel]->setRelCoor(point);
320}
321
[4892]322void Weapon::setEmissionPoint(const Vector& point)
323{
[10368]324  this->emissionPoint[0]->setRelCoor(point);
[4892]325}
326
327/**
[4891]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 */
[7221]332void Weapon::setActionSound(WeaponAction action, const std::string& soundFile)
[4885]333{
334  if (action >= WA_ACTION_COUNT)
335    return;
[4930]336
[7221]337  else if (!soundFile.empty())
[4885]338  {
[9869]339    this->soundBuffers[action] = OrxSound::ResourceSoundBuffer(soundFile);
340    if (this->soundBuffers[action].loaded())
[4885]341    {
[7221]342      PRINTF(4)("Loaded sound %s to action %s.\n", soundFile.c_str(), actionToChar(action));
[4885]343    }
344    else
345    {
[7221]346      PRINTF(2)("Failed to load sound %s to %s.\n.", soundFile.c_str(), actionToChar(action));
[4885]347    }
348  }
349  else
[9869]350    this->soundBuffers[action] = OrxSound::SoundBuffer();
[4885]351}
352
[6728]353
[4893]354/**
[4895]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).
[4893]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 */
[4895]364Animation3D* Weapon::getAnimation(WeaponState state, PNode* node)
[4893]365{
[4895]366  if (state >= WS_STATE_COUNT) // if the state is not known
[4893]367    return NULL;
368
[4895]369  if (unlikely(this->animation[state] == NULL)) // if the animation does not exist yet create it.
[4893]370  {
[4895]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    }
[4893]378  }
[4895]379  else
380    return this->animation[state];
[4893]381}
382
[10368]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
[7779]402OrxGui::GLGuiWidget* Weapon::getEnergyWidget()
[6438]403{
[10368]404  if ( this->energyWidget == NULL)
[6438]405  {
[10368]406    this->energyWidget = new OrxGui::GLGuiEnergyWidgetVertical();
407    //this->energyWidget->setDisplayedName(this->getClassCName());
[6438]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
[4892]424/////////////////
425//  EXECUTION  //
426// GAME ACTION //
427/////////////////
[4597]428/**
[4885]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{
[4906]437  if (likely(this->isActive()))
[4885]438  {
[10368]439    /** Disabled for releaseFire() from WM*/
[4906]440    if (this->requestedAction != WA_NONE)
441      return;
[10529]442    PRINTF(5)("%s: next action will be %s in %f seconds\n", this->getCName(), actionToChar(action), this->stateDuration);
[4885]443    this->requestedAction = action;
444  }
[4906]445  //else
446  else if (unlikely(action == WA_ACTIVATE))
447  {
448    this->currentState = WS_ACTIVATING;
[4926]449    this->requestedAction = WA_ACTIVATE;
[4906]450  }
[4885]451}
[3577]452
[6728]453
[4890]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;
[10368]466    this->updateWidgets();
[4890]467    return 0.0;
468  }
469  else
470  {
471    this->energy += maxAddEnergy;
[10368]472    this->updateWidgets();
[4890]473    return energyToAdd - maxAddEnergy;
474  }
[10443]475
[4890]476}
477
[6728]478
[5498]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////////////////////////////////////////////////////////////
[4891]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 */
[4885]494bool Weapon::execute()
[3583]495{
[7729]496#if DEBUG_LEVEL > 4
[4885]497  PRINTF(4)("trying to execute action %s\n", actionToChar(this->requestedAction));
498  this->debug();
[4906]499#endif
[4885]500
[4926]501  WeaponAction action = this->requestedAction;
502  this->requestedAction = WA_NONE;
503
504  switch (action)
[4885]505  {
[7350]506    case WA_SHOOT:
[9869]507    return this->fireW();
508    break;
[7350]509    case WA_CHARGE:
[9869]510    return this->chargeW();
511    break;
[7350]512    case WA_RELOAD:
[9869]513    return this->reloadW();
514    break;
[7350]515    case WA_DEACTIVATE:
[9869]516    return this->deactivateW();
517    break;
[7350]518    case WA_ACTIVATE:
[9869]519    return this->activateW();
520    break;
[8316]521    default:
[10368]522    PRINTF(5)("Action %s Not Implemented yet \n", Weapon::actionToChar(action));
[9869]523    return false;
[4885]524  }
[3583]525}
[3577]526
[4597]527/**
[4894]528 * checks and activates the Weapon.
529 * @return true on success.
[4892]530 */
531bool Weapon::activateW()
[3583]532{
[6438]533  //  if (this->currentState == WS_INACTIVE)
[4892]534  {
[6433]535    // play Sound
[9869]536    if (likely(this->soundBuffers[WA_ACTIVATE].loaded()))
[4892]537      this->soundSource->play(this->soundBuffers[WA_ACTIVATE]);
[6444]538    this->updateWidgets();
[6438]539    // activate
[9406]540    PRINTF(4)("Activating the Weapon %s\n", this->getCName());
[4892]541    this->activate();
[4895]542    // setting up for next action
[4926]543    this->enterState(WS_ACTIVATING);
[4892]544  }
[8316]545  return true;
[3583]546}
[3577]547
[4597]548/**
[4894]549 * checks and deactivates the Weapon
550 * @return true on success.
[4892]551 */
552bool Weapon::deactivateW()
[3583]553{
[6438]554  //  if (this->currentState != WS_INACTIVE)
[4892]555  {
[9406]556    PRINTF(4)("Deactivating the Weapon %s\n", this->getCName());
[6438]557    // play Sound
[9869]558    if (this->soundBuffers[WA_DEACTIVATE].loaded())
[4892]559      this->soundSource->play(this->soundBuffers[WA_DEACTIVATE]);
[4926]560    // deactivate
[4892]561    this->deactivate();
[4926]562    this->enterState(WS_DEACTIVATING);
[4892]563  }
[8316]564
565  return true;
[3583]566}
[3577]567
[4892]568/**
[4894]569 * checks and charges the Weapon
570 * @return true on success.
[4892]571 */
572bool Weapon::chargeW()
[4885]573{
[6671]574  if ( this->currentState != WS_INACTIVE && this->energy >= this->minCharge)
[4892]575  {
[6438]576    // playing Sound
[9869]577    if (this->soundBuffers[WA_CHARGE].loaded())
[4892]578      this->soundSource->play(this->soundBuffers[WA_CHARGE]);
[4893]579
[6438]580    // charge
[4892]581    this->charge();
[6438]582    // setting up for the next state
[4926]583    this->enterState(WS_CHARGING);
[4892]584  }
585  else // deactivate the Weapon if we do not have enough energy
586  {
587    this->requestAction(WA_RELOAD);
588  }
[8316]589  return true;
[4885]590}
[3573]591
[4892]592/**
[4894]593 * checks and fires the Weapon
594 * @return true on success.
[4892]595 */
596bool Weapon::fireW()
[3575]597{
[10368]598//   printf("fireW Weapon\n");
[6438]599  //if (likely(this->currentState != WS_INACTIVE))
[6671]600  if (this->minCharge <= this->energy)
[4892]601  {
[6438]602    // playing Sound
[9869]603    if (this->soundBuffers[WA_SHOOT].loaded())
[4892]604      this->soundSource->play(this->soundBuffers[WA_SHOOT]);
[6438]605    // fire
[6671]606    this->energy -= this->minCharge;
[4892]607    this->fire();
[6438]608    // setting up for the next state
[4926]609    this->enterState(WS_SHOOTING);
[10368]610    this->updateWidgets();
[4892]611  }
612  else  // reload if we still have the charge
613  {
614    this->requestAction(WA_RELOAD);
[4930]615    this->execute();
[4892]616  }
[8316]617  return true;
[4892]618}
619
620/**
[4894]621 * checks and Reloads the Weapon
622 * @return true on success.
[4892]623 */
624bool Weapon::reloadW()
625{
[9406]626  PRINTF(4)("Reloading Weapon %s\n", this->getCName());
[9869]627  if (!this->ammoContainer.isNull() &&
[7350]628      unlikely(this->energy + this->ammoContainer->getStoredEnergy() < this->minCharge))
[4885]629  {
[10368]630    //this->requestAction(WA_DEACTIVATE);
[4930]631    this->execute();
[4892]632    return false;
[4885]633  }
[3573]634
635
[9869]636  if (this->soundBuffers[WA_RELOAD].loaded())
[4892]637    this->soundSource->play(this->soundBuffers[WA_RELOAD]);
638
[9869]639  if (!this->ammoContainer.isNull())
[6671]640    this->ammoContainer->fillWeapon(this);
[4885]641  else
642  {
[6671]643    this->energy = this->energyMax;
[4885]644  }
[6444]645  this->updateWidgets();
[4892]646  this->reload();
[4926]647  this->enterState(WS_RELOADING);
[8316]648
649  return true;
[4926]650}
[3575]651
[4926]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{
[5041]658  PRINTF(4)("ENTERING STATE %s\n", stateToChar(state));
[4926]659  // playing animation if availiable
660  if (likely(this->animation[state] != NULL))
661    this->animation[state]->replay();
662
[6728]663  this->stateDuration += this->times[state];
[4926]664  this->currentState = state;
[3575]665}
666
[4927]667///////////////////
668//  WORLD-ENTITY //
669// FUNCTIONALITY //
670///////////////////
[3575]671/**
[4885]672 * tick signal for time dependent/driven stuff
[3575]673*/
[6736]674bool Weapon::tickW(float dt)
[4885]675{
[4934]676  //printf("%s ", stateToChar(this->currentState));
[4910]677
[4885]678  // setting up the timing properties
679  this->stateDuration -= dt;
[3575]680
[4949]681  if (this->stateDuration <= 0.0)
[4885]682  {
[4949]683    if (unlikely (this->currentState == WS_DEACTIVATING))
[4885]684    {
[4949]685      this->currentState = WS_INACTIVE;
[6736]686      return false;
[4949]687    }
688    else
689      this->currentState = WS_IDLE;
[4906]690
[4949]691    if (this->requestedAction != WA_NONE)
692    {
693      this->stateDuration = -dt;
694      this->execute();
[4885]695    }
696  }
[6736]697  return true;
[4885]698}
699
[3575]700
701
702
[4885]703//////////////////////
704// HELPER FUNCTIONS //
705//////////////////////
[3576]706/**
[4891]707 * checks wether all the Weapons functions are valid, and if it is possible to go to action with it.
[5498]708 * @todo IMPLEMENT the Weapons Check
[4891]709 */
710bool Weapon::check() const
711{
712  bool retVal = true;
713
[6438]714  //  if (this->projectile == NULL)
[4891]715  {
[5041]716    PRINTF(1)("There was no projectile assigned to the Weapon.\n");
[4891]717    retVal = false;
718  }
719
720
721
722
723  return retVal;
724}
725
726/**
[4885]727 * some nice debugging information about this Weapon
728 */
729void Weapon::debug() const
730{
[9406]731  PRINT(0)("Weapon-Debug %s, state: %s (duration: %fs), nextAction: %s\n", this->getCName(), Weapon::stateToChar(this->currentState), this->stateDuration, Weapon::actionToChar(requestedAction));
[6671]732  PRINT(0)("Energy: max: %f; current: %f; chargeMin: %f, chargeMax %f\n",
733           this->energyMax, this->energy, this->minCharge, this->maxCharge);
[4967]734
735
[4885]736}
[3575]737
[5498]738////////////////////////////////////////////////////////
739// static Definitions (transormators for readability) //
740////////////////////////////////////////////////////////
[4885]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 */
[7221]746WeaponAction Weapon::charToAction(const std::string& action)
[4885]747{
[7221]748  if (action == "none")
[4885]749    return WA_NONE;
[7221]750  else if (action == "shoot")
[4885]751    return WA_SHOOT;
[7221]752  else if (action == "charge")
[4885]753    return WA_CHARGE;
[7221]754  else if (action == "reload")
[4885]755    return WA_RELOAD;
[7221]756  else if (action == "acitvate")
[4885]757    return WA_ACTIVATE;
[7221]758  else if (action == "deactivate")
[4885]759    return WA_DEACTIVATE;
[7221]760  else if (action == "special1")
[4885]761    return WA_SPECIAL1;
762  else
[6438]763  {
[7221]764    PRINTF(2)("action %s could not be identified.\n", action.c_str());
[6438]765    return WA_NONE;
766  }
[4885]767}
[3575]768
769/**
[4885]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  {
[7350]778    case WA_SHOOT:
[9869]779    return "shoot";
780    break;
[7350]781    case WA_CHARGE:
[9869]782    return "charge";
783    break;
[7350]784    case WA_RELOAD:
[9869]785    return "reload";
786    break;
[7350]787    case WA_ACTIVATE:
[9869]788    return "activate";
789    break;
[7350]790    case WA_DEACTIVATE:
[9869]791    return "deactivate";
792    break;
[7350]793    case WA_SPECIAL1:
[9869]794    return "special1";
795    break;
[7350]796    default:
[9869]797    return "none";
798    break;
[4885]799  }
800}
[3577]801
802/**
[4885]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 */
[7221]807WeaponState Weapon::charToState(const std::string& state)
[4885]808{
[7221]809  if (state == "none")
[4885]810    return WS_NONE;
[7221]811  else if (state == "shooting")
[4885]812    return WS_SHOOTING;
[7221]813  else if (state == "charging")
[4885]814    return WS_CHARGING;
[7221]815  else if (state == "reloading")
[4885]816    return WS_RELOADING;
[7221]817  else if (state == "activating")
[4885]818    return WS_ACTIVATING;
[7221]819  else if (state == "deactivating")
[4885]820    return WS_DEACTIVATING;
[7221]821  else if (state == "inactive")
[4885]822    return WS_INACTIVE;
[7221]823  else if (state == "idle")
[4885]824    return WS_IDLE;
825  else
[6438]826  {
[7221]827    PRINTF(2)("state %s could not be identified.\n", state.c_str());
[6438]828    return WS_NONE;
829  }
[4885]830}
[3583]831
832/**
[4885]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  {
[7350]841    case WS_SHOOTING:
[9869]842    return "shooting";
843    break;
[7350]844    case WS_CHARGING:
[9869]845    return "charging";
846    break;
[7350]847    case WS_RELOADING:
[9869]848    return "reloading";
849    break;
[7350]850    case WS_ACTIVATING:
[9869]851    return "activating";
852    break;
[7350]853    case WS_DEACTIVATING:
[9869]854    return "deactivating";
855    break;
[7350]856    case WS_IDLE:
[9869]857    return "idle";
858    break;
[7350]859    case WS_INACTIVE:
[9869]860    return "inactive";
861    break;
[7350]862    default:
[9869]863    return "none";
864    break;
[4885]865  }
866}
Note: See TracBrowser for help on using the repository browser.