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
Line 
1
2/*
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
12### File Specific
13   main-programmer: Patrick Boenzli
14   co-programmer: Benjamin Grauer
15
16   2005-07-15: Benjamin Grauer: restructurating the entire Class
17*/
18
19#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
20
21#include "weapon.h"
22
23#include "projectile.h"
24
25#include "load_param.h"
26#include "vector.h"
27#include "list.h"
28#include "state.h"
29#include "animation3d.h"
30#include "sound_engine.h"
31
32/**
33 * standard constructor
34 *
35 * creates a new weapon
36*/
37Weapon::Weapon (PNode* parent, const Vector& coordinate, const Quaternion& direction)
38{
39  this->init();
40  parent->addChild(this, PNODE_ALL);
41  this->setRelCoor(coordinate);
42  this->setRelDir(direction);
43}
44
45/**
46 * standard deconstructor
47*/
48Weapon::~Weapon ()
49{
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])
55      ResourceManager::getInstance()->unload(this->soundBuffers[i]);
56}
57
58/**
59 * initializes the Weapon with ALL default values
60 */
61void Weapon::init()
62{
63  this->currentState     = WS_INACTIVE;
64  this->requestedAction  = WA_NONE;
65  this->stateDuration    = 0.0;
66  for (int i = 0; i < WS_STATE_COUNT; i++)
67    {
68      this->times[i] = 0.0;
69      this->animation[i] = NULL;
70    }
71  for (int i = 0; i < WA_ACTION_COUNT; i++)
72    this->soundBuffers[i] = NULL;
73
74  this->requestedAction = WA_NONE;
75  this->soundSource = new SoundSource(this);
76
77  this->active = true;
78  this->projectile = NULL;
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;
86}
87
88
89void Weapon::setActionSound(WeaponAction action, const char* soundFile)
90{
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  }
106}
107
108/**
109 * request an action that should be executed,
110 * @param action the next action to take
111 *
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 */
115void Weapon::requestAction(WeaponAction action)
116{
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  }
124}
125
126bool Weapon::execute()
127{
128  this->stateDuration = this->times[this->requestedAction] + this->stateDuration;
129
130  PRINTF(4)("trying to execute action %s\n", actionToChar(this->requestedAction));
131  this->debug();
132
133  switch (this->requestedAction)
134  {
135    case WA_SHOOT:
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      }
149      break;
150    case WA_CHARGE:
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      }
161      break;
162    case WA_RELOAD:
163      //if (this->currentState != WS_INACTIVE && this->energy + this->energyLoaded >= this->minCharge)
164      {
165        this->reload();
166        this->requestedAction = WA_NONE;
167      }
168      break;
169    case WA_DEACTIVATE:
170      if (this->currentState != WS_INACTIVE)
171      {
172        this->deactivate();
173        this->requestedAction = WA_NONE;
174      }
175      break;
176    case WA_ACTIVATE:
177      if (this->currentState == WS_INACTIVE)
178      {
179        this->activate();
180        this->requestedAction = WA_NONE;
181      }
182      break;
183  }
184}
185
186/**
187 * this activates the weapon
188*/
189void Weapon::activate()
190{
191  PRINTF(4)("Activating the Weapon %s\n", this->getName());
192
193  if (this->soundBuffers[WA_ACTIVATE] != NULL)
194    this->soundSource->play(this->soundBuffers[WA_ACTIVATE]);
195}
196
197
198/**
199 * this deactivates the weapon
200*/
201void Weapon::deactivate()
202{
203  PRINTF(4)("Deactivating the Weapon %s\n", this->getName());
204
205  if (this->soundBuffers[WA_DEACTIVATE] != NULL)
206    this->soundSource->play(this->soundBuffers[WA_DEACTIVATE]);
207}
208
209void Weapon::fire()
210{
211  this->energyLoaded -= this->minCharge;
212
213  if (this->soundBuffers[WA_SHOOT] != NULL)
214    this->soundSource->play(this->soundBuffers[WA_SHOOT]);
215}
216
217void Weapon::reload()
218{
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  }
225
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  }
240  if (this->soundBuffers[WA_RELOAD] != NULL)
241    this->soundSource->play(this->soundBuffers[WA_RELOAD]);
242
243}
244
245void Weapon::charge()
246{
247  if (this->soundBuffers[WA_CHARGE] != NULL)
248    this->soundSource->play(this->soundBuffers[WA_CHARGE]);
249
250}
251
252
253/**
254 *  is called, when the weapon is destroyed
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.
258*/
259void Weapon::destroy ()
260{}
261
262
263/**
264 * tick signal for time dependent/driven stuff
265*/
266void Weapon::tick(float dt)
267{
268  // setting up the timing properties
269  this->stateDuration -= dt;
270
271  if (this->isActive())
272  {
273    if (this->stateDuration <= 0.0 && this->requestedAction != WA_NONE)
274    {
275      this->stateDuration = -dt;
276      this->execute();
277    }
278  }
279  else
280    if (this->requestedAction == WA_ACTIVATE)
281      this->activate();
282
283}
284
285/**
286 *  this will draw the weapon
287*/
288void Weapon::draw ()
289{}
290
291
292
293
294
295//////////////////////
296// HELPER FUNCTIONS //
297//////////////////////
298// inclass
299/**
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
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}
325
326
327// static
328/**
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
350    {
351      PRINTF(2)("action %s could not be identified.\n", action);
352      return WA_NONE;
353    }
354}
355
356/**
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/**
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;
400  else if (!strcmp(state, "charging"))
401    return WS_CHARGING;
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
413    {
414      PRINTF(2)("state %s could not be identified.\n", state);
415      return WS_NONE;
416    }
417}
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.