Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: remake of the Projectile and TestBullet

File size: 11.2 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 if (soundFile != NULL)
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  else
106    this->soundBuffers[action] = NULL;
107}
108
109/**
110 * request an action that should be executed,
111 * @param action the next action to take
112 *
113 * This function must be called instead of the actions (like fire/reload...)
114 * to make all the checks needed to have a usefull WeaponSystem.
115 */
116void Weapon::requestAction(WeaponAction action)
117{
118  if (this->requestedAction != WA_NONE)
119    return;
120  else
121  {
122    printf("next action will be %s in %f seconds\n", actionToChar(action), this->stateDuration);
123    this->requestedAction = action;
124  }
125}
126
127
128/**
129 * adds energy to the Weapon
130 * @param energyToAdd The amount of energy
131 * @returns the amount of energy we did not pick up, because the weapon is already full
132 */
133float Weapon::increaseEnergy(float energyToAdd)
134{
135  float maxAddEnergy = this->energyMax - this->energy;
136
137  if (maxAddEnergy >= energyToAdd)
138  {
139    this->energy += energyToAdd;
140    return 0.0;
141  }
142  else
143  {
144    this->energy += maxAddEnergy;
145    return energyToAdd - maxAddEnergy;
146  }
147}
148
149bool Weapon::execute()
150{
151  this->stateDuration = this->times[this->requestedAction] + this->stateDuration;
152
153  PRINTF(4)("trying to execute action %s\n", actionToChar(this->requestedAction));
154  this->debug();
155
156  switch (this->requestedAction)
157  {
158    case WA_SHOOT:
159      //if (likely(this->currentState != WS_INACTIVE))
160      {
161        if (this->minCharge <= this->energyLoaded)
162        {
163          if (this->soundBuffers[WA_SHOOT] != NULL)
164            this->soundSource->play(this->soundBuffers[WA_SHOOT]);
165          this->fire();
166          this->requestedAction = WA_NONE;
167        }
168        else  // reload if we still have the charge
169        {
170          this->requestedAction = WA_NONE;
171          this->requestAction(WA_RELOAD);
172        }
173      }
174      break;
175    case WA_CHARGE:
176      if ( this->currentState != WS_INACTIVE && this->energyLoaded >= this->minCharge)
177      {
178        if (this->soundBuffers[WA_CHARGE] != NULL)
179         this->soundSource->play(this->soundBuffers[WA_CHARGE]);
180        this->charge();
181        this->requestedAction = WA_NONE;
182      }
183      else // deactivate the Weapon if we do not have enough energy
184      {
185        this->requestedAction = WA_NONE;
186        this->requestAction(WA_RELOAD);
187      }
188      break;
189    case WA_RELOAD:
190      //if (this->currentState != WS_INACTIVE && this->energy + this->energyLoaded >= this->minCharge)
191      {
192        if (this->soundBuffers[WA_RELOAD] != NULL)
193          this->soundSource->play(this->soundBuffers[WA_RELOAD]);
194
195        this->reload();
196        this->requestedAction = WA_NONE;
197      }
198      break;
199    case WA_DEACTIVATE:
200      if (this->currentState != WS_INACTIVE)
201      {
202        if (this->soundBuffers[WA_DEACTIVATE] != NULL)
203          this->soundSource->play(this->soundBuffers[WA_DEACTIVATE]);
204
205        this->deactivate();
206        this->requestedAction = WA_NONE;
207      }
208      break;
209    case WA_ACTIVATE:
210      if (this->currentState == WS_INACTIVE)
211      {
212        if (this->soundBuffers[WA_ACTIVATE] != NULL)
213          this->soundSource->play(this->soundBuffers[WA_ACTIVATE]);
214
215        this->activate();
216        this->requestedAction = WA_NONE;
217      }
218      break;
219  }
220}
221
222/**
223 * this activates the weapon
224*/
225void Weapon::activate()
226{
227  PRINTF(4)("Activating the Weapon %s\n", this->getName());
228
229  if (this->soundBuffers[WA_ACTIVATE] != NULL)
230    this->soundSource->play(this->soundBuffers[WA_ACTIVATE]);
231}
232
233
234/**
235 * this deactivates the weapon
236*/
237void Weapon::deactivate()
238{
239  PRINTF(4)("Deactivating the Weapon %s\n", this->getName());
240
241  if (this->soundBuffers[WA_DEACTIVATE] != NULL)
242    this->soundSource->play(this->soundBuffers[WA_DEACTIVATE]);
243}
244
245void Weapon::fire()
246{
247  this->energyLoaded -= this->minCharge;
248
249  if (this->soundBuffers[WA_SHOOT] != NULL)
250    this->soundSource->play(this->soundBuffers[WA_SHOOT]);
251}
252
253void Weapon::reload()
254{
255  PRINTF(4)("Reloading Weapon %s\n", this->getName());
256  if (this->energy + this->energyLoaded < this->minCharge)
257  {
258    this->requestAction(WA_DEACTIVATE);
259    return;
260  }
261
262  float chargeSize = this->energyLoadedMax - this->energyLoaded;       //!< The energy to be charged
263
264  if (chargeSize > this->energy)
265  {
266    this->energyLoaded += this->energy;
267    this->energy = 0.0;
268    PRINT(3)("Energy empty");
269  }
270  else
271  {
272    PRINTF(3)("Loaded %f energy into the Guns Buffer\n", chargeSize);
273    this->energyLoaded += chargeSize;
274    this->energy -= chargeSize;
275  }
276  if (this->soundBuffers[WA_RELOAD] != NULL)
277    this->soundSource->play(this->soundBuffers[WA_RELOAD]);
278
279}
280
281void Weapon::charge()
282{
283  if (this->soundBuffers[WA_CHARGE] != NULL)
284    this->soundSource->play(this->soundBuffers[WA_CHARGE]);
285
286}
287
288
289/**
290 *  is called, when the weapon is destroyed
291 *
292 * this is in conjunction with the hit function, so when a weapon is able to get
293 * hit, it can also be destoryed.
294*/
295void Weapon::destroy ()
296{}
297
298
299/**
300 * tick signal for time dependent/driven stuff
301*/
302void Weapon::tick(float dt)
303{
304  // setting up the timing properties
305  this->stateDuration -= dt;
306
307  if (this->isActive())
308  {
309    if (this->stateDuration <= 0.0 && this->requestedAction != WA_NONE)
310    {
311      this->stateDuration = -dt;
312      this->execute();
313    }
314  }
315  else
316    if (this->requestedAction == WA_ACTIVATE)
317      this->activate();
318
319}
320
321/**
322 *  this will draw the weapon
323*/
324void Weapon::draw ()
325{}
326
327
328
329
330
331//////////////////////
332// HELPER FUNCTIONS //
333//////////////////////
334// inclass
335/**
336 * checks if the next Action given is valid
337 * @returns if the Action that comes next is valid
338 * @todo more checks
339 */
340bool Weapon::nextActionValid() const
341{
342  if (this->currentState == WS_INACTIVE)
343  {
344    return (this->requestedAction == WA_ACTIVATE || this->requestedAction == WA_NONE);
345  }
346  else
347    return true;
348
349}
350
351
352/**
353 * some nice debugging information about this Weapon
354 */
355void Weapon::debug() const
356{
357  PRINT(3)("Weapon-Debug %s, state: %s, nexAction: %s\n", this->getName(), Weapon::stateToChar(this->currentState), Weapon::actionToChar(requestedAction));
358  PRINT(3)("Energy: max: %f; current: %f;  loadedMax: %f; loadedCurrent: %f; chargeMin: %f, chargeMax %f\n",
359            this->energyMax, this->energy, this->energyLoadedMax, this->energyLoaded, this->minCharge, this->maxCharge);
360}
361
362
363// static
364/**
365 * Converts a String into an Action.
366 * @param action the String input holding the Action.
367 * @return The Action if known, WA_NONE otherwise.
368 */
369WeaponAction Weapon::charToAction(const char* action)
370{
371  if (!strcmp(action, "none"))
372    return WA_NONE;
373  else if (!strcmp(action, "shoot"))
374    return WA_SHOOT;
375  else if (!strcmp(action, "charge"))
376    return WA_CHARGE;
377  else if (!strcmp(action, "reload"))
378    return WA_RELOAD;
379  else if (!strcmp(action, "acitvate"))
380    return WA_ACTIVATE;
381  else if (!strcmp(action, "deactivate"))
382    return WA_DEACTIVATE;
383  else if (!strcmp(action, "special1"))
384    return WA_SPECIAL1;
385  else
386    {
387      PRINTF(2)("action %s could not be identified.\n", action);
388      return WA_NONE;
389    }
390}
391
392/**
393 * converts an action into a String
394 * @param action the action to convert
395 * @return a String matching the name of the action
396 */
397const char* Weapon::actionToChar(WeaponAction action)
398{
399  switch (action)
400  {
401    case WA_SHOOT:
402      return "shoot";
403      break;
404    case WA_CHARGE:
405      return "charge";
406      break;
407    case WA_RELOAD:
408      return "reload";
409      break;
410    case WA_ACTIVATE:
411      return "activate";
412      break;
413    case WA_DEACTIVATE:
414      return "deactivate";
415      break;
416    case WA_SPECIAL1:
417      return "special1";
418      break;
419    default:
420      return "none";
421      break;
422  }
423}
424
425/**
426 * Converts a String into a State.
427 * @param state the String input holding the State.
428 * @return The State if known, WS_NONE otherwise.
429 */
430WeaponState Weapon::charToState(const char* state)
431{
432  if (!strcmp(state, "none"))
433    return WS_NONE;
434  else if (!strcmp(state, "shooting"))
435    return WS_SHOOTING;
436  else if (!strcmp(state, "charging"))
437    return WS_CHARGING;
438  else if (!strcmp(state, "reloading"))
439    return WS_RELOADING;
440  else if (!strcmp(state, "activating"))
441    return WS_ACTIVATING;
442  else if (!strcmp(state, "deactivating"))
443    return WS_DEACTIVATING;
444  else if (!strcmp(state, "inactive"))
445    return WS_INACTIVE;
446  else if (!strcmp(state, "idle"))
447    return WS_IDLE;
448  else
449    {
450      PRINTF(2)("state %s could not be identified.\n", state);
451      return WS_NONE;
452    }
453}
454
455/**
456 * converts a State into a String
457 * @param state the state to convert
458 * @return a String matching the name of the state
459 */
460const char* Weapon::stateToChar(WeaponState state)
461{
462  switch (state)
463  {
464    case WS_SHOOTING:
465      return "shooting";
466      break;
467    case WS_CHARGING:
468      return "charging";
469      break;
470    case WS_RELOADING:
471      return "reloading";
472      break;
473    case WS_ACTIVATING:
474      return "activating";
475      break;
476    case WS_DEACTIVATING:
477      return "deactivating";
478      break;
479    case WS_IDLE:
480      return "idle";
481      break;
482    default:
483      return "none";
484      break;
485  }
486}
Note: See TracBrowser for help on using the repository browser.