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
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;
[4884]93  else if (soundFile != NULL)
[4883]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  }
[4884]105  else
106    this->soundBuffers[action] = NULL;
[3575]107}
[3573]108
[3575]109/**
[4883]110 * request an action that should be executed,
111 * @param action the next action to take
[4878]112 *
[4883]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 */
[4880]116void Weapon::requestAction(WeaponAction action)
117{
[4882]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  }
[4880]125}
126
[4881]127bool Weapon::execute()
[4880]128{
[4881]129  this->stateDuration = this->times[this->requestedAction] + this->stateDuration;
[4880]130
[4882]131  PRINTF(4)("trying to execute action %s\n", actionToChar(this->requestedAction));
132  this->debug();
[4881]133
134  switch (this->requestedAction)
[4880]135  {
136    case WA_SHOOT:
[4882]137      //if (likely(this->currentState != WS_INACTIVE))
138      {
[4884]139        if (this->minCharge <= this->energyLoaded)
[4882]140        {
[4884]141          if (this->soundBuffers[WA_SHOOT] != NULL)
142            this->soundSource->play(this->soundBuffers[WA_SHOOT]);
[4882]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      }
[4880]152      break;
153    case WA_CHARGE:
[4882]154      if ( this->currentState != WS_INACTIVE && this->energyLoaded >= this->minCharge)
155      {
[4884]156        if (this->soundBuffers[WA_CHARGE] != NULL)
157         this->soundSource->play(this->soundBuffers[WA_CHARGE]);
[4882]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      }
[4880]166      break;
167    case WA_RELOAD:
[4882]168      //if (this->currentState != WS_INACTIVE && this->energy + this->energyLoaded >= this->minCharge)
169      {
[4884]170        if (this->soundBuffers[WA_RELOAD] != NULL)
171          this->soundSource->play(this->soundBuffers[WA_RELOAD]);
172
[4882]173        this->reload();
174        this->requestedAction = WA_NONE;
175      }
[4880]176      break;
177    case WA_DEACTIVATE:
[4882]178      if (this->currentState != WS_INACTIVE)
179      {
[4884]180        if (this->soundBuffers[WA_DEACTIVATE] != NULL)
181          this->soundSource->play(this->soundBuffers[WA_DEACTIVATE]);
182
[4882]183        this->deactivate();
184        this->requestedAction = WA_NONE;
185      }
[4880]186      break;
187    case WA_ACTIVATE:
[4882]188      if (this->currentState == WS_INACTIVE)
189      {
[4884]190        if (this->soundBuffers[WA_ACTIVATE] != NULL)
191          this->soundSource->play(this->soundBuffers[WA_ACTIVATE]);
192
[4882]193        this->activate();
194        this->requestedAction = WA_NONE;
195      }
[4880]196      break;
197  }
198}
199
[3575]200/**
[4878]201 * this activates the weapon
[3575]202*/
203void Weapon::activate()
[4882]204{
205  PRINTF(4)("Activating the Weapon %s\n", this->getName());
[4883]206
207  if (this->soundBuffers[WA_ACTIVATE] != NULL)
208    this->soundSource->play(this->soundBuffers[WA_ACTIVATE]);
[4882]209}
[3575]210
211
212/**
[4878]213 * this deactivates the weapon
[3575]214*/
215void Weapon::deactivate()
[4882]216{
217  PRINTF(4)("Deactivating the Weapon %s\n", this->getName());
[4883]218
219  if (this->soundBuffers[WA_DEACTIVATE] != NULL)
220    this->soundSource->play(this->soundBuffers[WA_DEACTIVATE]);
[4882]221}
[3575]222
[4880]223void Weapon::fire()
224{
[4882]225  this->energyLoaded -= this->minCharge;
[4883]226
227  if (this->soundBuffers[WA_SHOOT] != NULL)
228    this->soundSource->play(this->soundBuffers[WA_SHOOT]);
[4880]229}
[3577]230
[4880]231void Weapon::reload()
232{
[4882]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  }
[4880]239
[4882]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  }
[4883]254  if (this->soundBuffers[WA_RELOAD] != NULL)
255    this->soundSource->play(this->soundBuffers[WA_RELOAD]);
256
[4880]257}
258
259void Weapon::charge()
260{
[4883]261  if (this->soundBuffers[WA_CHARGE] != NULL)
262    this->soundSource->play(this->soundBuffers[WA_CHARGE]);
263
[4880]264}
265
266
[3575]267/**
[4836]268 *  is called, when the weapon is destroyed
[4878]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.
[3575]272*/
[4597]273void Weapon::destroy ()
[3575]274{}
275
276
277/**
[4880]278 * tick signal for time dependent/driven stuff
[3577]279*/
[4880]280void Weapon::tick(float dt)
281{
[4881]282  // setting up the timing properties
283  this->stateDuration -= dt;
284
[4880]285  if (this->isActive())
286  {
[4881]287    if (this->stateDuration <= 0.0 && this->requestedAction != WA_NONE)
[4882]288    {
289      this->stateDuration = -dt;
[4881]290      this->execute();
[4882]291    }
[4880]292  }
293  else
294    if (this->requestedAction == WA_ACTIVATE)
295      this->activate();
296
297}
298
[3577]299/**
[4879]300 *  this will draw the weapon
[3583]301*/
[4879]302void Weapon::draw ()
[3583]303{}
304
305
[4879]306
307
308
[4880]309//////////////////////
310// HELPER FUNCTIONS //
311//////////////////////
312// inclass
[3583]313/**
[4880]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
[4882]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}
[4880]339
[4882]340
[4880]341// static
342/**
[4879]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
[4880]364    {
365      PRINTF(2)("action %s could not be identified.\n", action);
366      return WA_NONE;
367    }
[4879]368}
[3575]369
[4879]370/**
[4882]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/**
[4879]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;
[4880]414  else if (!strcmp(state, "charging"))
415    return WS_CHARGING;
[4879]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
[4880]427    {
428      PRINTF(2)("state %s could not be identified.\n", state);
429      return WS_NONE;
430    }
[4879]431}
[4882]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.