Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/mount_points/src/world_entities/world_entity.cc @ 10052

Last change on this file since 10052 was 10052, checked in by patrick, 17 years ago

integrating loading to we

File size: 19.9 KB
RevLine 
[2036]1
2
[4570]3/*
[2036]4   orxonox - the future of 3D-vertical-scrollers
5
6   Copyright (C) 2004 orx
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   ### File Specific:
14   main-programmer: Patrick Boenzli
[2190]15   co-programmer: Christian Meyer
[2036]16*/
[5300]17#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
[2036]18
19#include "world_entity.h"
[5208]20#include "shell_command.h"
[5143]21
[9869]22#include "util/loading/resource_manager.h"
23#include "resource_obj.h"
[8490]24#include "md2/md2Model.h"
25#include "md3/md3_model.h"
[10052]26#include "oif/object_information_file.h"
[8490]27
[8724]28#include "aabb_tree_node.h"
29
[7193]30#include "util/loading/load_param.h"
[4682]31#include "obb_tree.h"
[3608]32
[8974]33#include "elements/glgui_energywidget.h"
[6430]34
[6002]35#include "state.h"
[7014]36#include "camera.h"
[6002]37
[10013]38#include "collision_filter.h"
[8190]39#include "collision_event.h"
[8777]40#include "game_rules.h"
41#include "kill.h"
[9869]42#include "debug.h"
[7927]43
[9869]44#include "projectiles/projectile.h"
[7927]45
[5208]46SHELL_COMMAND(model, WorldEntity, loadModel)
[6430]47->describe("sets the Model of the WorldEntity")
[7711]48->defaultValues("models/ships/fighter.obj", 1.0f);
[5208]49
[6424]50SHELL_COMMAND(debugEntity, WorldEntity, debugWE);
[5208]51
[9869]52
53ObjectListDefinition(WorldEntity);
[2043]54/**
[4836]55 *  Loads the WordEntity-specific Part of any derived Class
[5498]56 *
57 * @param root: Normally NULL, as the Derived Entities define a loadParams Function themeselves,
58 *              that can calls WorldEntities loadParams for itself.
59 */
[6430]60WorldEntity::WorldEntity()
[10013]61  : Synchronizeable(), _collisionFilter(this)
[2190]62{
[9869]63  this->registerObject(this, WorldEntity::_objectList);
[4597]64
[4682]65  this->obbTree = NULL;
[8724]66  this->aabbNode = NULL;
[6700]67  this->healthWidget = NULL;
68  this->healthMax = 1.0f;
69  this->health = 1.0f;
[8190]70  this->damage = 0.0f; // no damage dealt by a default entity
[6695]71  this->scaling = 1.0f;
[4261]72
[6695]73  /* OSOLETE */
74  this->bVisible = true;
75  this->bCollide = true;
76
[6142]77  this->objectListNumber = OM_INIT;
[9003]78  this->lastObjectListNumber = OM_INIT;
[6142]79
[10013]80  this->_bOnGround = false;
[8190]81
82  // registering default reactions:
[10013]83  this->subscribeReaction(CoRe::CREngine::CR_OBJECT_DAMAGE, Projectile::staticClassID());
[8190]84
[6142]85  this->toList(OM_NULL);
[9235]86
[10013]87  this->registerVar( new SynchronizeableString( &this->md2TextureFileName, &this->md2TextureFileName, "md2TextureFileName", PERMISSION_MASTER_SERVER ) );
88  this->modelFileName_handle = registerVarId( new SynchronizeableString( &modelFileName, &modelFileName, "modelFileName", PERMISSION_MASTER_SERVER ) );
89  this->scaling_handle = registerVarId( new SynchronizeableFloat( &scaling, &scaling, "scaling", PERMISSION_MASTER_SERVER ) );
90  this->list_handle = registerVarId( new SynchronizeableInt( (int*)&objectListNumber, &list_write, "list", PERMISSION_MASTER_SERVER ) );
[9235]91
[10013]92  this->health_handle = registerVarId( new SynchronizeableFloat( &this->health, &this->health_write, "health", PERMISSION_MASTER_SERVER ) );
93  this->healthMax_handle = registerVarId( new SynchronizeableFloat( &this->healthMax, &this->healthMax_write, "maxHealth", PERMISSION_MASTER_SERVER ) );
[2190]94}
[2043]95
96/**
[4836]97 *  standard destructor
[2043]98*/
[2190]99WorldEntity::~WorldEntity ()
[2036]100{
[7125]101  State::getObjectManager()->toList(this, OM_INIT);
102
103  // Delete the model (unregister it with the ResourceManager)
104  for (unsigned int i = 0; i < this->models.size(); i++)
105    this->setModel(NULL, i);
106
[5498]107  // Delete the obbTree
[5302]108  if( this->obbTree != NULL)
[4814]109    delete this->obbTree;
[5994]110
[6700]111  if (this->healthWidget != NULL)
112    delete this->healthWidget;
[8190]113
[10013]114  this->unsubscribeReactions();
[3531]115}
116
[5498]117/**
118 * loads the WorldEntity Specific Parameters.
119 * @param root: the XML-Element to load the Data From
120 */
[4436]121void WorldEntity::loadParams(const TiXmlElement* root)
122{
[5498]123  // Do the PNode loading stuff
[6512]124  PNode::loadParams(root);
[5498]125
[6222]126  LoadParam(root, "md2texture", this, WorldEntity, loadMD2Texture)
[6430]127  .describe("the fileName of the texture, that should be loaded onto this world-entity. (must be relative to the data-dir)")
[7198]128  .defaultValues("");
[6222]129
[4436]130  // Model Loading
[5671]131  LoadParam(root, "model", this, WorldEntity, loadModel)
[6430]132  .describe("the fileName of the model, that should be loaded onto this world-entity. (must be relative to the data-dir)")
[7198]133  .defaultValues("", 1.0f, 0);
[6430]134
[6700]135  LoadParam(root, "maxHealth", this, WorldEntity, setHealthMax)
136  .describe("The Maximum health that can be loaded onto this entity")
[7198]137  .defaultValues(1.0f);
[6430]138
[6700]139  LoadParam(root, "health", this, WorldEntity, setHealth)
140  .describe("The Health the WorldEntity has at this moment")
[7198]141  .defaultValues(1.0f);
[9656]142
143  LoadParam(root, "list", this, WorldEntity, toListS);
[4436]144}
145
[6222]146
[3531]147/**
[4885]148 * loads a Model onto a WorldEntity
[4836]149 * @param fileName the name of the model to load
[5057]150 * @param scaling the Scaling of the model
[7711]151 *
152 * FIXME
153 * @todo: separate the obb tree generation from the model
[7221]154 */
[7711]155void WorldEntity::loadModel(const std::string& fileName, float scaling, unsigned int modelNumber, unsigned int obbTreeDepth)
[4261]156{
[6695]157  this->modelLODName = fileName;
[6424]158  this->scaling = scaling;
[7954]159
160  std::string name = fileName;
161
[9869]162  if (  name.find( Resources::ResourceManager::getInstance()->mainGlobalPath().name() ) == 0 )
[7954]163  {
[9869]164    name.erase(Resources::ResourceManager::getInstance()->mainGlobalPath().name().size());
[7954]165  }
166
167  this->modelFileName = name;
168
[7221]169  if (!fileName.empty())
[6142]170  {
[6430]171    // search for the special character # in the LoadParam
[7221]172    if (fileName.find('#') != std::string::npos)
[6222]173    {
[7221]174      PRINTF(4)("Found # in %s... searching for LOD's\n", fileName.c_str());
175      std::string lodFile = fileName;
176      unsigned int offset = lodFile.find('#');
[6720]177      for (unsigned int i = 0; i < 3; i++)
[6005]178      {
[7221]179        lodFile[offset] = 48+(int)i;
[9869]180        if (Resources::ResourceManager::getInstance()->checkFileInMainPath( lodFile))
[6222]181          this->loadModel(lodFile, scaling, i);
[6005]182      }
[6222]183      return;
184    }
[6720]185    if (this->scaling <= 0.0)
[6424]186    {
[7193]187      PRINTF(1)("YOU GAVE ME A CRAPY SCALE resetting to 1.0\n");
[6720]188      this->scaling = 1.0;
[6424]189    }
[9869]190    /// LOADING AN OBJ FILE
[7221]191    if(fileName.find(".obj") != std::string::npos)
[6222]192    {
[7221]193      PRINTF(4)("fetching OBJ file: %s\n", fileName.c_str());
[10052]194      // creating the model and loading it
[9869]195      StaticModel* model = new StaticModel();
196      *model = ResourceOBJ(fileName, this->scaling);
197      if (model->getVertexCount() > 0)
198      {
199        this->setModel(model, modelNumber);
200        if( modelNumber == 0 /* FIXME && !this->isA(CL_WEAPON) */)
201          this->buildObbTree(obbTreeDepth);
202      }
[7221]203      else
[9869]204        delete model;
[10052]205
206      // now get the object information file for this model, if any
207      std::string oifName = fileName.substr(0, fileName.length() - 3) + ".oif";
208      this->loadObjectInformationFile( oifName);
[6222]209    }
[9869]210    /// LOADING AN MD2-model
[7221]211    else if(fileName.find(".md2") != std::string::npos)
[6222]212    {
[7221]213      PRINTF(4)("fetching MD2 file: %s\n", fileName.c_str());
[7055]214      Model* m = new MD2Model(fileName, this->md2TextureFileName, this->scaling);
[6430]215      //this->setModel((Model*)ResourceManager::getInstance()->load(fileName, MD2, RP_CAMPAIGN), 0);
[6222]216      this->setModel(m, 0);
[7068]217
218      if( m != NULL)
[7711]219        this->buildObbTree(obbTreeDepth);
[6222]220    }
[9869]221    /// LOADING AN MD3-MODEL.
[9235]222    else if(fileName.find(".md3") != std::string::npos)
[8490]223    {
224      PRINTF(4)("fetching MD3 file: %s\n", fileName.c_str());
[9869]225//      Model* m = new md3::MD3Model(fileName, this->scaling);
226//      this->setModel(m, 0);
[8490]227
[9869]228      //       if( m != NULL)
229      //         this->buildObbTree(obbTreeDepth);
[8490]230    }
[4732]231  }
232  else
[6341]233  {
[5995]234    this->setModel(NULL);
[6341]235  }
[4261]236}
237
[5061]238/**
[5994]239 * sets a specific Model for the Object.
240 * @param model The Model to set
241 * @param modelNumber the n'th model in the List to get.
242 */
243void WorldEntity::setModel(Model* model, unsigned int modelNumber)
244{
[5995]245  if (this->models.size() <= modelNumber)
246    this->models.resize(modelNumber+1, NULL);
247
248  if (this->models[modelNumber] != NULL)
[6004]249  {
[9869]250    delete this->models[modelNumber];
[5994]251  }
[6222]252
[5995]253  this->models[modelNumber] = model;
[5994]254}
255
256
[10052]257
[5994]258/**
[10052]259 * loads the object information file for this model
260 * @param fileName the name of the file
261 */
262void WorldEntity::loadObjectInformationFile(const std::string& fileName)
263{
264  PRINTF(0)("loading the oif File: %s", fileName.c_str());
265}
266
267
268/**
[5061]269 * builds the obb-tree
270 * @param depth the depth to calculate
271 */
[7711]272bool WorldEntity::buildObbTree(int depth)
[5061]273{
[9494]274  if( this->obbTree != NULL)
275  {
[5428]276    delete this->obbTree;
[9494]277    this->obbTree = NULL;
278  }
[5428]279
[5995]280  if (this->models[0] != NULL)
[7711]281    this->obbTree = new OBBTree(depth, models[0]->getModelInfo(), this);
[5428]282  else
283  {
[7711]284    PRINTF(1)("could not create obb-tree, because no model was loaded yet\n");
[5428]285    this->obbTree = NULL;
286    return false;
287  }
[8724]288
289
290  // create the axis aligned bounding box
291  if( this->aabbNode != NULL)
292  {
293    delete this->aabbNode;
294    this->aabbNode = NULL;
295  }
296
[9869]297  if( this->models[0] != NULL)
298  {
[8724]299    this->aabbNode = new AABBTreeNode();
300    this->aabbNode->spawnBVTree(this->models[0]);
301  }
[9494]302  else
303  {
304    PRINTF(1)("could not create aabb bounding box, because no model was loaded yet\n");
305    this->aabbNode = NULL;
306    return false;
307  }
[8724]308  return true;
[5061]309}
[5057]310
[7927]311
[6142]312/**
[7927]313 * subscribes this world entity to a collision reaction
314 *  @param type the type of reaction to subscribe to
[8190]315 *  @param target1 a filter target (classID)
316 */
[10013]317void WorldEntity::subscribeReaction(CoRe::CREngine::ReactionType type, const ClassID& target1)
[8190]318{
[10013]319  this->_collisionFilter.subscribeReaction(type, target1);
[8190]320}
321
322
323/**
324 * subscribes this world entity to a collision reaction
325 *  @param type the type of reaction to subscribe to
326 *  @param target1 a filter target (classID)
327 */
[10013]328void WorldEntity::subscribeReaction(CoRe::CREngine::ReactionType type, const ClassID& target1, const ClassID& target2)
[8190]329{
[10013]330  this->_collisionFilter.subscribeReaction(type, target1, target2);
[8190]331}
332
333
334/**
335 * subscribes this world entity to a collision reaction
336 *  @param type the type of reaction to subscribe to
337 *  @param target1 a filter target (classID)
338 */
[10013]339void WorldEntity::subscribeReaction(CoRe::CREngine::ReactionType type, const ClassID& target1, const ClassID& target2, const ClassID& target3)
[8190]340{
[10013]341  this->_collisionFilter.subscribeReaction(type, target1, target2, target3);
[8190]342}
343
344
345/**
346 * unsubscribes a specific reaction from the worldentity
347 *  @param type the reaction to unsubscribe
348 */
[10013]349void WorldEntity::unsubscribeReaction(CoRe::CREngine::ReactionType type)
[8190]350{
[10013]351  this->_collisionFilter.unsubscribeReaction(type);
[8190]352}
353
354
355/**
356 * unsubscribes all collision reactions
357 */
[10013]358void WorldEntity::unsubscribeReactions()
[8190]359{
[10013]360  this->_collisionFilter.unsubscribeReactions();
[8190]361}
362
363
364/**
[6142]365 * @brief moves this entity to the List OM_List
366 * @param list the list to set this Entity to.
367 *
368 * this is the same as a call to State::getObjectManager()->toList(entity , list);
369 * directly, but with an easier interface.
370 *
371 * @todo inline this (peut etre)
372 */
373void WorldEntity::toList(OM_LIST list)
374{
375  State::getObjectManager()->toList(this, list);
376}
[5061]377
[9656]378void WorldEntity::toListS(const std::string& listName)
379{
380  OM_LIST id = ObjectManager::StringToOMList(listName);
381  if (id != OM_NULL)
382    this->toList(id);
383  else
384    PRINTF(2)("List %s not found\n", listName.c_str());
385}
386
387
[8037]388void WorldEntity::toReflectionList()
389{
390  State::getObjectManager()->toReflectionList( this );
391}
[6142]392
[8037]393void removeFromReflectionList()
394{
[9869]395  /// TODO
396  ///  State::getObject
[8037]397}
[6142]398
[4261]399/**
[4885]400 * sets the character attributes of a worldentity
[4836]401 * @param character attributes
[4885]402 *
403 * these attributes don't have to be set, only use them, if you need them
[2043]404*/
[5498]405//void WorldEntity::setCharacterAttributes(CharacterAttributes* charAttr)
406//{}
[2036]407
[3583]408
[2043]409/**
[5029]410 *  this function is called, when two entities collide
411 * @param entity: the world entity with whom it collides
412 *
413 * Implement behaviour like damage application or other miscellaneous collision stuff in this function
414 */
415void WorldEntity::collidesWith(WorldEntity* entity, const Vector& location)
416{
[5498]417  /**
418   * THIS IS A DEFAULT COLLISION-Effect.
419   * IF YOU WANT TO CREATE A SPECIFIC COLLISION ON EACH OBJECT
420   * USE::
421   * if (entity->isA(CL_WHAT_YOU_ARE_LOOKING_FOR)) { printf "dothings"; };
422   *
423   * You can always define a default Action.... don't be affraid just test it :)
424   */
[9406]425  //  PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getClassCName(), entity->getClassCName(), location.x, location.y, location.z);
[5029]426}
427
[2043]428
429/**
[8186]430 *  this function is called, when two entities collide
431 * @param entity: the world entity with whom it collides
432 *
433 * Implement behaviour like damage application or other miscellaneous collision stuff in this function
434 */
435void WorldEntity::collidesWithGround(const Vector& location)
436{
[9406]437  PRINTF(0)("BSP_GROUND: %s collides \n", this->getClassCName() );
[8186]438}
439
440void WorldEntity::collidesWithGround(const Vector& feet, const Vector& ray_1, const Vector& ray_2)
441{
[8190]442
[9406]443  // PRINTF(0)("BSP_GROUND: Player collides \n", this->getClassCName() );
[8190]444
[8186]445  Vector v = this->getAbsDirX();
[8490]446  v.x *= 10.1;
447  v.y *= 10.1;
448  v.z *= 10.1;
449  Vector u = Vector(0.0,-20.0,0.0);
[8190]450
[8490]451
452  if(!(this->getAbsCoor().x == ray_2.x && this->getAbsCoor().y == ray_2.y && this->getAbsCoor().z == ray_2.z) )
[8186]453  {
[8190]454
[9869]455    this->setAbsCoor(ray_2 - v);
[8490]456
[8186]457  }
[9869]458  else
[8186]459  {
460    if(ray_1.x == this->getAbsCoor().x + v.x && ray_1.y == this->getAbsCoor().y + v.y + 0.1 && ray_1.z ==this->getAbsCoor().z + v.z)
461    {
[8190]462      this->setAbsCoor(feet -u );
[8186]463    }
[8190]464
465    this->setAbsCoor(ray_2 - v);
466
[8186]467  }
[8490]468
469
[8186]470}
471
472/**
[5498]473 *  this is called immediately after the Entity has been constructed, initialized and then Spawned into the World
[4885]474 *
[5498]475 */
[3229]476void WorldEntity::postSpawn ()
[6430]477{}
[2043]478
[3583]479
[2043]480/**
[6959]481 *  this method is called by the world if the WorldEntity leaves the game
[5498]482 */
[6959]483void WorldEntity::leaveWorld ()
[6430]484{}
[2043]485
[3583]486
[2190]487/**
[7085]488 * resets the WorldEntity to its initial values. eg. used for multiplayer games: respawning
489 */
490void WorldEntity::reset()
[9235]491{
492  this->setHealth( this->getHealthMax() );
493}
[7085]494
495/**
[4836]496 *  this method is called every frame
497 * @param time: the time in seconds that has passed since the last tick
[4885]498 *
499 * Handle all stuff that should update with time inside this method (movement, animation, etc.)
[2043]500*/
[4570]501void WorldEntity::tick(float time)
[6430]502{}
[3583]503
[5498]504
[3583]505/**
[4836]506 *  the entity is drawn onto the screen with this function
[4885]507 *
508 * This is a central function of an entity: call it to let the entity painted to the screen.
509 * Just override this function with whatever you want to be drawn.
[3365]510*/
[5500]511void WorldEntity::draw() const
[3803]512{
[9406]513  //PRINTF(0)("(%s::%s)\n", this->getClassCName(), this->getName());
[6281]514  //  assert(!unlikely(this->models.empty()));
[6002]515  {
516    glMatrixMode(GL_MODELVIEW);
517    glPushMatrix();
[4570]518
[6002]519    /* translate */
520    glTranslatef (this->getAbsCoor ().x,
521                  this->getAbsCoor ().y,
522                  this->getAbsCoor ().z);
[6004]523    Vector tmpRot = this->getAbsDir().getSpacialAxis();
524    glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
[2043]525
[6004]526
527    // This Draws the LOD's
[7014]528    float cameraDistance = State::getCamera()->distance(this);
[6004]529    if (cameraDistance > 30 && this->models.size() >= 3 && this->models[2] != NULL)
[6002]530    {
[6222]531      this->models[2]->draw();
[6004]532    }
533    else if (cameraDistance > 10 && this->models.size() >= 2 && this->models[1] != NULL)
[6002]534    {
535      this->models[1]->draw();
[6004]536    }
537    else if (this->models.size() >= 1 && this->models[0] != NULL)
[6002]538    {
539      this->models[0]->draw();
540    }
[8724]541
[9869]542    //     if( this->aabbNode != NULL)
543    //       this->aabbNode->drawBV(0, DRAW_BV_POLYGON, Vector(1, 0.6, 0.2), true);
[8724]544
[6002]545    glPopMatrix();
546  }
[3803]547}
[3583]548
[6430]549/**
[6700]550 * @param health the Health to add.
551 * @returns the health left (this->healthMax - health+this->health)
[6430]552 */
[6700]553float WorldEntity::increaseHealth(float health)
[6430]554{
[6700]555  this->health += health;
556  if (this->health > this->healthMax)
[6430]557  {
[6700]558    float retHealth = this->healthMax - this->health;
559    this->health = this->healthMax;
560    this->updateHealthWidget();
561    return retHealth;
[6430]562  }
[6700]563  this->updateHealthWidget();
[6430]564  return 0.0;
565}
[6281]566
[5498]567/**
[6700]568 * @param health the Health to be removed
[6430]569 * @returns 0.0 or the rest, that was not substracted (bellow 0.0)
570 */
[6700]571float WorldEntity::decreaseHealth(float health)
[6430]572{
[6700]573  this->health -= health;
[6430]574
[6700]575  if (this->health < 0)
[6430]576  {
[6700]577    float retHealth = -this->health;
578    this->health = 0.0f;
579    this->updateHealthWidget();
580    return retHealth;
[6430]581  }
[6700]582  this->updateHealthWidget();
[6430]583  return 0.0;
584
585}
586
587/**
[6700]588 * @param maxHealth the maximal health that can be loaded onto the entity.
[6430]589 */
[6700]590void WorldEntity::setHealthMax(float healthMax)
[6430]591{
[6700]592  this->healthMax = healthMax;
593  if (this->health > this->healthMax)
[6430]594  {
[9406]595    PRINTF(3)("new maxHealth is bigger as the old health. Did you really intend to do this for (%s::%s)\n", this->getClassCName(), this->getCName());
[6700]596    this->health = this->healthMax;
[6430]597  }
[6700]598  this->updateHealthWidget();
[6430]599}
600
[6431]601/**
[6700]602 * @brief creates the HealthWidget
[6431]603 *
[6700]604 * since not all entities need an HealthWidget, it is only created on request.
[6431]605 */
[6700]606void WorldEntity::createHealthWidget()
[6430]607{
[6700]608  if (this->healthWidget == NULL)
[6430]609  {
[8974]610    this->healthWidget = new OrxGui::GLGuiEnergyWidget();
[8977]611    this->healthWidget->setDisplayedName(std::string(this->getClassName()) + " Energy:");
[6700]612    this->healthWidget->setSize2D(30,400);
613    this->healthWidget->setAbsCoor2D(10,100);
[6430]614
[6700]615    this->updateHealthWidget();
[6430]616  }
617  else
[9406]618    PRINTF(3)("Allready created the HealthWidget for %s::%s\n", this->getClassCName(), this->getCName());
[6430]619}
620
[6700]621void WorldEntity::increaseHealthMax(float increaseHealth)
[6440]622{
[6700]623  this->healthMax += increaseHealth;
624  this->updateHealthWidget();
[6440]625}
626
[6700]627
[7779]628OrxGui::GLGuiWidget* WorldEntity::getHealthWidget()
[6700]629{
630  this->createHealthWidget();
631  return this->healthWidget;
632}
633
[6431]634/**
[6700]635 * @param visibility shows or hides the health-bar
[6431]636 * (creates the widget if needed)
637 */
[6700]638void WorldEntity::setHealthWidgetVisibilit(bool visibility)
[6430]639{
[7198]640  if (visibility)
641  {
642    if (this->healthWidget != NULL)
643      this->healthWidget->show();
644    else
[6430]645    {
[7198]646      this->createHealthWidget();
647      this->updateHealthWidget();
648      this->healthWidget->show();
[6430]649    }
[7198]650  }
651  else if (this->healthWidget != NULL)
652    this->healthWidget->hide();
[6430]653}
654
[8724]655
[6431]656/**
[8724]657 * hit the world entity with
658 *  @param damage damage to be dealt
659 */
[9008]660void WorldEntity::hit(float damage, WorldEntity* killer)
[8724]661{
662  this->decreaseHealth(damage);
663
[9406]664  PRINTF(5)("Hit me: %s::%s now only %f/%f health\n", this->getClassCName(), this->getCName(), this->getHealth(), this->getHealthMax());
[8777]665
[8724]666  if( this->getHealth() > 0)
667  {
668    // any small explosion animaitions
669  }
670  else
671  {
[9235]672    this->destroy( killer );
[8724]673  }
674}
675
676
677/**
[8777]678 * destoys the world entity
679 */
[9235]680void WorldEntity::destroy(WorldEntity* killer)
[8777]681{
682  this->toList(OM_DEAD);
683}
684
685
686/**
[6700]687 * @brief updates the HealthWidget
[6431]688 */
[6700]689void WorldEntity::updateHealthWidget()
[6430]690{
[6700]691  if (this->healthWidget != NULL)
[6430]692  {
[6700]693    this->healthWidget->setMaximum(this->healthMax);
694    this->healthWidget->setValue(this->health);
[6430]695  }
696}
697
698
699/**
[5498]700 * DEBUG-DRAW OF THE BV-Tree.
701 * @param depth What depth to draw
702 * @param drawMode the mode to draw this entity under
703 */
[7711]704void WorldEntity::drawBVTree(int depth, int drawMode) const
[4684]705{
706  glMatrixMode(GL_MODELVIEW);
707  glPushMatrix();
708  /* translate */
709  glTranslatef (this->getAbsCoor ().x,
710                this->getAbsCoor ().y,
711                this->getAbsCoor ().z);
712  /* rotate */
[4998]713  Vector tmpRot = this->getAbsDir().getSpacialAxis();
714  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
[4684]715
[7711]716
[4684]717  if (this->obbTree)
718    this->obbTree->drawBV(depth, drawMode);
[7711]719
720
[4684]721  glPopMatrix();
722}
[6341]723
[6424]724
[6341]725/**
[6424]726 * Debug the WorldEntity
727 */
728void WorldEntity::debugEntity() const
729{
[9406]730  PRINT(0)("WorldEntity %s::%s  (DEBUG)\n", this->getClassCName(), this->getCName());
[6424]731  this->debugNode();
[9656]732  PRINT(0)("List: %s ; ModelCount %d - ", ObjectManager::OMListToString(this->objectListNumber).c_str(), this->models.size());
[6424]733  for (unsigned int i = 0; i < this->models.size(); i++)
734  {
735    if (models[i] != NULL)
[9406]736      PRINT(0)(" : %d:%s", i, this->models[i]->getCName());
[6424]737  }
738  PRINT(0)("\n");
739
740}
741
742
743/**
[7954]744 * handler for changes on registred vars
745 * @param id id's which changed
[6341]746 */
[7954]747void WorldEntity::varChangeHandler( std::list< int > & id )
[6341]748{
[7954]749  if ( std::find( id.begin(), id.end(), modelFileName_handle ) != id.end() ||
750       std::find( id.begin(), id.end(), scaling_handle ) != id.end()
751     )
[6341]752  {
[7954]753    loadModel( modelFileName, scaling );
[6341]754  }
755
[9008]756  if ( std::find( id.begin(), id.end(), list_handle ) != id.end() )
757  {
758    this->toList( (OM_LIST)list_write );
759  }
[9235]760
[9110]761  if ( std::find( id.begin(), id.end(), health_handle ) != id.end() )
762  {
763    this->setHealth( health_write );
764  }
[9235]765
[9110]766  if ( std::find( id.begin(), id.end(), healthMax_handle ) != id.end() )
767  {
768    this->setHealthMax( healthMax_write );
769  }
[9008]770
[7954]771  PNode::varChangeHandler( id );
[6341]772}
773
Note: See TracBrowser for help on using the repository browser.