PhysicalObj Class Reference

#include <physical_obj.h>

Inheritance diagram for PhysicalObj:

Inheritance graph
[legend]
Collaboration diagram for PhysicalObj:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 PhysicalObj (const std::string &name, const std::string &xml_config="")
virtual ~PhysicalObj ()
void SetX (int x)
void SetY (int y)
void SetXY (const Point2i &position)
int GetX () const
int GetY () const
const Point2i GetPosition () const
void SetSize (const Point2i &newSize)
int GetWidth () const
int GetHeight () const
Point2i GetSize () const
void SetTestRect (uint left, uint right, uint top, uint bottom)
const Rectanglei GetTestRect () const
int GetTestWidth () const
int GetTestHeight () const
virtual const std::string & GetName () const
int GetCenterX () const
int GetCenterY () const
const Point2i GetCenter () const
const Rectanglei GetRect () const
bool GoesThroughWall () const
void UpdatePosition ()
bool PutOutOfGround ()
bool PutOutOfGround (double direction)
void SetCollisionModel (bool goes_through_wall, bool collides_with_characters, bool collides_with_objects)
void SetOverlappingObject (PhysicalObj *obj)
virtual bool IsOverlapping (const PhysicalObj *obj) const
bool IsInVacuumXY (const Point2i &position, bool check_objects=true) const
bool IsInVacuum (const Point2i &offset, bool check_objects=true) const
PhysicalObjCollidedObjectXY (const Point2i &position) const
PhysicalObjCollidedObject (const Point2i &offset) const
bool FootsInVacuumXY (const Point2i &position) const
bool FootsInVacuum () const
bool FootsOnFloor (int y) const
bool IsInWater () const
bool IsOutsideWorldXY (Point2i position) const
bool IsOutsideWorld (const Point2i &offset) const
virtual void Refresh ()=0
virtual void Draw ()=0
void AddDamage (uint damage_points)
void Init ()
void Ghost ()
void Drown ()
void GoOutOfWater ()
virtual bool IsImmobile () const
bool IsDead () const
bool IsGhost () const
bool IsDrowned () const
bool ObjTouche (const PhysicalObj &b) const
bool ObjTouche (const Point2i &p) const
bool PutRandomly (bool on_top_of_world, double min_dst_with_characters)

Protected Member Functions

virtual void CheckOverlapping ()
virtual void SignalRebound ()
virtual void SignalObjectCollision (PhysicalObj *obj)
virtual void SignalGroundCollision ()
virtual void SignalCollision ()
virtual void SignalOutOfMap ()

Protected Attributes

PhysicalObjm_overlapping_object
std::string m_name
uint m_test_left
uint m_test_right
uint m_test_top
uint m_test_bottom
uint m_width
uint m_height
std::string m_rebound_sound
alive_t m_alive
int life_points
bool m_allow_negative_y

Private Member Functions

bool ContactPoint (int &x, int &y)
void NotifyMove (Point2d oldPos, Point2d newPos)
void DirectFall ()
void CheckRebound ()

Private Attributes

bool m_goes_through_wall
bool m_collides_with_characters
bool m_collides_with_objects
Point2i m_rebound_position

Detailed Description

Definition at line 47 of file physical_obj.h.


Constructor & Destructor Documentation

PhysicalObj::PhysicalObj ( const std::string &  name,
const std::string &  xml_config = "" 
)

Definition at line 54 of file physical_obj.cpp.

00054                                                                             :
00055   m_name(name),
00056   m_width(0),
00057   m_height(0)
00058 {
00059   life_points = -1; // Disable lifepoints
00060   m_goes_through_wall = false;
00061   m_collides_with_characters = false;
00062   m_collides_with_objects = false;
00063 
00064   // No collision with this object until we have gone out of his collision rectangle
00065   m_overlapping_object = NULL;
00066 
00067   m_allow_negative_y = false;
00068   m_alive = ALIVE;
00069 
00070   m_rebound_sound = "";
00071 
00072   m_test_left = 0;
00073   m_test_right = 0;
00074   m_test_top = 0;
00075   m_test_bottom = 0;
00076 
00077   m_rebound_position = Point2i(-1, -1);
00078 
00079   m_cfg.LoadXml(m_name,xml_config);  // Load physics constants from the xml file
00080   ResetConstants();       // Set physics constants from the xml file
00081 }

Here is the call graph for this function:

PhysicalObj::~PhysicalObj (  )  [virtual]

Definition at line 83 of file physical_obj.cpp.

00084 {}


Member Function Documentation

void PhysicalObj::AddDamage ( uint  damage_points  ) 

Definition at line 225 of file physical_obj.cpp.

00226 {
00227   if(life_points == -1)
00228     return;
00229   life_points -= damage_points;
00230   if(life_points <= 0 && !IsGhost())
00231   {
00232     Ghost();
00233     life_points = -1;
00234   }
00235 }

Here is the call graph for this function:

Here is the caller graph for this function:

void PhysicalObj::CheckOverlapping (  )  [protected, virtual]

Definition at line 177 of file physical_obj.cpp.

00178 {
00179   if(m_overlapping_object == NULL)
00180     return;
00181 
00182   // Check if we are still overlapping with this object
00183   if (!m_overlapping_object->GetTestRect().Intersect( GetTestRect() ))
00184   {
00185     MSG_DEBUG( "physic.overlapping", "\"%s\" just stopped overlapping with \"%s\"", GetName().c_str(), m_overlapping_object->GetName().c_str());
00186     m_overlapping_object = NULL;
00187   }
00188   else
00189   {
00190     MSG_DEBUG( "physic.overlapping", "\"%s\" is overlapping with \"%s\"", GetName().c_str(), m_overlapping_object->GetName().c_str());
00191   }
00192 }

Here is the call graph for this function:

Here is the caller graph for this function:

void PhysicalObj::CheckRebound (  )  [private]

Definition at line 571 of file physical_obj.cpp.

00572 {
00573   // If we bounce twice in a row at the same place, stop bouncing
00574   // cause it's almost sure this object is stuck bouncing indefinitely
00575   if( m_rebound_position != Point2i( -1, -1) )
00576   {
00577     if ( m_rebound_position == GetPosition() )
00578     {
00579       MSG_DEBUG("physic.state", "%s seems to be stuck in ground. Stop moving!", m_name.c_str());
00580       StopMoving();
00581     }
00582   }
00583   m_rebound_position = GetPosition();
00584 }

Here is the call graph for this function:

Here is the caller graph for this function:

PhysicalObj * PhysicalObj::CollidedObject ( const Point2i offset  )  const

Definition at line 642 of file physical_obj.cpp.

00643 {
00644   return CollidedObjectXY(GetPosition() + offset);
00645 }

Here is the call graph for this function:

PhysicalObj * PhysicalObj::CollidedObjectXY ( const Point2i position  )  const

Definition at line 647 of file physical_obj.cpp.

00648 {
00649   if( IsOutsideWorldXY(position) )
00650     return NULL;
00651 
00652   Rectanglei rect(position.x + m_test_left, position.y + m_test_top,
00653                  m_width - m_test_right - m_test_left, m_height - m_test_bottom - m_test_top);
00654 
00655   if (m_collides_with_characters)
00656     {
00657       FOR_ALL_LIVING_CHARACTERS(team,character)
00658       {
00659         // We check both objet if one overlapse the other
00660         if (&(*character) != this && !IsOverlapping(&(*character)) && !character->IsOverlapping(this)
00661         && character->GetTestRect().Intersect( rect ))
00662           return (PhysicalObj*) &(*character);
00663       }
00664     }
00665 
00666   if (m_collides_with_objects)
00667     {
00668       FOR_EACH_OBJECT(it)
00669       {
00670         PhysicalObj * object=*it;
00671         // We check both objet if one overlapse the other
00672         if (object != this && !IsOverlapping(object) && !object->IsOverlapping(this)
00673             && object->m_collides_with_objects
00674             && object->GetTestRect().Intersect(rect) )
00675           return object;
00676       }
00677     }
00678   return NULL;
00679 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool PhysicalObj::ContactPoint ( int &  x,
int &  y 
) [private]

Definition at line 730 of file physical_obj.cpp.

00731 {
00732   int x1, x2, y1, y2;
00733 
00734   // On cherche un point de contact en bas de l'objet:
00735   y1 = (GetY()+m_height-m_test_bottom);
00736   y2 = y1-1;
00737   for (uint x=GetX()+ m_test_left; x<=(GetX()+m_width)-m_test_right; x++)
00738   {
00739     if(!world.EstHorsMonde(Point2i(x,y1)) && !world.EstHorsMonde(Point2i(x,y2))
00740     && world.ground.IsEmpty(Point2i(x,y2)) && !world.ground.IsEmpty(Point2i(x,y1)))
00741     {
00742       contact_x = x;
00743       contact_y = GetY() +m_height-m_test_bottom;
00744       return true;
00745     }
00746   }
00747 
00748   // On cherche un point de contact �gauche de l'objet:
00749   x1 = GetX()+m_test_left;
00750   x2 = x1+1;
00751   for(uint y=GetY()+m_test_top;y<=GetY()+m_height-m_test_bottom;y++)
00752   {
00753     if(!world.EstHorsMonde(Point2i(x1,y)) && !world.EstHorsMonde(Point2i(x2,y))
00754     && !world.ground.IsEmpty(Point2i(x1,y)) &&  world.ground.IsEmpty(Point2i(x2,y)))
00755     {
00756       contact_x = GetX() +m_test_left;
00757       contact_y = y;
00758       return true;
00759     }
00760   }
00761 
00762   // On cherche un point de contact �droite de l'objet:
00763   x1 = (GetX()+m_width-m_test_right);
00764   x2 = x1-1;
00765   for(uint y=GetY()+m_test_top;y<=GetY()+m_height-m_test_bottom;y++)
00766   {
00767     if(!world.EstHorsMonde(Point2i(x1, y)) && !world.EstHorsMonde(Point2i(x2, y))
00768        && !world.ground.IsEmpty(Point2i(x1, y)) && world.ground.IsEmpty(Point2i(x2, y)))
00769     {
00770       contact_x = GetX() + m_width - m_test_right;
00771       contact_y = y;
00772       return true;
00773     }
00774   }
00775 
00776   // On cherche un point de contact en haut de l'objet:
00777   y1 = GetY()+m_test_top;
00778   y2 = y1 - 1;
00779   for(uint x=GetX()+m_test_left;x<=GetX()+m_width-m_test_right;x++)
00780   {
00781     if(!world.EstHorsMonde(Point2i(x,y1)) && !world.EstHorsMonde(Point2i(x,y2))
00782     && !world.ground.IsEmpty(Point2i(x, y1)) && world.ground.IsEmpty(Point2i(x, y2)))
00783     {
00784       contact_x =x;
00785       contact_y = GetY() +m_test_top;
00786       return true;
00787     }
00788   }
00789   return false;
00790 }

Here is the call graph for this function:

Here is the caller graph for this function:

void PhysicalObj::DirectFall (  )  [private]

Definition at line 724 of file physical_obj.cpp.

00725 {
00726   while (!IsGhost() && !IsInWater() && FootsInVacuum())
00727       SetY(GetY()+1);
00728 }

Here is the call graph for this function:

Here is the caller graph for this function:

virtual void PhysicalObj::Draw (  )  [pure virtual]

Implemented in Character, WindParticle, PetrolBarrel, BonusBox, ExplosionSmoke, FireParticle, IllBubble, Particle, Plane, WeaponProjectile, and ObjMine.

void PhysicalObj::Drown (  ) 

Definition at line 497 of file physical_obj.cpp.

00498 {
00499   assert (m_alive != DROWNED);
00500   MSG_DEBUG("physic.state", "%s - Drowned...", m_name.c_str());
00501   m_alive = DROWNED;
00502 
00503   // Set the air grab to water resist factor.
00504   SetAirResistFactor(WATER_RESIST_FACTOR * GetAirResistFactor());
00505   StopMoving();
00506   StartMoving();
00507   SignalDrowning();
00508 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool PhysicalObj::FootsInVacuum (  )  const

Definition at line 681 of file physical_obj.cpp.

00682 {
00683   return FootsInVacuumXY(GetPosition());
00684 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool PhysicalObj::FootsInVacuumXY ( const Point2i position  )  const

Definition at line 686 of file physical_obj.cpp.

00687 {
00688   if( IsOutsideWorldXY(position) ){
00689     MSG_DEBUG("physical", "%s - physobj is outside the world", m_name.c_str());
00690     return Config::GetInstance()->GetExterieurMondeVide();
00691   }
00692 
00693   if( FootsOnFloor(position.y) ){
00694     MSG_DEBUG("physical", "%s - physobj is on floor", m_name.c_str());
00695     return false;
00696   }
00697 
00698   int y_test = position.y + m_height - m_test_bottom;
00699 
00700   Rectanglei rect( position.x + m_test_left, y_test,
00701                  m_width - m_test_right - m_test_left, 1);
00702 
00703   if( m_allow_negative_y && rect.GetPositionY() < 0){
00704     int b = rect.GetPositionY() + rect.GetSizeY();
00705 
00706     rect.SetPositionY( 0 );
00707     rect.SetSizeY( ( b > 0 ) ? b - rect.GetPositionY() : 0 );
00708   }
00709 
00710   if(CollidedObjectXY( position + Point2i(0, 1)) != NULL )
00711     return false;
00712 
00713   return world.RectEstDansVide (rect);
00714 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool PhysicalObj::FootsOnFloor ( int  y  )  const

Definition at line 606 of file physical_obj.cpp.

00607 {
00608   // If outside is empty, the object can't hit the ground !
00609   if ( Config::GetInstance()->GetExterieurMondeVide() ) return false;
00610 
00611   const int y_max = world.GetHeight()-m_height +m_test_bottom;
00612   return (y_max <= y);
00613 }

Here is the call graph for this function:

Here is the caller graph for this function:

const Point2i PhysicalObj::GetCenter (  )  const

Definition at line 142 of file physical_obj.cpp.

00143 {
00144   return Point2i(GetCenterX(), GetCenterY());
00145 }

Here is the call graph for this function:

Here is the caller graph for this function:

int PhysicalObj::GetCenterX (  )  const

Definition at line 132 of file physical_obj.cpp.

00133 {
00134   return GetX() +m_test_left +GetTestWidth()/2;
00135 }

Here is the call graph for this function:

Here is the caller graph for this function:

int PhysicalObj::GetCenterY (  )  const

Definition at line 137 of file physical_obj.cpp.

00138 {
00139   return GetY() +m_test_top +GetTestHeight()/2;
00140 }

Here is the call graph for this function:

Here is the caller graph for this function:

int PhysicalObj::GetHeight (  )  const

Definition at line 161 of file physical_obj.cpp.

00161                                 {
00162   assert (m_height != 0);
00163   return m_height;
00164 }

Here is the caller graph for this function:

virtual const std::string& PhysicalObj::GetName (  )  const [inline, virtual]

Reimplemented in Character.

Definition at line 104 of file physical_obj.h.

00104 { return m_name; }

Here is the caller graph for this function:

const Point2i PhysicalObj::GetPosition (  )  const

Definition at line 117 of file physical_obj.cpp.

00118 {
00119   return Point2i(GetX(), GetY());
00120 }

Here is the call graph for this function:

Here is the caller graph for this function:

const Rectanglei PhysicalObj::GetRect (  )  const

Definition at line 212 of file physical_obj.cpp.

00213 {
00214   return Rectanglei( GetX(), GetY(), m_width, m_height);
00215 }

Here is the call graph for this function:

Here is the caller graph for this function:

Point2i PhysicalObj::GetSize (  )  const

Definition at line 166 of file physical_obj.cpp.

00166                                   {
00167         return Point2i(m_width, m_height);
00168 }

Here is the caller graph for this function:

int PhysicalObj::GetTestHeight (  )  const

Definition at line 207 of file physical_obj.cpp.

00208 {
00209   return m_height -m_test_top -m_test_bottom;
00210 }

Here is the caller graph for this function:

const Rectanglei PhysicalObj::GetTestRect (  )  const

Definition at line 217 of file physical_obj.cpp.

00218 {
00219   return Rectanglei(GetX()+m_test_left,
00220                     GetY()+m_test_top,
00221                     m_width-m_test_right-m_test_left,
00222                     m_height-m_test_bottom-m_test_top);
00223 }

Here is the call graph for this function:

Here is the caller graph for this function:

int PhysicalObj::GetTestWidth (  )  const

Definition at line 202 of file physical_obj.cpp.

00203 {
00204   return m_width -m_test_left -m_test_right;
00205 }

Here is the caller graph for this function:

int PhysicalObj::GetWidth (  )  const

Definition at line 156 of file physical_obj.cpp.

00156                                {
00157   assert (m_width != 0);
00158   return m_width;
00159 }

Here is the caller graph for this function:

int PhysicalObj::GetX (  )  const

Definition at line 122 of file physical_obj.cpp.

00123 {
00124   return (int)round(GetPhysX() * PIXEL_PER_METER);
00125 }

Here is the call graph for this function:

Here is the caller graph for this function:

int PhysicalObj::GetY (  )  const

Definition at line 127 of file physical_obj.cpp.

00128 {
00129   return (int)round(GetPhysY() * PIXEL_PER_METER);
00130 }

Here is the call graph for this function:

Here is the caller graph for this function:

void PhysicalObj::Ghost (  ) 

Definition at line 482 of file physical_obj.cpp.

00483 {
00484   if (m_alive == GHOST)
00485     return;
00486 
00487   bool was_dead = IsDead();
00488   m_alive = GHOST;
00489   MSG_DEBUG("physic.state", "%s - Ghost, was_dead = %d", m_name.c_str(), was_dead);
00490 
00491   // The object became a gost
00492   StopMoving();
00493 
00494   SignalGhostState(was_dead);
00495 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool PhysicalObj::GoesThroughWall (  )  const [inline]

Definition at line 109 of file physical_obj.h.

00109 { return m_goes_through_wall; }

Here is the caller graph for this function:

void PhysicalObj::GoOutOfWater (  ) 

Definition at line 510 of file physical_obj.cpp.

00511 {
00512   assert (m_alive == DROWNED);
00513   MSG_DEBUG("physic.state", "%s - Go out of water!...", m_name.c_str());
00514   m_alive = ALIVE;
00515 
00516   // Set the air grab to normal air resist factor.
00517   SetAirResistFactor(m_cfg.m_air_resist_factor);
00518 
00519   StartMoving();
00520 }

Here is the call graph for this function:

Here is the caller graph for this function:

void PhysicalObj::Init (  ) 

Definition at line 473 of file physical_obj.cpp.

00474 {
00475   if (m_alive != ALIVE)
00476     MSG_DEBUG( "physic.state", "%s - Init.", m_name.c_str());
00477   m_alive = ALIVE;
00478   m_overlapping_object = NULL;
00479   StopMoving();
00480 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool PhysicalObj::IsDead (  )  const

Definition at line 527 of file physical_obj.cpp.

00528 { return ((m_alive == GHOST) || (m_alive == DROWNED) || (m_alive == DEAD)); }

Here is the caller graph for this function:

bool PhysicalObj::IsDrowned (  )  const

Definition at line 533 of file physical_obj.cpp.

00534 { return (m_alive == DROWNED); }

Here is the caller graph for this function:

bool PhysicalObj::IsGhost (  )  const

Definition at line 530 of file physical_obj.cpp.

00531 { return (m_alive == GHOST); }

Here is the caller graph for this function:

bool PhysicalObj::IsImmobile (  )  const [virtual]

Reimplemented in WeaponProjectile, and ObjMine.

Definition at line 522 of file physical_obj.cpp.

00523 {
00524   return (!IsMoving() && !FootsInVacuum())||(m_alive == GHOST);
00525 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool PhysicalObj::IsInVacuum ( const Point2i offset,
bool  check_objects = true 
) const

Definition at line 620 of file physical_obj.cpp.

00621 {
00622   return IsInVacuumXY(GetPosition() + offset, check_object);
00623 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool PhysicalObj::IsInVacuumXY ( const Point2i position,
bool  check_objects = true 
) const

Definition at line 625 of file physical_obj.cpp.

00626 {
00627   if( IsOutsideWorldXY(position) )
00628     return Config::GetInstance()->GetExterieurMondeVide();
00629 
00630   if( FootsOnFloor(position.y - 1) )
00631     return false;
00632 
00633   if( check_object && CollidedObjectXY(position) )
00634     return false;
00635 
00636   Rectanglei rect(position.x + m_test_left, position.y + m_test_top,
00637                   m_width - m_test_right - m_test_left, m_height -m_test_bottom - m_test_top);
00638 
00639   return world.RectEstDansVide (rect);
00640 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool PhysicalObj::IsInWater (  )  const

Definition at line 716 of file physical_obj.cpp.

00717 {
00718   assert (!IsGhost());
00719   if (!world.water.IsActive()) return false;
00720   int x = BorneLong(GetCenterX(), 0, world.GetWidth()-1);
00721   return (int)world.water.GetHeight(x) < GetCenterY();
00722 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool PhysicalObj::IsOutsideWorld ( const Point2i offset  )  const

Definition at line 601 of file physical_obj.cpp.

00602 {
00603   return IsOutsideWorldXY( GetPosition() + offset );
00604 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool PhysicalObj::IsOutsideWorldXY ( Point2i  position  )  const

Definition at line 586 of file physical_obj.cpp.

00586                                                         {
00587   int x = position.x + m_test_left;
00588   int y = position.y + m_test_top;
00589 
00590   if( world.EstHorsMondeXlarg(x, GetTestWidth()) )
00591           return true;
00592   if( world.EstHorsMondeYhaut(y, GetTestHeight()) ){
00593     if( m_allow_negative_y )
00594       if( (Y_OBJET_MIN <= y) && (y + GetTestHeight() - 1 < 0) )
00595                   return false;
00596     return true;
00597   }
00598   return false;
00599 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool PhysicalObj::IsOverlapping ( const PhysicalObj obj  )  const [virtual]

Reimplemented in ShotgunBuckshot.

Definition at line 615 of file physical_obj.cpp.

00616 {
00617   return m_overlapping_object == obj;
00618 }

Here is the caller graph for this function:

void PhysicalObj::NotifyMove ( Point2d  oldPos,
Point2d  newPos 
) [private, virtual]

Implements Physics.

Definition at line 238 of file physical_obj.cpp.

00239 {
00240   if (IsGhost()) return;
00241   Point2d pos, offset;
00242   PhysicalObj* collided_obj = NULL;
00243 
00244   typedef enum {
00245     NO_COLLISION = 0,
00246     COLLISION_ON_GROUND,
00247     COLLISION_ON_OBJECT
00248   } collision_t;
00249   collision_t collision = NO_COLLISION;
00250 
00251   if(IsGhost())
00252     return;
00253 
00254   // Convert meters to pixels.
00255   oldPos *= PIXEL_PER_METER;
00256   newPos *= PIXEL_PER_METER;
00257 
00258   // Compute distance between old and new position.
00259   double lg = oldPos.Distance( newPos);
00260 
00261   if (lg == 0)
00262     return;
00263 
00264   // Compute increments to move the object step by step from the old
00265   // to the new position.
00266   offset = (newPos - oldPos) / lg;
00267 
00268   // First iteration position.
00269   pos = oldPos + offset;
00270 
00271   if (m_goes_through_wall || IsInWater())
00272   {
00273     Point2i tmpPos( lround(newPos.x), lround(newPos.y) );
00274     SetXY(tmpPos);
00275     return;
00276   }
00277 
00278   do
00279   {
00280     Point2i tmpPos( lround(pos.x), lround(pos.y) );
00281 
00282     // Check if we exit the world. If so, we stop moving and return.
00283     if( IsOutsideWorldXY(tmpPos) ){
00284 
00285       if( !Config::GetInstance()->GetExterieurMondeVide() ){
00286         tmpPos.x = BorneLong(tmpPos.x, 0, world.GetWidth() - GetWidth() - 1);
00287         tmpPos.y = BorneLong(tmpPos.y, 0, world.GetHeight() - GetHeight() - 1);
00288         MSG_DEBUG( "physic.state", "%s - DeplaceTestCollision touche un bord : %d, %d",  m_name.c_str(), tmpPos.x, tmpPos.y );
00289         collision = COLLISION_ON_GROUND;
00290         break;
00291       }
00292 
00293       SetXY( tmpPos );
00294       return;
00295     }
00296 
00297     // Test if we collide...
00298     collided_obj = CollidedObjectXY(tmpPos);
00299     if( collided_obj != NULL)
00300       MSG_DEBUG( "physic.state", "%s collide on %s", m_name.c_str(), collided_obj->GetName().c_str() );
00301 
00302     if( collided_obj != NULL)
00303       collision = COLLISION_ON_OBJECT;
00304     else
00305     if( ! IsInVacuumXY(tmpPos, false) )
00306       collision = COLLISION_ON_GROUND;
00307 
00308     if( collision != NO_COLLISION ) // Nothing more to do!
00309     {
00310       MSG_DEBUG( "physic.state", "%s - Collision at %d,%d : %s", m_name.c_str(), tmpPos.x, tmpPos.y,
00311           collision == COLLISION_ON_GROUND ? "on ground" : "on an object");
00312 
00313       // Set the object position to the current position.
00314       SetXY( Point2i( lround(pos.x - offset.x), lround(pos.y - offset.y)) );
00315       break;
00316     }
00317 
00318     // Next motion step
00319     pos += offset;
00320     lg -= 1.0 ;
00321   } while (0 < lg);
00322 
00323 
00324   // Only for ninja rope... TO REMOVE!!
00325   if (ActiveTeam().GetWeaponType() == Weapon::WEAPON_NINJA_ROPE &&
00326       ActiveTeam().GetWeapon().IsActive()) {
00327     Weapon& tmp = ActiveTeam().AccessWeapon();
00328     NinjaRope * ninjarope = (NinjaRope *)(&tmp);
00329     ninjarope->NotifyMove(collision) ;
00330   }
00331 
00332   if ( collision == NO_COLLISION ) // Nothing more to do!
00333     return;
00334   if ( collision == COLLISION_ON_GROUND ) {
00335       // Find the contact point and collision angle.
00336 //       // !!! ContactPoint(...) _can_ return false when CollisionTest(...) is true !!!
00337 //       // !!! WeaponProjectiles collide on objects, so computing the tangeante to the ground leads
00338 //       // !!! uninitialised values of cx and cy!!
00339 //       if( ContactPoint(cx, cy) ){
00340     int cx, cy;
00341     Point2d contactPos;
00342     double ground_angle;
00343 
00344     if (ContactPoint(cx, cy)) {
00345       ground_angle = world.ground.Tangeante(cx, cy);
00346       contactPos.x = (double)cx / PIXEL_PER_METER;
00347       contactPos.y = (double)cy / PIXEL_PER_METER;
00348     } else {
00349       ground_angle = - GetSpeedAngle();
00350       contactPos = pos;
00351     }
00352 
00353     SignalGroundCollision();
00354     SignalCollision();
00355     // Make it rebound on the ground !!
00356     Rebound(contactPos, ground_angle);
00357     CheckRebound();
00358   } else if ( collision == COLLISION_ON_OBJECT ) {
00359     SignalObjectCollision(collided_obj);
00360     collided_obj->SignalObjectCollision(this);
00361 
00362     // Get the current speed
00363     double v1, v2, mass1, angle1, angle2, mass2;
00364     collided_obj->GetSpeed(v1, angle1);
00365     GetSpeed(v2, angle2);
00366     mass1 = GetMass();
00367     mass2 = collided_obj->GetMass();
00368 
00369     // Give speed to the other object
00370     // thanks to physic and calculations about chocs, we know that :
00371     //
00372     // v'1 =  ((m1 - m2) * v1 + 2m1 *v2) / (m1 + m2)
00373     // v'2 =  ((m2 - m1) * v2 + 2m1 *v1) / (m1 + m2)
00374     SignalCollision();
00375 
00376     collided_obj->SetSpeed(((mass1 - mass2) * v1 + 2 * mass1 *v2 * m_cfg.m_rebound_factor) / (mass1 + mass2),
00377                            angle1);
00378     SetSpeed(((mass2 - mass1) * v2 + 2 * mass1 *v1 * m_cfg.m_rebound_factor) / (mass1 + mass2), angle2);
00379 
00380     // Rebound on the object
00381     double contact_angle = - GetSpeedAngle();
00382     Point2d contactPos = pos;
00383     Rebound(contactPos, contact_angle);
00384     CheckRebound();
00385   }
00386   return;
00387 }

Here is the call graph for this function:

bool PhysicalObj::ObjTouche ( const Point2i p  )  const

Definition at line 799 of file physical_obj.cpp.

00800 {
00801    return  GetTestRect().Contains( p );
00802 }

Here is the call graph for this function:

bool PhysicalObj::ObjTouche ( const PhysicalObj b  )  const

Definition at line 793 of file physical_obj.cpp.

00794 {
00795   return GetTestRect().Intersect( b.GetTestRect() );
00796 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool PhysicalObj::PutOutOfGround ( double  direction  ) 

Definition at line 421 of file physical_obj.cpp.

00422 {
00423   if(IsOutsideWorld(Point2i(0, 0)))
00424     return false;
00425 
00426   const int max_step = 30;
00427 
00428   if( IsInVacuum(Point2i(0, 0), false) )
00429     return true;
00430 
00431   double dx = cos(direction);
00432   double dy = sin(direction);
00433 
00434   int step=1;
00435   while(step<max_step && !IsInVacuum(
00436                           Point2i((int)(dx * (double)step),(int)(dy * (double)step)), false ))
00437     step++;
00438 
00439   if(step<max_step)
00440     SetXY( Point2i((int)(dx * (double)step)+GetX(),(int)(dy * (double)step)+GetY()) );
00441   else
00442     return false; //Can't put the object out of the ground
00443 
00444   return true;
00445 }

Here is the call graph for this function:

bool PhysicalObj::PutOutOfGround (  ) 

Definition at line 447 of file physical_obj.cpp.

00448 {
00449   if(IsOutsideWorld(Point2i(0, 0)))
00450     return false;
00451 
00452   if( IsInVacuum(Point2i(0, 0)) )
00453     return true;
00454 
00455   bool left,right,top,bottom;
00456   left   = world.IsInVacuum_left(*this, 0, 0);
00457   right  = world.IsInVacuum_right(*this, 0, 0);
00458   top    = world.EstDansVide_haut(*this, 0, 0);
00459   bottom = world.EstDansVide_bas(*this, 0, 0);
00460 
00461   int dx = (int)GetTestRect().GetSizeX() * (right-left);
00462   int dy = (int)GetTestRect().GetSizeY() * (top-bottom);
00463 
00464   if( dx == 0 && dy == 0 )
00465     return false; //->Don't know in which direction we should go...
00466 
00467   Point2i b(dx, dy);
00468 
00469   double dir = b.ComputeAngle();
00470   return PutOutOfGround(dir);
00471 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool PhysicalObj::PutRandomly ( bool  on_top_of_world,
double  min_dst_with_characters 
)

Definition at line 804 of file physical_obj.cpp.

00805 {
00806   uint bcl=0;
00807   uint NB_MAX_TRY = 60;
00808   bool ok;
00809   Point2i position;
00810 
00811   MSG_DEBUG("physic.position", "%s - Search a position...", m_name.c_str());
00812 
00813   do
00814   {
00815     bcl++;
00816     ok = true;
00817     Init();
00818 
00819     if (bcl >= NB_MAX_TRY) {
00820       MSG_DEBUG("physic.position", "%s - Impossible to find an initial position !!", m_name.c_str());
00821       return false;
00822     }
00823 
00824     if (on_top_of_world) {
00825       // Placement au hasard en X
00826       position.x = randomSync.GetLong(0, world.GetWidth() - GetWidth());
00827       position.y = -GetHeight()+1;
00828     } else {
00829       position = randomSync.GetPoint(world.GetSize() - GetSize() + 1);
00830     }
00831     SetXY(position);
00832     MSG_DEBUG("physic.position", "%s - Test in %d, %d",  m_name.c_str(), position.x, position.y);
00833 
00834     // Check physical object is not in the ground
00835     ok &= !IsGhost() && world.ParanoiacRectIsInVacuum(GetTestRect())  && IsInVacuum( Point2i(0, 1) );
00836     if (!ok) {
00837       MSG_DEBUG("physic.position", "%s - Put it in the ground -> try again !", m_name.c_str());
00838       continue;
00839     }
00840 
00841     // Check object does not go in water or outside the map
00842     DirectFall();
00843     ok &= !IsGhost() && !IsInWater() && (GetY() < static_cast<int>(world.GetHeight() - (WATER_INITIAL_HEIGHT + 30)));
00844 
00845     if (!ok) {
00846       MSG_DEBUG("physic.position", "%s - Put in outside the map or in water -> try again", m_name.c_str());
00847       continue;
00848     }
00849 
00850     // Check distance with characters
00851     FOR_ALL_LIVING_CHARACTERS(equipe, ver) if (&(*ver) != this)
00852     {
00853       if (min_dst_with_characters == 0) {
00854 
00855         if( ObjTouche(*ver) ) {
00856             MSG_DEBUG("physic.position", "%s - Object is too close from character %s", m_name.c_str(), (*ver).m_name.c_str());
00857             ok = false;
00858         }
00859       } else {
00860         Point2i p1 = ver->GetCenter();
00861         Point2i p2 = GetCenter();
00862         double dst = p1.Distance( p2 );
00863 
00864         // ok this test is not perfect but quite efficient ;-)
00865         // else we need to check each distance between each "corner"
00866         if (dst < min_dst_with_characters) ok = false;
00867       }
00868     }
00869 
00870     if (ok && on_top_of_world) SetXY(position);
00871   } while (!ok);
00872 
00873   MSG_DEBUG("physic.position", "Putted after  %d try", m_name.c_str(), bcl);
00874 
00875   return true;
00876 }

Here is the call graph for this function:

Here is the caller graph for this function:

virtual void PhysicalObj::Refresh (  )  [pure virtual]

Implemented in Character, WindParticle, PetrolBarrel, BonusBox, BodyMemberParticle, BulletParticle, ExplosionSmoke, FireParticle, GroundParticle, MagicStarParticle, Particle, TeleportMemberParticle, Plane, Anvil, RPG, BazookaRocket, BounceBall, Cluster, ClusterBomb, DiscoGrenade, DynamiteStick, Gnu, Grenade, WeaponProjectile, WeaponBullet, ObjMine, Polecat, RiotBombRocket, and SuperTux.

void PhysicalObj::SetCollisionModel ( bool  goes_through_wall,
bool  collides_with_characters,
bool  collides_with_objects 
)

Definition at line 551 of file physical_obj.cpp.

00554 {
00555   m_goes_through_wall = goes_through_wall;
00556   m_collides_with_characters = collides_with_characters;
00557   m_collides_with_objects = collides_with_objects;
00558 
00559   // Check boolean values
00560   {
00561     if (m_collides_with_characters || m_collides_with_objects)
00562       assert(m_goes_through_wall == false);
00563 
00564     if (m_goes_through_wall) {
00565       assert(m_collides_with_characters == false);
00566       assert(m_collides_with_objects == false);
00567     }
00568   }
00569 }

Here is the caller graph for this function:

void PhysicalObj::SetOverlappingObject ( PhysicalObj obj  ) 

Definition at line 170 of file physical_obj.cpp.

00171 {
00172   m_overlapping_object = obj;
00173   MSG_DEBUG( "physic.overlapping", "\"%s\" doesn't check any collision with \"%s\" anymore", GetName().c_str(), obj->GetName().c_str());
00174   CheckOverlapping();
00175 }

Here is the call graph for this function:

Here is the caller graph for this function:

void PhysicalObj::SetSize ( const Point2i newSize  ) 

Definition at line 147 of file physical_obj.cpp.

00147                                                {
00148   if( newSize == Point2i(0, 0) )
00149           Error( "New size of (0, 0) !");
00150   m_width = newSize.x;
00151   m_height = newSize.y;
00152   SetPhysSize( (double)newSize.x / PIXEL_PER_METER, (double)newSize.y/PIXEL_PER_METER );
00153 }

Here is the call graph for this function:

Here is the caller graph for this function:

void PhysicalObj::SetTestRect ( uint  left,
uint  right,
uint  top,
uint  bottom 
)

Definition at line 194 of file physical_obj.cpp.

00195 {
00196   m_test_left =  left;
00197   m_test_right = right;
00198   m_test_top = top;
00199   m_test_bottom = bottom;
00200 }

Here is the caller graph for this function:

void PhysicalObj::SetX ( int  x  ) 

Definition at line 90 of file physical_obj.cpp.

00090                             {
00091   SetXY( Point2i(x, GetY()) );
00092 }

Here is the call graph for this function:

Here is the caller graph for this function:

void PhysicalObj::SetXY ( const Point2i position  ) 

Definition at line 98 of file physical_obj.cpp.

00099 {
00100   CheckOverlapping();
00101 
00102   if( IsOutsideWorldXY( position ) )
00103   {
00104     Point2d physPos(position.x, position.y);
00105     SetPhysXY( physPos / PIXEL_PER_METER );
00106     Ghost();
00107     SignalOutOfMap();
00108   }
00109   else
00110   {
00111     Point2d physPos(position.x, position.y);
00112     SetPhysXY( physPos / PIXEL_PER_METER );
00113     if( FootsInVacuum() ) StartMoving();
00114   }
00115 }

Here is the call graph for this function:

Here is the caller graph for this function:

void PhysicalObj::SetY ( int  y  ) 

Definition at line 94 of file physical_obj.cpp.

00094                             {
00095   SetXY( Point2i(GetX(), y) );
00096 }

Here is the call graph for this function:

Here is the caller graph for this function:

void PhysicalObj::SignalCollision (  )  [protected, virtual]

Reimplemented in Character, BonusBox, and WeaponProjectile.

Definition at line 547 of file physical_obj.cpp.

00547 {}

Here is the caller graph for this function:

void PhysicalObj::SignalGroundCollision (  )  [protected, virtual]

Reimplemented in Anvil, WeaponProjectile, and WeaponBullet.

Definition at line 545 of file physical_obj.cpp.

00545 {}

Here is the caller graph for this function:

void PhysicalObj::SignalObjectCollision ( PhysicalObj obj  )  [protected, virtual]

Reimplemented in PolecatFart, Anvil, WeaponProjectile, and WeaponBullet.

Definition at line 543 of file physical_obj.cpp.

00543 {}

Here is the caller graph for this function:

void PhysicalObj::SignalOutOfMap (  )  [protected, virtual]

Reimplemented in FireParticle, RPG, BazookaRocket, BounceBall, Cluster, ClusterBomb, DiscoGrenade, DynamiteStick, Gnu, Grenade, WeaponProjectile, WeaponBullet, Polecat, RiotBombRocket, and SuperTux.

Definition at line 549 of file physical_obj.cpp.

00549 {}

Here is the caller graph for this function:

void PhysicalObj::SignalRebound (  )  [protected, virtual]

Reimplemented from Physics.

Reimplemented in BulletParticle.

Definition at line 536 of file physical_obj.cpp.

00537 {
00538   // TO CLEAN...
00539    if (!m_rebound_sound.empty())
00540      jukebox.Play("share", m_rebound_sound) ;
00541 }

Here is the call graph for this function:

Here is the caller graph for this function:

void PhysicalObj::UpdatePosition (  ) 

Definition at line 389 of file physical_obj.cpp.

00390 {
00391   // No ghost allowed here !
00392   if (IsGhost()) return;
00393 
00394   if ( !m_goes_through_wall )
00395     {
00396       // object is not moving and has no reason to move
00397       if ( !IsMoving() && !FootsInVacuum() && !IsInWater() ) return;
00398 
00399       // object is not moving BUT it should fall !
00400       if ( !IsMoving() && FootsInVacuum() ) StartMoving();
00401     }
00402 
00403   // Compute new position.
00404   RunPhysicalEngine();
00405 
00406   // Test if object is still inside the world
00407   if( IsOutsideWorldXY(GetPosition()) )
00408     Ghost();
00409 
00410   if (IsGhost()) return;
00411 
00412   // Classical object sometimes sinks in water and sometimes goes out of water!
00413   if ( !m_goes_through_wall )
00414     {
00415       if ( IsInWater() && m_alive != DROWNED ) Drown();
00416       else if ( !IsInWater() && m_alive == DROWNED ) GoOutOfWater();
00417     }
00418 
00419 }

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

int PhysicalObj::life_points [protected]

Definition at line 73 of file physical_obj.h.

alive_t PhysicalObj::m_alive [protected]

Definition at line 72 of file physical_obj.h.

bool PhysicalObj::m_allow_negative_y [protected]

Definition at line 75 of file physical_obj.h.

bool PhysicalObj::m_collides_with_characters [private]

Definition at line 52 of file physical_obj.h.

bool PhysicalObj::m_collides_with_objects [private]

Definition at line 53 of file physical_obj.h.

bool PhysicalObj::m_goes_through_wall [private]

Definition at line 51 of file physical_obj.h.

uint PhysicalObj::m_height [protected]

Definition at line 68 of file physical_obj.h.

std::string PhysicalObj::m_name [protected]

Definition at line 62 of file physical_obj.h.

PhysicalObj* PhysicalObj::m_overlapping_object [protected]

Definition at line 57 of file physical_obj.h.

Point2i PhysicalObj::m_rebound_position [private]

Definition at line 55 of file physical_obj.h.

std::string PhysicalObj::m_rebound_sound [protected]

Definition at line 70 of file physical_obj.h.

uint PhysicalObj::m_test_bottom [protected]

Definition at line 65 of file physical_obj.h.

uint PhysicalObj::m_test_left [protected]

Definition at line 65 of file physical_obj.h.

uint PhysicalObj::m_test_right [protected]

Definition at line 65 of file physical_obj.h.

uint PhysicalObj::m_test_top [protected]

Definition at line 65 of file physical_obj.h.

uint PhysicalObj::m_width [protected]

Definition at line 68 of file physical_obj.h.


The documentation for this class was generated from the following files:
Generated on Mon Jan 1 14:08:28 2007 for Wormux by  doxygen 1.4.7