Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/weaponSystem/src/world_entities/weapons/weapon.cc @ 4883

Last change on this file since 4883 was 4883, checked in by bensch, 19 years ago

orxonox/branches/weaponSystem: connecting sounds to the weapon works fine now

File size: 10.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
[4880]15
16   2005-07-15: Benjamin Grauer: restructurating the entire Class
[3573]17*/
18
[4881]19#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
20
[4828]21#include "weapon.h"
22
[4834]23#include "projectile.h"
24
25#include "load_param.h"
[3573]26#include "vector.h"
[3620]27#include "list.h"
[4828]28#include "state.h"
[4880]29#include "animation3d.h"
30#include "sound_engine.h"
[3573]31
[3870]32/**
[4878]33 * standard constructor
34 *
35 * creates a new weapon
[3575]36*/
[4597]37Weapon::Weapon (PNode* parent, const Vector& coordinate, const Quaternion& direction)
[3620]38{
[4878]39  this->init();
[3752]40  parent->addChild(this, PNODE_ALL);
[3881]41  this->setRelCoor(coordinate);
42  this->setRelDir(direction);
[3620]43}
[3573]44
[3575]45/**
[4878]46 * standard deconstructor
[3575]47*/
[4597]48Weapon::~Weapon ()
[3573]49{
[4880]50  for (int i = 0; i < WS_STATE_COUNT; i++)
51    if (this->animation[i])
52      delete this->animation[i];
53  for (int i = 0; i < WA_ACTION_COUNT; i++)
54    if (this->soundBuffers[i])
[4883]55      ResourceManager::getInstance()->unload(this->soundBuffers[i]);
[3573]56}
57
[4880]58/**
59 * initializes the Weapon with ALL default values
60 */
[4878]61void Weapon::init()
[3583]62{
[4878]63  this->currentState     = WS_INACTIVE;
[4882]64  this->requestedAction  = WA_NONE;
[4880]65  this->stateDuration    = 0.0;
[4878]66  for (int i = 0; i < WS_STATE_COUNT; i++)
[4880]67    {
68      this->times[i] = 0.0;
69      this->animation[i] = NULL;
70    }
[4878]71  for (int i = 0; i < WA_ACTION_COUNT; i++)
72    this->soundBuffers[i] = NULL;
[3577]73
[4880]74  this->requestedAction = WA_NONE;
[4883]75  this->soundSource = new SoundSource(this);
[3577]76
[4881]77  this->active = true;
[4878]78  this->projectile = NULL;
[4882]79
80  this->minCharge = 1.0;
81  this->maxCharge = 1.0;
82  this->energyLoaded = .0;
83  this->energyLoadedMax = 10.0;
84  this->energy = .0;
85  this->energyMax = 100.0;
[3583]86}
[3577]87
[4883]88
89void Weapon::setActionSound(WeaponAction action, const char* soundFile)
[3575]90{
[4883]91  if (action >= WA_ACTION_COUNT)
92    return;
93  else
94  {
95    this->soundBuffers[action] = (SoundBuffer*)ResourceManager::getInstance()->load(soundFile, WAV);
96    if (this->soundBuffers[action] != NULL)
97    {
98      PRINTF(4)("Loaded sound %s to action %s\n", soundFile, actionToChar(action));
99    }
100    else
101    {
102      PRINTF(4)("failed to load sound %s to %s\n", soundFile, actionToChar(action));
103    }
104
105  }
[3575]106}
[3573]107
[3575]108/**
[4883]109 * request an action that should be executed,
110 * @param action the next action to take
[4878]111 *
[4883]112 * This function must be called instead of the actions (like fire/reload...)
113 * to make all the checks needed to have a usefull WeaponSystem.
114 */
[4880]115void Weapon::requestAction(WeaponAction action)
116{
[4882]117  if (this->requestedAction != WA_NONE)
118    return;
119  else
120  {
121    printf("next action will be %s in %f seconds\n", actionToChar(action), this->stateDuration);
122    this->requestedAction = action;
123  }
[4880]124}
125
[4881]126bool Weapon::execute()
[4880]127{
[4881]128  this->stateDuration = this->times[this->requestedAction] + this->stateDuration;
[4880]129
[4882]130  PRINTF(4)("trying to execute action %s\n", actionToChar(this->requestedAction));
131  this->debug();
[4881]132
133  switch (this->requestedAction)
[4880]134  {
135    case WA_SHOOT:
[4882]136      //if (likely(this->currentState != WS_INACTIVE))
137      {
138        if (this->minCharge < this->energyLoaded)
139        {
140          this->fire();
141          this->requestedAction = WA_NONE;
142        }
143        else  // reload if we still have the charge
144        {
145          this->requestedAction = WA_NONE;
146          this->requestAction(WA_RELOAD);
147        }
148      }
[4880]149      break;
150    case WA_CHARGE:
[4882]151      if ( this->currentState != WS_INACTIVE && this->energyLoaded >= this->minCharge)
152      {
153        this->charge();
154        this->requestedAction = WA_NONE;
155      }
156      else // deactivate the Weapon if we do not have enough energy
157      {
158        this->requestedAction = WA_NONE;
159        this->requestAction(WA_RELOAD);
160      }
[4880]161      break;
162    case WA_RELOAD:
[4882]163      //if (this->currentState != WS_INACTIVE && this->energy + this->energyLoaded >= this->minCharge)
164      {
165        this->reload();
166        this->requestedAction = WA_NONE;
167      }
[4880]168      break;
169    case WA_DEACTIVATE:
[4882]170      if (this->currentState != WS_INACTIVE)
171      {
172        this->deactivate();
173        this->requestedAction = WA_NONE;
174      }
[4880]175      break;
176    case WA_ACTIVATE:
[4882]177      if (this->currentState == WS_INACTIVE)
178      {
179        this->activate();
180        this->requestedAction = WA_NONE;
181      }
[4880]182      break;
183  }
184}
185
[3575]186/**
[4878]187 * this activates the weapon
[3575]188*/
189void Weapon::activate()
[4882]190{
191  PRINTF(4)("Activating the Weapon %s\n", this->getName());
[4883]192
193  if (this->soundBuffers[WA_ACTIVATE] != NULL)
194    this->soundSource->play(this->soundBuffers[WA_ACTIVATE]);
[4882]195}
[3575]196
197
198/**
[4878]199 * this deactivates the weapon
[3575]200*/
201void Weapon::deactivate()
[4882]202{
203  PRINTF(4)("Deactivating the Weapon %s\n", this->getName());
[4883]204
205  if (this->soundBuffers[WA_DEACTIVATE] != NULL)
206    this->soundSource->play(this->soundBuffers[WA_DEACTIVATE]);
[4882]207}
[3575]208
[4880]209void Weapon::fire()
210{
[4882]211  this->energyLoaded -= this->minCharge;
[4883]212
213  if (this->soundBuffers[WA_SHOOT] != NULL)
214    this->soundSource->play(this->soundBuffers[WA_SHOOT]);
[4880]215}
[3577]216
[4880]217void Weapon::reload()
218{
[4882]219  PRINTF(4)("Reloading Weapon %s\n", this->getName());
220  if (this->energy + this->energyLoaded < this->minCharge)
221  {
222    this->requestAction(WA_DEACTIVATE);
223    return;
224  }
[4880]225
[4882]226  float chargeSize = this->energyLoadedMax - this->energyLoaded;       //!< The energy to be charged
227
228  if (chargeSize > this->energy)
229  {
230    this->energyLoaded += this->energy;
231    this->energy = 0.0;
232    PRINT(3)("Energy empty");
233  }
234  else
235  {
236    PRINTF(3)("Loaded %f energy into the Guns Buffer\n", chargeSize);
237    this->energyLoaded += chargeSize;
238    this->energy -= chargeSize;
239  }
[4883]240  if (this->soundBuffers[WA_RELOAD] != NULL)
241    this->soundSource->play(this->soundBuffers[WA_RELOAD]);
242
[4880]243}
244
245void Weapon::charge()
246{
[4883]247  if (this->soundBuffers[WA_CHARGE] != NULL)
248    this->soundSource->play(this->soundBuffers[WA_CHARGE]);
249
[4880]250}
251
252
[3575]253/**
[4836]254 *  is called, when the weapon is destroyed
[4878]255 *
256 * this is in conjunction with the hit function, so when a weapon is able to get
257 * hit, it can also be destoryed.
[3575]258*/
[4597]259void Weapon::destroy ()
[3575]260{}
261
262
263/**
[4880]264 * tick signal for time dependent/driven stuff
[3577]265*/
[4880]266void Weapon::tick(float dt)
267{
[4881]268  // setting up the timing properties
269  this->stateDuration -= dt;
270
[4880]271  if (this->isActive())
272  {
[4881]273    if (this->stateDuration <= 0.0 && this->requestedAction != WA_NONE)
[4882]274    {
275      this->stateDuration = -dt;
[4881]276      this->execute();
[4882]277    }
[4880]278  }
279  else
280    if (this->requestedAction == WA_ACTIVATE)
281      this->activate();
282
283}
284
[3577]285/**
[4879]286 *  this will draw the weapon
[3583]287*/
[4879]288void Weapon::draw ()
[3583]289{}
290
291
[4879]292
293
294
[4880]295//////////////////////
296// HELPER FUNCTIONS //
297//////////////////////
298// inclass
[3583]299/**
[4880]300 * checks if the next Action given is valid
301 * @returns if the Action that comes next is valid
302 * @todo more checks
303 */
304bool Weapon::nextActionValid() const
305{
306  if (this->currentState == WS_INACTIVE)
307  {
308    return (this->requestedAction == WA_ACTIVATE || this->requestedAction == WA_NONE);
309  }
310  else
311    return true;
312
313}
314
315
[4882]316/**
317 * some nice debugging information about this Weapon
318 */
319void Weapon::debug() const
320{
321  PRINT(3)("Weapon-Debug %s, state: %s, nexAction: %s\n", this->getName(), Weapon::stateToChar(this->currentState), Weapon::actionToChar(requestedAction));
322  PRINT(3)("Energy: max: %f; current: %f;  loadedMax: %f; loadedCurrent: %f; chargeMin: %f, chargeMax %f\n",
323            this->energyMax, this->energy, this->energyLoadedMax, this->energyLoaded, this->minCharge, this->maxCharge);
324}
[4880]325
[4882]326
[4880]327// static
328/**
[4879]329 * Converts a String into an Action.
330 * @param action the String input holding the Action.
331 * @return The Action if known, WA_NONE otherwise.
332 */
333WeaponAction Weapon::charToAction(const char* action)
334{
335  if (!strcmp(action, "none"))
336    return WA_NONE;
337  else if (!strcmp(action, "shoot"))
338    return WA_SHOOT;
339  else if (!strcmp(action, "charge"))
340    return WA_CHARGE;
341  else if (!strcmp(action, "reload"))
342    return WA_RELOAD;
343  else if (!strcmp(action, "acitvate"))
344    return WA_ACTIVATE;
345  else if (!strcmp(action, "deactivate"))
346    return WA_DEACTIVATE;
347  else if (!strcmp(action, "special1"))
348    return WA_SPECIAL1;
349  else
[4880]350    {
351      PRINTF(2)("action %s could not be identified.\n", action);
352      return WA_NONE;
353    }
[4879]354}
[3575]355
[4879]356/**
[4882]357 * converts an action into a String
358 * @param action the action to convert
359 * @return a String matching the name of the action
360 */
361const char* Weapon::actionToChar(WeaponAction action)
362{
363  switch (action)
364  {
365    case WA_SHOOT:
366      return "shoot";
367      break;
368    case WA_CHARGE:
369      return "charge";
370      break;
371    case WA_RELOAD:
372      return "reload";
373      break;
374    case WA_ACTIVATE:
375      return "activate";
376      break;
377    case WA_DEACTIVATE:
378      return "deactivate";
379      break;
380    case WA_SPECIAL1:
381      return "special1";
382      break;
383    default:
384      return "none";
385      break;
386  }
387}
388
389/**
[4879]390 * Converts a String into a State.
391 * @param state the String input holding the State.
392 * @return The State if known, WS_NONE otherwise.
393 */
394WeaponState Weapon::charToState(const char* state)
395{
396  if (!strcmp(state, "none"))
397    return WS_NONE;
398  else if (!strcmp(state, "shooting"))
399    return WS_SHOOTING;
[4880]400  else if (!strcmp(state, "charging"))
401    return WS_CHARGING;
[4879]402  else if (!strcmp(state, "reloading"))
403    return WS_RELOADING;
404  else if (!strcmp(state, "activating"))
405    return WS_ACTIVATING;
406  else if (!strcmp(state, "deactivating"))
407    return WS_DEACTIVATING;
408  else if (!strcmp(state, "inactive"))
409    return WS_INACTIVE;
410  else if (!strcmp(state, "idle"))
411    return WS_IDLE;
412  else
[4880]413    {
414      PRINTF(2)("state %s could not be identified.\n", state);
415      return WS_NONE;
416    }
[4879]417}
[4882]418
419/**
420 * converts a State into a String
421 * @param state the state to convert
422 * @return a String matching the name of the state
423 */
424const char* Weapon::stateToChar(WeaponState state)
425{
426  switch (state)
427  {
428    case WS_SHOOTING:
429      return "shooting";
430      break;
431    case WS_CHARGING:
432      return "charging";
433      break;
434    case WS_RELOADING:
435      return "reloading";
436      break;
437    case WS_ACTIVATING:
438      return "activating";
439      break;
440    case WS_DEACTIVATING:
441      return "deactivating";
442      break;
443    case WS_IDLE:
444      return "idle";
445      break;
446    default:
447      return "none";
448      break;
449  }
450}
Note: See TracBrowser for help on using the repository browser.