Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: saver implementation of state-variables.
this step makes the execute function very big, and as such is not the best idea, maybe i will split up the checks in the execute-functions so one has a better insight into what is happening in weapon.
For this maybe a wrapper around fire/reload… functions will be written, that calls them within a fireWeapon/reloadWeapon function

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